Skip to content

Commit f48d127

Browse files
committed
feat: standardize tsgo rules and update dependencies
1 parent d8493d1 commit f48d127

File tree

3 files changed

+263
-131
lines changed

3 files changed

+263
-131
lines changed

CLAUDE.md

Lines changed: 151 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,24 @@ You are a **Principal Software Engineer** responsible for:
3030
## Commands
3131

3232
### Development Commands
33-
- **Build**: `npm run build` (alias for `npm run build:dist`)
34-
- **Build source**: `npm run build:dist:src` or `pnpm build:dist:src`
35-
- **Build types**: `npm run build:dist:types`
36-
- **Test**: `npm run test` (runs check + all tests)
37-
- **Test unit only**: `npm run test:unit` or `pnpm test:unit`
38-
- **Lint**: `npm run check:lint` (uses eslint)
39-
- **Type check**: `npm run check:tsc` (uses tsgo)
40-
- **Check all**: `npm run check` (lint + typecheck)
41-
- **Fix linting**: `npm run lint:fix`
33+
- **Build**: `pnpm run build` (alias for `pnpm run build:dist`)
34+
- **Build source**: `pnpm run build:dist:src`
35+
- **Build types**: `pnpm run build:dist:types`
36+
- **Test**: `pnpm run test` (runs check + all tests)
37+
- **Test unit only**: `pnpm run test:unit`
38+
- **Lint**: `pnpm run check:lint` (uses eslint)
39+
- **Type check**: `pnpm run check:tsc` (uses tsgo)
40+
- **Check all**: `pnpm run check` (lint + typecheck)
41+
- **Fix linting**: `pnpm run lint:fix`
4242
- **Commit without tests**: `git commit --no-verify` (skips pre-commit hooks including tests)
4343

4444
### Cross-Platform Compatibility - CRITICAL: Windows and POSIX
4545
- **🚨 MANDATORY**: Tests and functionality MUST work on both POSIX (macOS/Linux) and Windows systems
4646
- **Path handling**: ALWAYS use `path.join()`, `path.resolve()`, `path.sep` for file paths
4747
- ❌ WRONG: `'/usr/local/bin/npm'` (hard-coded POSIX path)
48-
- ✅ CORRECT: `path.join(path.sep, 'usr', 'local', 'bin', 'npm')` (cross-platform)
48+
- ✅ CORRECT: `path.join(somePath, 'bin/npm')` (cross-platform)
49+
- ✅ CORRECT: ``path.join(somePath, `bin/${binName}`)`` (cross-platform)
50+
- ✅ CORRECT: `path.join(somePath, 'bin', binName)` (cross-platform)
4951
- ❌ WRONG: `'/project/package-lock.json'` (hard-coded forward slashes)
5052
- ✅ CORRECT: `path.join('project', 'package-lock.json')` (uses correct separator)
5153
- **Temp directories**: Use `os.tmpdir()` for temporary file paths in tests
@@ -58,41 +60,44 @@ You are a **Principal Software Engineer** responsible for:
5860
- Use `path.sep` when you need the separator character
5961
- Use `path.join()` to construct paths correctly
6062
- **File URLs**: Use `pathToFileURL()` and `fileURLToPath()` from `node:url` when working with file:// URLs
63+
- ❌ WRONG: `path.dirname(new URL(import.meta.url).pathname)` (Windows path doubling)
64+
- ✅ CORRECT: `path.dirname(fileURLToPath(import.meta.url))` (cross-platform)
6165
- **Line endings**: Be aware of CRLF (Windows) vs LF (Unix) differences when processing text files
6266
- **Shell commands**: Consider platform differences in shell commands and utilities
6367

