|
| 1 | +# PROJECT KNOWLEDGE BASE |
| 2 | + |
| 3 | +**Generated:** 2026-03-14 |
| 4 | +**Commit:** 7e10534 |
| 5 | +**Branch:** main |
| 6 | + |
| 7 | +## OVERVIEW |
| 8 | + |
| 9 | +VS Code extension that colors JSX component tags based on `"use client"` directive detection — visually distinguishing React Server Components from Client Components in Next.js App Router projects. |
| 10 | + |
| 11 | +## STRUCTURE |
| 12 | + |
| 13 | +``` |
| 14 | +. |
| 15 | +├── src/ |
| 16 | +│ ├── extension.ts # VS Code lifecycle, config, file watchers, orchestration |
| 17 | +│ ├── analyzer.ts # TS AST parsing, JSX tag extraction, "use client" detection |
| 18 | +│ ├── resolver.ts # Import → file path resolution (tsconfig aliases, barrel re-exports) |
| 19 | +│ └── decorations.ts # VS Code text decoration rendering + hover tooltips |
| 20 | +├── test/ |
| 21 | +│ └── analyzer.test.ts # Integration tests with temp filesystem projects |
| 22 | +├── out/ # Compiled JS output (do NOT edit) |
| 23 | +├── .husky/pre-commit # Runs `bun run lint` before every commit |
| 24 | +└── .oxlintrc.json # Extends eslint-plugin-devup |
| 25 | +``` |
| 26 | + |
| 27 | +## WHERE TO LOOK |
| 28 | + |
| 29 | +| Task | Location | Notes | |
| 30 | +|------|----------|-------| |
| 31 | +| Add new component detection logic | `src/analyzer.ts` | `parseFileAnalysis()` is the core pipeline | |
| 32 | +| Support new import patterns | `src/resolver.ts` | Wraps `ts.resolveModuleName()` with caching | |
| 33 | +| Change decoration colors/style | `src/decorations.ts` | `createDecorationType()` at bottom | |
| 34 | +| Add VS Code events/commands | `src/extension.ts` | All subscriptions in `activate()` | |
| 35 | +| Add extension settings | `package.json` → `contributes.configuration` | Plus `getConfiguration()` in extension.ts | |
| 36 | +| Add/modify tests | `test/analyzer.test.ts` | Uses `createProject()` helper for temp FS | |
| 37 | + |
| 38 | +## CODE MAP |
| 39 | + |
| 40 | +| Symbol | Type | Location | Role | |
| 41 | +|--------|------|----------|------| |
| 42 | +| `ComponentLensAnalyzer` | class | analyzer.ts:41 | Parses JSX, resolves imports, classifies components | |
| 43 | +| `ImportResolver` | class | resolver.ts:27 | Resolves specifiers to file paths with tsconfig support | |
| 44 | +| `LensDecorations` | class | decorations.ts:12 | Applies colored text decorations to editor | |
| 45 | +| `SourceHost` | interface | resolver.ts:5 | File I/O abstraction (enables testing without VS Code) | |
| 46 | +| `ComponentUsage` | interface | analyzer.ts:7 | Core data type flowing from analyzer → decorations | |
| 47 | +| `activate()` | function | extension.ts:17 | Extension entry point; wires everything together | |
| 48 | + |
| 49 | +### Data Flow |
| 50 | + |
| 51 | +``` |
| 52 | +activate() → ComponentLensAnalyzer.analyzeDocument() |
| 53 | + → parseFileAnalysis() [AST parse, extract imports + JSX tags] |
| 54 | + → ImportResolver.resolveImport() [specifier → absolute path] |
| 55 | + → hasUseClientDirective() [check resolved file for "use client"] |
| 56 | + → ComponentUsage[] [tagged ranges with client/server kind] |
| 57 | + → LensDecorations.apply() [color tag delimiters in editor] |
| 58 | +``` |
| 59 | + |
| 60 | +## CONVENTIONS |
| 61 | + |
| 62 | +- **Linter**: oxlint (not ESLint) — run `bun run lint:fix` |
| 63 | +- **Package manager**: bun (but npm-compatible) |
| 64 | +- **Test runner**: Node.js built-in `node:test` — run `bun run test` |
| 65 | +- **Build**: Plain `tsc` (no bundler) — output to `out/` |
| 66 | +- **Publish**: `@vscode/vsce` — manual `vsce publish` |
| 67 | +- **Pre-commit hook**: Husky runs lint automatically |
| 68 | +- **TypeScript**: Strict mode with `noUnusedLocals` + `noUnusedParameters` |
| 69 | +- **Import style**: `node:` prefix for Node builtins, type-only imports where possible |
| 70 | + |
| 71 | +## ANTI-PATTERNS (THIS PROJECT) |
| 72 | + |
| 73 | +- **No error throwing** — All functions return `undefined`/`[]`/`'unknown'` on failure. Never throw. |
| 74 | +- **No logging** — No console.log/debug/warn anywhere. Only `vscode.window.showInformationMessage` for user-facing feedback. |
| 75 | +- **No `any` types** — Full strict TypeScript; uses `satisfies` for type narrowing. |
| 76 | +- **Don't edit `out/`** — Generated directory; always edit `src/` and rebuild. |
| 77 | + |
| 78 | +## UNIQUE STYLES |
| 79 | + |
| 80 | +- **Signature-based caching**: Files tracked by `"disk:{mtime}:{size}"` or `"open:{version}"` tokens. When adding new caches, follow this pattern. |
| 81 | +- **Graceful degradation**: Extension silently shows fewer decorations rather than crashing. Unresolvable imports are skipped, not errored. |
| 82 | +- **Tag-only coloring**: Only `<Component`, `>`, `/>`, `</Component>` get colored — props are left untouched. Ranges are explicit `{start, end}` byte offsets. |
| 83 | +- **`SourceHost` abstraction**: All file I/O goes through this interface. Production uses `WorkspaceSourceHost` (extension.ts:192); tests use an in-memory mock. |
| 84 | +- **Component detection**: Only capitalized identifiers (`/^[A-Z]/`) are treated as components (React convention). Recognizes `forwardRef`, `memo`, `React.forwardRef`, `React.memo` wrappers. |
| 85 | + |
| 86 | +## COMMANDS |
| 87 | + |
| 88 | +```bash |
| 89 | +bun run build # Compile TS → out/ |
| 90 | +bun run watch # Watch mode |
| 91 | +bun run lint # oxlint check |
| 92 | +bun run lint:fix # oxlint auto-fix |
| 93 | +bun run test # Build + run Node.js tests |
| 94 | +``` |
| 95 | + |
| 96 | +## NOTES |
| 97 | + |
| 98 | +- **Runtime dependency on TypeScript**: `typescript` is listed under `dependencies` (not devDependencies) because the extension uses `ts.createSourceFile()` and `ts.resolveModuleName()` at runtime for AST parsing. |
| 99 | +- **VS Code engine >=1.110.0**: Uses `DecorationRangeBehavior.ClosedClosed` and other modern APIs. |
| 100 | +- **Test helper `createProject()`**: Creates real temp directories with files, returns a `SourceHost` mock. Uses `Symbol.dispose()` for cleanup — always wrap in try/finally. |
| 101 | +- **No CI/CD**: Quality enforcement is local-only (husky pre-commit). No GitHub Actions or automated publishing. |
0 commit comments