|
1 | 1 | # CLAUDE.md |
2 | 2 |
|
3 | | -🚨 **CRITICAL**: This file contains MANDATORY guidelines for Claude Code (claude.ai/code). You MUST follow these guidelines EXACTLY as specified. Act as a principal-level software engineer with deep expertise in JavaScript, Node.js, and package URL parsing. |
| 3 | +🚨 **MANDATORY**: Act as principal-level engineer with deep expertise in JavaScript, Node.js, and package URL parsing. |
4 | 4 |
|
5 | 5 | ## 📚 SHARED STANDARDS |
6 | 6 |
|
7 | | -**This project follows Socket's unified development standards.** For comprehensive guidelines on: |
8 | | -- Code style (imports, sorting, __proto__ patterns, comments) |
9 | | -- Git workflow (GitHub Actions, CI, commit messages) |
10 | | -- Error handling standards and message patterns |
11 | | -- Cross-platform compatibility |
12 | | -- Testing best practices (Vitest memory optimization) |
13 | | -- Dependency alignment |
14 | | -- Changelog management |
| 7 | +**See canonical reference:** `../socket-registry/CLAUDE.md` |
15 | 8 |
|
16 | | -**See the canonical reference:** `socket-registry/CLAUDE.md` (in sibling repository) |
| 9 | +For all shared Socket standards (git workflow, testing, code style, imports, sorting, error handling, cross-platform, CI, etc.), refer to socket-registry/CLAUDE.md. |
17 | 10 |
|
18 | | -This file contains **Package URL (purl) specific** rules and patterns. When in doubt, consult socket-registry/CLAUDE.md first. |
19 | | - |
20 | | -## 🎯 YOUR ROLE |
21 | | - |
22 | | -You are a **Principal Software Engineer** responsible for production-quality code, architectural decisions, and system reliability. |
23 | | - |
24 | | -## 🔍 PRE-ACTION PROTOCOL |
25 | | - |
26 | | -- **🚨 MANDATORY**: Before ANY action, review both this file AND socket-registry/CLAUDE.md |
27 | | -- Check before you act - ensure approach follows established patterns |
28 | | -- No exceptions for code changes, commits, documentation, testing, file operations |
29 | | - |
30 | | -## 🛡️ ABSOLUTE RULES |
31 | | - |
32 | | -- 🚨 **NEVER** create files unless absolutely necessary |
33 | | -- 🚨 **ALWAYS** prefer editing existing files |
34 | | -- 🚨 **FORBIDDEN** to proactively create documentation files unless explicitly requested |
35 | | -- 🚨 **REQUIRED** to do exactly what was asked - nothing more, nothing less |
| 11 | +--- |
36 | 12 |
|
37 | | -## 🏗️ ARCHITECTURE |
| 13 | +## 🏗️ PURL-SPECIFIC |
38 | 14 |
|
39 | | -### TypeScript Implementation of Package URL Specification |
40 | | -Parsing and constructing package URLs, compiled to CommonJS for deployment. |
| 15 | +### Architecture |
| 16 | +TypeScript implementation of [Package URL specification](https://github.com/package-url/purl-spec) - Compiled to CommonJS for deployment |
41 | 17 |
|
42 | | -### Core Structure |
43 | | -- **Main entry**: `src/package-url.ts` - Main exports and API |
| 18 | +**Core Structure**: |
| 19 | +- **Main**: `src/package-url.ts` - Main exports and API |
44 | 20 | - **Parser**: Core parsing logic for purl strings |
45 | | -- **Normalizer**: Normalization logic for different package types |
| 21 | +- **Normalizer**: Type-specific normalization |
46 | 22 | - **Validator**: Input validation and sanitization |
47 | | -- **Types**: Type-specific handling for npm, pypi, maven, etc. |
48 | | -- **Build output**: `dist/` - CommonJS compilation output |
49 | | - |
50 | | -### Key Features |
51 | | -- Full purl specification compliance |
52 | | -- High-performance parsing with TypeScript type safety |
53 | | -- Type-specific normalization |
54 | | -- Comprehensive validation |
55 | | -- Extensive test coverage |
56 | | -- CommonJS-only deployment for maximum compatibility |
| 23 | +- **Types**: Type-specific handling (npm, pypi, maven, etc.) |
| 24 | +- **Build**: `dist/` - CommonJS output |
57 | 25 |
|
58 | | -## ⚡ COMMANDS |
| 26 | +**Features**: Full purl spec compliance, high-performance parsing, TypeScript type safety, type-specific normalization, CommonJS-only deployment |
59 | 27 |
|
60 | | -### Development Commands |
| 28 | +### Commands |
61 | 29 | - **Build**: `pnpm build` |
62 | | -- **Test**: `pnpm test` |
63 | | -- **Test unit**: `pnpm test:unit` |
| 30 | +- **Test**: `pnpm test`, `pnpm test:unit` |
64 | 31 | - **Type check**: `pnpm check:tsc` |
65 | 32 | - **Lint**: `pnpm check:lint` |
66 | 33 | - **Check all**: `pnpm check` |
67 | | -- **Fix linting**: `pnpm check:lint:fix` or `pnpm fix` |
| 34 | +- **Fix**: `pnpm check:lint:fix` or `pnpm fix` |
68 | 35 | - **Coverage**: `pnpm coverage` |
69 | 36 |
|
70 | | -### Testing Best Practices |
71 | | -- **🚨 NEVER USE `--` BEFORE TEST FILE PATHS** - Runs ALL tests! |
72 | | -- **Test single file**: ✅ CORRECT: `pnpm test:unit path/to/file.test.js` |
73 | | - - ❌ WRONG: `pnpm test:unit -- path/to/file.test.js` |
74 | | -- **Update snapshots**: `pnpm test:unit -u` or `pnpm testu` |
75 | | -- **🚨 MANDATORY Coverage Requirements**: Before pushing commits, ensure test coverage is maintained or improved |
76 | | - - **Never decrease coverage**: All changes MUST maintain or increase existing coverage percentages |
77 | | - - **Check before push**: Run `pnpm run test` to verify coverage thresholds are met |
78 | | - - **Fix coverage drops**: If coverage decreases, add tests to restore or improve coverage before pushing |
79 | | - - **Rationale**: Declining coverage indicates untested code paths, which increases risk of bugs and regressions |
80 | | - |
81 | | -### CI Testing Infrastructure |
82 | | -- **🚨 MANDATORY**: Use `SocketDev/socket-registry/.github/workflows/ci.yml@<SHA>` with full commit SHA (not @main) |
83 | | -- **🚨 CRITICAL**: GitHub Actions require full-length commit SHAs. Format: `@662bbcab1b7533e24ba8e3446cffd8a7e5f7617e # main` |
84 | | -- **Reusable workflows**: Socket-registry provides centralized, reusable workflows for lint/type-check/test/coverage |
85 | | -- **Benefits**: Parallel execution, consistent configuration, cross-platform testing |
86 | | -- **Documentation**: See `docs/CI_TESTING.md` and `socket-registry/docs/CI_TESTING_TOOLS.md` |
87 | | - |
88 | | -## 📋 PURL-SPECIFIC RULES |
89 | | - |
90 | | -### 1. Package URL Standards |
91 | | -- Implements [Package URL specification](https://github.com/package-url/purl-spec) |
| 37 | +### PURL Standards |
| 38 | + |
| 39 | +#### Specification Compliance |
92 | 40 | - Maintain strict compliance with purl spec |
93 | 41 | - Test against reference implementations |
94 | | -- Document any deviations or extensions |
| 42 | +- Document any deviations/extensions |
| 43 | +- Never throw on valid purls per spec |
95 | 44 |
|
96 | | -### 2. Performance Critical |
97 | | -- High-performance parser used in security scanning |
| 45 | +#### Performance Critical |
| 46 | +- High-performance parser for security scanning |
98 | 47 | - Optimize for speed without sacrificing correctness |
99 | 48 | - Benchmark changes against existing performance |
100 | 49 | - Avoid unnecessary allocations |
101 | 50 |
|
102 | | -### 3. Error Handling - PurlError Patterns |
| 51 | +### Error Handling - PurlError Patterns |
103 | 52 |
|
104 | 53 | #### Error Types |
105 | | -- **Custom error type**: Use `PurlError` from `src/error.js` for parser-specific errors |
106 | | -- **Standard errors**: Use `Error` only for generic argument validation |
107 | | -- **Catch parameters**: 🚨 MANDATORY - Use `catch (e)` not `catch (error)` |
| 54 | +- **PurlError**: Parser-specific errors from `src/error.js` |
| 55 | +- **Error**: Generic argument validation only |
| 56 | +- **Catch parameters**: 🚨 MANDATORY `catch (e)` not `catch (error)` |
108 | 57 |
|
109 | 58 | #### Error Message Format |
110 | | -- **Parser errors (PurlError)**: No ending period, lowercase start (unless proper noun) |
111 | | - - ✅ CORRECT: `throw new PurlError('missing required "pkg" scheme component')` |
112 | | - - ✅ CORRECT: `throw new PurlError('npm "name" component cannot contain whitespace')` |
113 | | - - ❌ WRONG: `throw new PurlError('Missing required component.')` |
114 | | -- **Argument validation (Error)**: Ending period, sentence case |
115 | | - - ✅ CORRECT: `throw new Error('JSON string argument is required.')` |
116 | | - - ✅ CORRECT: `throw new Error('Invalid JSON string.', { cause: e })` |
117 | | - - ❌ WRONG: `throw new Error('json string required')` |
| 59 | +**Parser errors (PurlError)**: No period, lowercase (unless proper noun) |
| 60 | +- ✅ `throw new PurlError('missing required "pkg" scheme component')` |
| 61 | +- ✅ `throw new PurlError('npm "name" component cannot contain whitespace')` |
| 62 | +- ❌ `throw new PurlError('Missing required component.')` |
| 63 | + |
| 64 | +**Argument validation (Error)**: Period, sentence case |
| 65 | +- ✅ `throw new Error('JSON string argument is required.')` |
| 66 | +- ✅ `throw new Error('Invalid JSON string.', { cause: e })` |
| 67 | +- ❌ `throw new Error('json string required')` |
118 | 68 |
|
119 | 69 | #### Error Message Patterns |
120 | 70 | - **Component validation**: `{type} "{component}" component {violation}` |
121 | 71 | - Example: `cocoapods "name" component cannot contain whitespace` |
122 | | -- **Required components**: `"{component}" is a required component` |
123 | | -- **Type-specific requirements**: `{type} requires a "{component}" component` |
124 | | -- **Qualifier validation**: `qualifier "{key}" {violation}` |
| 72 | +- **Required**: `"{component}" is a required component` |
| 73 | +- **Type requirements**: `{type} requires a "{component}" component` |
| 74 | +- **Qualifier**: `qualifier "{key}" {violation}` |
125 | 75 | - Example: `qualifier "tag_id" must not be empty` |
126 | 76 | - **Parse failures**: `failed to parse as {format}` or `unable to decode "{component}" component` |
127 | | -- **Character restrictions**: Use specific descriptions like `cannot start with`, `cannot contain` |
| 77 | +- **Character restrictions**: `cannot start with`, `cannot contain` |
128 | 78 |
|
129 | | -#### Error Handling Requirements |
130 | | -- **Spec compliance**: Never throw on valid purls per spec |
131 | | -- **Error context**: Include `{ cause: e }` when wrapping underlying errors |
132 | | -- **No process.exit()**: Never use `process.exit(1)` - throw errors instead |
133 | | -- **No silent failures**: Never use `logger.error()` followed by `return` - throw proper errors |
| 79 | +#### Error Requirements |
| 80 | +- Never throw on valid purls per spec |
| 81 | +- Include `{ cause: e }` when wrapping errors |
| 82 | +- No `process.exit()` - throw errors |
| 83 | +- No silent failures - throw proper errors |
134 | 84 |
|
135 | | -## 🎨 PURL-SPECIFIC CODE PATTERNS |
| 85 | +### TypeScript Patterns |
136 | 86 |
|
137 | | -### File Structure |
138 | | -- **File extensions**: `.ts` for TypeScript, `.js` for JavaScript, `.mjs` for ES modules |
139 | | -- **Naming**: kebab-case (e.g., `package-url.ts`, `purl-type.ts`) |
140 | | -- **Module headers**: 🚨 MANDATORY - All modules MUST have `@fileoverview` headers |
| 87 | +#### Optional Properties |
| 88 | +With `exactOptionalPropertyTypes`, assign conditionally: |
| 89 | +- ✅ `if (value !== undefined) { this.prop = value }` |
| 90 | +- ❌ `this.prop = value ?? undefined` |
141 | 91 |
|
142 | | -### TypeScript Patterns |
143 | | -- **Optional properties**: With `exactOptionalPropertyTypes`, assign conditionally |
144 | | - - ✅ CORRECT: `if (value !== undefined) { this.prop = value }` |
145 | | - - ❌ WRONG: `this.prop = value ?? undefined` |
146 | | - |
147 | | -### Index Signatures & Bracket Notation |
148 | | -- **Access pattern**: 🚨 MANDATORY - Use bracket notation with index signatures |
149 | | - - ✅ CORRECT: `obj['prop']?.['method']` |
150 | | - - ❌ WRONG: `obj.prop.method` |
151 | | -- **Type assertions**: Use with bracket notation |
152 | | - - ✅ CORRECT: `(obj['method'] as MethodType)?.(arg)` |
153 | | -- **Reusable types**: Define common patterns once |
154 | | - - `ComponentEncoder = (_value: unknown) => string` |
155 | | - - `ComponentNormalizer = (_value: string) => string | undefined` |
156 | | - - `QualifiersValue = string | number | boolean | null | undefined` |
157 | | - |
158 | | -## 🔧 GIT WORKFLOW |
159 | | - |
160 | | -### Commit Messages |
161 | | -- **🚨 ABSOLUTELY FORBIDDEN**: NEVER add Claude Code attribution to commit messages |
162 | | - - ❌ WRONG: Adding "🤖 Generated with [Claude Code]..." or "Co-Authored-By: Claude" |
163 | | - - ✅ CORRECT: Write commit messages without any AI attribution or signatures |
164 | | - - **Rationale**: This is a professional project and commit messages should not contain AI tool attributions |
165 | | - |
166 | | -### Pre-Commit Quality Checks |
167 | | -- **🚨 MANDATORY**: Always run these commands before committing: |
168 | | - - `pnpm fix` - Fix linting and formatting issues |
169 | | - - `pnpm check` - Run all checks (lint, type-check, tests) |
170 | | - - **Rationale**: Ensures code quality regardless of whether hooks run |
171 | | - |
172 | | -### Commit Strategy with --no-verify |
173 | | -- **--no-verify usage**: Use `--no-verify` flag for commits that don't require pre-commit hooks |
174 | | - - ✅ **Safe to skip hooks**: GitHub Actions workflows (.github/workflows/), tests (test/), documentation (*.md), configuration files |
175 | | - - ❌ **Always run hooks**: Package source code (src/), published library code, parser implementations |
176 | | - - **Important**: Even when using `--no-verify`, you MUST still run `pnpm fix` and `pnpm check` manually first |
177 | | - - **Rationale**: Pre-commit hooks run linting and type-checking which are critical for library code but less critical for non-published files |
178 | | - |
179 | | -### Batch Commits Strategy |
180 | | -- **When making many changes**: Break large changesets into small, logical commits |
181 | | -- **First commit with tests**: Run full test suite (hooks) for the first commit only |
182 | | -- **Subsequent commits with --no-verify**: Use `--no-verify` for follow-up commits |
183 | | -- **Example workflow**: |
184 | | - 1. Make all changes and ensure `pnpm fix && pnpm check` passes |
185 | | - 2. Stage and commit core changes with hooks: `git commit -m "message"` |
186 | | - 3. Stage and commit related changes: `git commit --no-verify -m "message"` |
187 | | - 4. Stage and commit cleanup: `git commit --no-verify -m "message"` |
188 | | - 5. Stage and commit docs: `git commit --no-verify -m "message"` |
189 | | -- **Rationale**: Reduces commit time while maintaining code quality through initial validation |
190 | | - |
191 | | -## 🔍 DEBUGGING |
192 | | - |
193 | | -### Performance Testing |
194 | | -- Use benchmarks to verify parsing speed |
195 | | -- Test against purl-spec test suite |
196 | | -- Test with unusual but valid package URLs |
| 92 | +#### Index Signatures & Bracket Notation |
| 93 | +🚨 MANDATORY - Use bracket notation with index signatures: |
| 94 | +- ✅ `obj['prop']?.['method']` |
| 95 | +- ❌ `obj.prop.method` |
197 | 96 |
|
198 | | -## 📝 SCRATCH DOCUMENTS |
| 97 | +**Type assertions**: Use with bracket notation |
| 98 | +- ✅ `(obj['method'] as MethodType)?.(arg)` |
199 | 99 |
|
200 | | -### Working Documents Directory |
201 | | -- **Location**: `.claude/` directory (gitignored) |
202 | | -- **Purpose**: Store scratch documents, planning notes, analysis reports, and temporary documentation |
203 | | -- **🚨 CRITICAL**: NEVER commit files in `.claude/` to version control |
204 | | -- **Examples of scratch documents**: |
205 | | - - Working notes and implementation plans |
206 | | - - Analysis reports from codebase investigations |
207 | | - - Temporary documentation and TODO lists |
208 | | - - Any files not intended for production use |
| 100 | +**Reusable types**: Define common patterns once |
| 101 | +- `ComponentEncoder = (_value: unknown) => string` |
| 102 | +- `ComponentNormalizer = (_value: string) => string | undefined` |
| 103 | +- `QualifiersValue = string | number | boolean | null | undefined` |
209 | 104 |
|
210 | | ---- |
| 105 | +### Testing |
| 106 | +- **🚨 NEVER USE `--` before test paths** - runs ALL tests |
| 107 | +- **Test single file**: ✅ `pnpm test:unit path/to/file.test.js` |
| 108 | +- **Update snapshots**: `pnpm test:unit -u` or `pnpm testu` |
| 109 | + |
| 110 | +### CI Testing |
| 111 | +- **🚨 MANDATORY**: `SocketDev/socket-registry/.github/workflows/ci.yml@<SHA>` with full SHA |
| 112 | +- **Format**: `@662bbcab1b7533e24ba8e3446cffd8a7e5f7617e # main` |
| 113 | +- **Docs**: `docs/CI_TESTING.md`, `socket-registry/docs/CI_TESTING_TOOLS.md` |
211 | 114 |
|
212 | | -**For all other standards not covered here, refer to `socket-registry/CLAUDE.md` (in sibling repository)** |
| 115 | +### Debugging |
| 116 | +- Use benchmarks to verify parsing speed |
| 117 | +- Test against purl-spec test suite |
| 118 | +- Test unusual but valid package URLs |
0 commit comments