6468
### Testing Best Practices - CRITICAL: NO -- FOR FILE PATHS
6569
- **🚨 NEVER USE `--` BEFORE TEST FILE PATHS** - This runs ALL tests, not just your specified files!
66-
- **Always build before testing**: Run `pnpm build:dist:src` before running tests to ensure dist files are up to date
67-
- **Test single file**: ✅ CORRECT: `pnpm test:unit src/commands/specific/cmd-file.test.mts`
68-
- ❌ WRONG: `pnpm test:unit -- src/commands/specific/cmd-file.test.mts` (runs ALL tests!)
69-
- **Test multiple files**: ✅ CORRECT: `pnpm test:unit file1.test.mts file2.test.mts`
70-
- **Test with pattern**: ✅ CORRECT: `pnpm test:unit src/commands/specific/cmd-file.test.mts -t "pattern"`
71-
- ❌ WRONG: `pnpm test:unit -- src/commands/specific/cmd-file.test.mts -t "pattern"`
70+
- **Always build before testing**: Run `pnpm run build:dist:src` before running tests to ensure dist files are up to date
71+
- **Test single file**: ✅ CORRECT: `pnpm run test:unit src/commands/specific/cmd-file.test.mts`
72+
- ❌ WRONG: `pnpm run test:unit -- src/commands/specific/cmd-file.test.mts` (runs ALL tests!)
73+
- **Test multiple files**: ✅ CORRECT: `pnpm run test:unit file1.test.mts file2.test.mts`
74+
- **Test with pattern**: ✅ CORRECT: `pnpm run test:unit src/commands/specific/cmd-file.test.mts -t "pattern"`
75+
- ❌ WRONG: `pnpm run test:unit -- src/commands/specific/cmd-file.test.mts -t "pattern"`
7276
- **Update snapshots**:
73-
- All tests: `pnpm testu` (builds first, then updates all snapshots)
74-
- Single file: ✅ CORRECT: `pnpm testu src/commands/specific/cmd-file.test.mts`
75-
- ❌ WRONG: `pnpm testu -- src/commands/specific/cmd-file.test.mts` (updates ALL snapshots!)
76-
- **Update with --update flag**: `pnpm test:unit src/commands/specific/cmd-file.test.mts --update`
77+
- All tests: `pnpm run testu` (builds first, then updates all snapshots)
78+
- Single file: ✅ CORRECT: `pnpm run testu src/commands/specific/cmd-file.test.mts`
79+
- ❌ WRONG: `pnpm run testu -- src/commands/specific/cmd-file.test.mts` (updates ALL snapshots!)
80+
- **Update with --update flag**: `pnpm run test:unit src/commands/specific/cmd-file.test.mts --update`
7781
- **Timeout for long tests**: Use `timeout` command or specify in test file
7882

7983
#### Vitest Memory Optimization (CRITICAL)
8084
- **Pool configuration**: Use `pool: 'forks'` with `singleFork: true`, `maxForks: 1`, `isolate: true`
8185
- **Memory limits**: Set `NODE_OPTIONS="--max-old-space-size=4096 --max-semi-space-size=512"` in `.env.test`
8286
- **Timeout settings**: Use `testTimeout: 60000, hookTimeout: 60000` for stability
8387
- **Thread limits**: Use `singleThread: true, maxThreads: 1` to prevent RegExp compiler exhaustion
84-
- **Test cleanup**: 🚨 MANDATORY - Import and use `trash` package: `import { trash } from 'trash'` then `await trash([paths])`
88+
- **Test cleanup**: 🚨 MANDATORY - Use `await trash([paths])` in test scripts/utilities only. For cleanup within `/src/` test files, use `fs.rm()` with proper error handling
8589

8690
### Git Commit Guidelines
8791
- **🚨 FORBIDDEN**: NEVER add Claude co-authorship or Claude signatures to commits
8892
- **🚨 FORBIDDEN**: Do NOT include "Generated with Claude Code" or similar AI attribution in commit messages
8993
- **Commit messages**: Should be written as if by a human developer, focusing on the what and why of changes
9094
- **Professional commits**: Write clear, concise commit messages that describe the actual changes made
95+
- **Pithy messages**: Keep commit messages concise and to the point - avoid lengthy explanations
9196

9297
### Running the CLI locally
93-
- **Build and run**: `npm run build && npm exec socket` or `pnpm build && pnpm exec socket`
94-
- **Quick build + run**: `npm run bs` or `pnpm bs` (builds source only, then runs socket)
95-
- **Run without build**: `npm run s` or `pnpm s` (runs socket directly)
98+
- **Build and run**: `pnpm run build && pnpm exec socket`
99+
- **Quick build + run**: `pnpm run bs` (builds source only, then runs socket)
100+
- **Run without build**: `pnpm run s` (runs socket directly)
96101
- **Native TypeScript**: `./sd` (runs the CLI without building using Node.js native TypeScript support on Node 22+)
97102

98103
### Package Management
@@ -101,6 +106,9 @@ You are a **Principal Software Engineer** responsible for:
101106
- **Add dependency**: `pnpm add <package> --save-exact`
102107
- **Add dev dependency**: `pnpm add -D <package> --save-exact`
103108
- **Update dependencies**: `pnpm update`
109+
- **Script execution**: Always use `pnpm run <script>` for package.json scripts to distinguish from built-in pnpm commands
110+
- ✅ CORRECT: `pnpm run build`, `pnpm run test`, `pnpm run check`
111+
- ❌ AVOID: `pnpm build`, `pnpm test` (unclear if built-in or script)
104112
- **🚨 MANDATORY**: Always add dependencies with exact versions using `--save-exact` flag to ensure reproducible builds
105113
- **Dependency validation**: All dependencies MUST be pinned to exact versions without range specifiers like `^` or `~`
106114
- **Override behavior**: pnpm.overrides in package.json controls dependency versions across the entire project
@@ -148,6 +156,38 @@ Each command follows a consistent pattern:
148156
- Fixtures in `test/fixtures/`
149157
- Coverage reporting available
150158

159+
#### Test Organization Best Practices
160+
- **Modular test files**: Split large test files by functionality (e.g., `main.test.mts``socket-sdk-basic.test.mts`, `socket-sdk-organization.test.mts`, etc.)
161+
- **Test file naming**: Use descriptive names that reflect the module being tested
162+
- **Test directory structure**: 🚨 MANDATORY - Standardize test directory organization across all Socket projects:
163+
```
164+
test/
165+
├── unit/ # Unit tests
166+
├── integration/ # Integration tests (if applicable)
167+
├── fixtures/ # Test fixtures and data files
168+
└── utils/ # Test utilities and helpers
169+
```
170+
- **Test fixtures**: Store reusable test data, mock responses, and sample files in `test/fixtures/` directory
171+
- **Organization**: Group fixtures by test category or functionality
172+
- **File formats**: Support JSON, text, binary files as needed for comprehensive testing
173+
- **Naming**: Use descriptive names that clearly indicate the fixture's purpose
174+
- **Test utilities organization**: 🚨 MANDATORY - Organize test utilities in `test/utils/` directory
175+
- **Directory structure**: Create `test/utils/` subdirectory for reusable test utilities
176+
- **Modular utilities**: Split utilities by purpose into focused modules:
177+
- `environment.mts` - Test environment setup and cleanup (nock, error handling)
178+
- `fixtures.mts` - Test data configurations and mock objects
179+
- `mock-helpers.mts` - Mock setup and configuration utilities
180+
- `constants.mts` - Test constants and configuration values
181+
- **Import paths**: Update all test file imports to reference specific utility modules
182+
- **Cross-project consistency**: Apply this pattern across all Socket projects for standardization
183+
- **Examples**:
184+
- ✅ CORRECT: `import { setupTestEnvironment } from './utils/environment.mts'`
185+
- ✅ CORRECT: `import { TEST_PACKAGE_CONFIGS } from './utils/fixtures.mts'`
186+
- ❌ OLD PATTERN: `import { setupTestEnvironment } from './test-utils.mts'`
187+
- **Test structure**: Group tests by logical functionality, not just by class methods
188+
- **Shared setup**: Use common beforeEach/afterEach patterns across test files
189+
- **Mock management**: Clean up mocks properly to prevent test interference
190+
151191
### External Dependencies
152192
- Bundles external dependencies in `external/` directory
153193
- Uses Socket registry overrides for security
@@ -184,7 +224,6 @@ Each command follows a consistent pattern:
184224

185225
### Dependency Management
186226
- Uses Socket registry overrides for enhanced alternatives
187-
- Custom patches applied to dependencies via `custompatch`
188227
- Overrides specified in package.json for enhanced alternatives
189228

190229
## Changelog Management
@@ -241,8 +280,20 @@ Socket CLI integrates with various third-party tools and services:
241280

242281
### 📁 File Organization
243282
- **File extensions**: Use `.mts` for TypeScript module files
283+
- **Module headers**: 🚨 MANDATORY - All JavaScript/TypeScript modules MUST have `@fileoverview` headers
284+
- **Format**: Use `/** @fileoverview Brief description of module purpose. */` at the top of each file
285+
- **Placement**: Must be the very first content in the file, before imports or other code
286+
- **Content**: Provide a concise, clear description of what the module does and its primary purpose
287+
- **Examples**:
288+
- ✅ CORRECT: `/** @fileoverview CLI command for scanning packages and generating security reports. */`
289+
- ✅ CORRECT: `/** @fileoverview Configuration utilities for Socket CLI settings and preferences. */`
290+
- ❌ FORBIDDEN: Missing @fileoverview header entirely
291+
- ❌ FORBIDDEN: Placing @fileoverview after imports or other code
244292
- **Import order**: Node.js built-ins first, then third-party packages, then local imports
245293
- **Import grouping**: Group imports by source (Node.js, external packages, local modules)
294+
- **Node.js module imports**: 🚨 MANDATORY - Always use `node:` prefix for Node.js built-in modules
295+
- ✅ CORRECT: `import { readFile } from 'node:fs'`, `import path from 'node:path'`
296+
- ❌ FORBIDDEN: `import { readFile } from 'fs'`, `import path from 'path'`
246297
- **Type imports**: 🚨 ALWAYS use separate `import type` statements for TypeScript types, NEVER mix runtime imports with type imports in the same statement
247298
- ✅ CORRECT: `import { readPackageJson } from '@socketsecurity/registry/lib/packages'` followed by `import type { PackageJson } from '@socketsecurity/registry/lib/packages'`
248299
- ❌ FORBIDDEN: `import { readPackageJson, type PackageJson } from '@socketsecurity/registry/lib/packages'`
@@ -261,11 +312,14 @@ Socket CLI integrates with various third-party tools and services:
261312
- **Dynamic imports**: 🚨 FORBIDDEN - Never use dynamic imports (`await import()`). Always use static imports at the top of the file
262313
- **Sorting**: 🚨 MANDATORY - Always sort lists, exports, and items in documentation headers alphabetically/alphanumerically for consistency
263314
- **Comment formatting**: 🚨 MANDATORY - ALL comments MUST follow these rules:
315+
- **Single-line preference**: Prefer single-line comments (`//`) over multiline comments (`/* */`) unless for method headers, module headers, or copyright notices. Use single-line comments for property descriptions, inline explanations, and general code comments.
264316
- **Periods required**: Every comment MUST end with a period, except ESLint disable comments and URLs which are directives/references. This includes single-line, multi-line, inline, and c8 ignore comments.
265317
- **Sentence structure**: Comments should be complete sentences with proper capitalization and grammar.
266318
- **Placement**: Place comments on their own line above the code they describe, not trailing to the right of code.
267319
- **Style**: Use fewer hyphens/dashes and prefer commas, colons, or semicolons for better readability.
268320
- **Examples**:
321+
- ✅ CORRECT: `// Custom GitHub host (default: github.com).` (property description)
322+
- ❌ WRONG: `/** Custom GitHub host (default: github.com). */` (multiline for simple property)
269323
- ✅ CORRECT: `// This function validates user input.`
270324
- ✅ CORRECT: `/* This is a multi-line comment that explains the complex logic below. */`
271325
- ✅ CORRECT: `// eslint-disable-next-line no-await-in-loop` (directive, no period)
@@ -274,6 +328,7 @@ Socket CLI integrates with various third-party tools and services:
274328
- ❌ WRONG: `// this validates input` (no period, not capitalized)
275329
- ❌ WRONG: `const x = 5 // some value` (trailing comment)
276330
- **Await in loops**: When using `await` inside for-loops, add `// eslint-disable-next-line no-await-in-loop` to suppress the ESLint warning when sequential processing is intentional
331+
- **For...of loop type annotations**: 🚨 FORBIDDEN - Never use type annotations in for...of loop variable declarations. TypeScript cannot parse `for await (const chunk: Buffer of stream)` - use `for await (const chunk of stream)` instead and let TypeScript infer the type
277332
- **If statement returns**: Never use single-line return if statements; always use proper block syntax with braces
278333
- **List formatting**: Use `-` for bullet points in text output, not `` or other Unicode characters, for better terminal compatibility
279334
- **Existence checks**: Perform simple existence checks first before complex operations
@@ -287,6 +342,51 @@ Socket CLI integrates with various third-party tools and services:
287342
- **Node.js fs imports**: 🚨 MANDATORY pattern - `import { someSyncThing, promises as fs } from 'node:fs'`
288343
- **Process spawning**: 🚨 FORBIDDEN to use Node.js built-in `child_process.spawn` - MUST use `spawn` from `@socketsecurity/registry/lib/spawn`
289344
- **Number formatting**: 🚨 REQUIRED - Use underscore separators (e.g., `20_000`) for large numeric literals. 🚨 FORBIDDEN - Do NOT modify number values inside strings
345+
- **JSDoc function documentation**: 🚨 MANDATORY - Function JSDoc comments MUST follow this exact pattern:
346+
- **Format**: Description only, with optional `@throws` - NO `@param` or `@returns` tags
347+
- **Order**: Description paragraph, then `@throws` tag (if needed)
348+
- **Closure**: End with `*/` immediately after the last JSDoc tag
349+
- **Examples**:
350+
- ✅ CORRECT:
351+
```javascript
352+
/**
353+
* Check if a string contains a trusted domain using proper URL parsing.
354+
*/
355+
```
356+
-CORRECT (with throws):
357+
```javascript
358+
/**
359+
* Parse a configuration file and validate its contents.
360+
* @throws {Error} When file cannot be read or parsed.
361+
*/
362+
```
363+
-FORBIDDEN: Adding `@param` or `@returns` tags
364+
-FORBIDDEN: Adding extra tags like `@author`, `@since`, `@example`, etc.
365+
-FORBIDDEN: Adding empty lines between JSDoc tags
366+
-FORBIDDEN: Adding extra content after the last JSDoc tag
367+
368+
### 🏗️ Function Options Pattern (MANDATORY)
369+
- **🚨 REQUIRED**: ALL functions accepting options MUST follow this exact pattern:
370+
```typescript
371+
function foo(a: SomeA, b: SomeB, options?: SomeOptions | undefined): FooResult {
372+
const opts = { __proto__: null, ...options } as SomeOptions
373+
// OR for destructuring with defaults:
374+
const { someOption = 'someDefaultValue' } = { __proto__: null, ...options } as SomeOptions
375+
// ... rest of function
376+
}
377+
```
378+
- **Key requirements**:
379+
- Options parameter MUST be optional with `?` and explicitly typed as `| undefined`
380+
- MUST use `{ __proto__: null, ...options }` pattern to prevent prototype pollution
381+
- MUST use `as SomeOptions` type assertion after spreading
382+
- Use destructuring form when you need defaults for individual options
383+
- Use direct assignment form when passing entire options object to other functions
384+
- **Examples**:
385+
-CORRECT: `const opts = { __proto__: null, ...options } as SomeOptions`
386+
-CORRECT: `const { timeout = 5000, retries = 3 } = { __proto__: null, ...options } as SomeOptions`
387+
-FORBIDDEN: `const opts = { ...options }` (vulnerable to prototype pollution)
388+
-FORBIDDEN: `const opts = options || {}` (doesn't handle null prototype)
389+
- ❌ FORBIDDEN: `const opts = Object.assign({}, options)` (inconsistent pattern)
290390
291391
### Error Handling
292392
- **Input validation errors**: Use `InputError` from `src/utils/errors.mts` for user input validation failures (missing files, invalid arguments, etc.)
@@ -357,3 +457,29 @@ Socket CLI integrates with various third-party tools and services:
357457
- All patterns MUST follow established codebase conventions
358458
- Error handling MUST be robust and user-friendly
359459
- Performance considerations MUST be evaluated for any changes
460+
461+
## 📋 Recurring Patterns & Instructions
462+
463+
These are patterns and instructions that should be consistently applied across all Socket projects:
464+
465+
### 🏗️ Mandatory Code Patterns
466+
1. **Options Parameter Pattern**: Use `{ __proto__: null, ...options } as SomeOptions` for all functions accepting options
467+
2. **Reflect.apply Pattern**: Use `const { apply: ReflectApply } = Reflect` and `ReflectApply(fn, thisArg, [])` instead of `.call()` for method invocation
468+
3. **Object Mappings**: Use `{ __proto__: null, ...mapping }` for static string-to-string mappings to prevent prototype pollution
469+
4. **Import Separation**: ALWAYS separate type imports (`import type`) from runtime imports
470+
5. **Node.js Imports**: ALWAYS use `node:` prefix for Node.js built-in modules
471+
6. **🚨 TSGO PRESERVATION**: NEVER replace tsgo with tsc - tsgo provides enhanced performance and should be maintained across all Socket projects
472+
473+
### 🧪 Test Patterns & Cleanup
474+
1. **Remove Duplicate Tests**: Eliminate tests that verify the same functionality across multiple files
475+
2. **Centralize Test Data**: Use shared test fixtures instead of hardcoded values repeated across projects
476+
3. **Focus Test Scope**: Each project should test its specific functionality, not dependencies' core features
477+
478+
### 🔄 Cross-Project Consistency
479+
These patterns should be enforced across all Socket repositories:
480+
- `socket-cli`
481+
- `socket-packageurl-js`
482+
- `socket-registry`
483+
- `socket-sdk-js`
484+
485+
When working in any Socket repository, check CLAUDE.md files in other Socket projects for consistency and apply these patterns universally.

0 commit comments

Comments
 (0)