purecontext-mcp 1.1.1 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/package.json +1 -1
  2. package/docs/dev/API_STABILITY.md +0 -319
  3. package/docs/dev/DECISIONS.md +0 -22
  4. package/docs/dev/DOCUMENTATION_PLAN.md +0 -113
  5. package/docs/dev/PHASE10_TASKS.md +0 -476
  6. package/docs/dev/PHASE11_TASKS.md +0 -385
  7. package/docs/dev/PHASE12_TASKS.md +0 -335
  8. package/docs/dev/PHASE13_TASKS.md +0 -381
  9. package/docs/dev/PHASE14_TASKS.md +0 -371
  10. package/docs/dev/PHASE15_TASKS.md +0 -256
  11. package/docs/dev/PHASE16_TASKS.md +0 -314
  12. package/docs/dev/PHASE17_TASKS.md +0 -321
  13. package/docs/dev/PHASE18_TASKS.md +0 -345
  14. package/docs/dev/PHASE19_TASKS.md +0 -261
  15. package/docs/dev/PHASE1_TASKS.md +0 -443
  16. package/docs/dev/PHASE20_TASKS.md +0 -280
  17. package/docs/dev/PHASE21_TASKS.md +0 -355
  18. package/docs/dev/PHASE22_TASKS.md +0 -371
  19. package/docs/dev/PHASE23_TASKS.md +0 -274
  20. package/docs/dev/PHASE24_TASKS.md +0 -326
  21. package/docs/dev/PHASE25_TASKS.md +0 -452
  22. package/docs/dev/PHASE26_TASKS.md +0 -253
  23. package/docs/dev/PHASE27_TASKS.md +0 -410
  24. package/docs/dev/PHASE2_TASKS.md +0 -328
  25. package/docs/dev/PHASE3_TASKS.md +0 -571
  26. package/docs/dev/PHASE4_TASKS.md +0 -531
  27. package/docs/dev/PHASE5_TASKS.md +0 -835
  28. package/docs/dev/PHASE6_TASKS.md +0 -347
  29. package/docs/dev/PHASE7_TASKS.md +0 -257
  30. package/docs/dev/PHASE8_TASKS.md +0 -299
  31. package/docs/dev/PHASE9_TASKS.md +0 -320
  32. package/docs/dev/PureContext_MCP_PRD_v1.0.docx +0 -0
  33. package/docs/dev/SELF_HOSTING.md +0 -142
  34. package/docs/dev/TEAM_SETUP.md +0 -316
  35. package/docs/dev/TELEMETRY.md +0 -99
  36. package/docs/dev/feature-analysis.md +0 -305
  37. package/docs/dev/phase-1-notes.md +0 -3
@@ -1,253 +0,0 @@
1
- # Phase 26 — Enhanced Web UI
2
-
3
- **Goal**: Evolve the Web UI from a basic browser into a visual intelligence dashboard — architecture heatmaps, symbol history timelines, test coverage overlays, multi-repo workspaces, and richer dependency graph interaction.
4
-
5
- **Scope rationale**: jCodeMunch has no UI at all. PureContext's Web UI (Phase 13) is a significant differentiator. This phase deepens it with visuals that make architecture analysis intuitive and that surface the data computed in Phases 24–25 in a way that non-agent users can also benefit from.
6
-
7
- ---
8
-
9
- ## Task 163: Architecture Heatmap
10
-
11
- Overlay code quality and churn data (from Phases 24–25) onto the file tree, turning it into a visual risk map of the codebase.
12
-
13
- **Current state**: The file tree (`src/ui/src/components/FileTree.tsx`) shows directory structure with file extension badges. It has no visual indication of code quality, complexity, or change frequency.
14
-
15
- **Deliverables**:
16
-
17
- - `src/ui/src/components/HeatmapLegend.tsx` — color scale legend with toggle between `complexity`, `churn`, and `combined` modes
18
- - `src/ui/src/components/FileTree.tsx` — extend with heatmap support:
19
- - Each file node gets a colored left-border or background tint based on the selected metric
20
- - Color scale: green (low/good) → yellow (moderate) → orange (high) → red (critical)
21
- - Tooltip on hover: "Avg complexity: 8.3 | Churn: 12 commits/90d | 3 critical symbols"
22
- - Heatmap mode toggle button in the file tree header
23
- - `src/ui/src/api/client.ts` — add `api.getQualityMetrics(repoId, scope?)` and `api.getChurnMetrics(repoId, scope?)`
24
- - `src/server/http-server.ts` — add REST endpoints:
25
- - `GET /api/repos/:id/quality?scope=...` → `get_quality_metrics` tool
26
- - `GET /api/repos/:id/churn?scope=...&days=...` → `get_churn_metrics` tool
27
- - Heatmap data is loaded lazily when the user enables heatmap mode (not on initial page load)
28
- - Directory nodes: aggregate their children's scores (max for critical display, avg for gradient)
29
- - Color interpolation: use D3's `scaleSequential` with a `RdYlGn` color scale (red-yellow-green)
30
-
31
- **Key technical notes**:
32
- - Heatmap data should be cached in the Zustand store — don't re-fetch on every tree expand
33
- - If quality metrics are not available for a repo (never calculated), show a banner: "Run analysis to enable heatmap" with a button that triggers re-indexing
34
- - Three modes: `complexity` (cyclomatic), `churn` (commits/90d), `combined` (weighted: 60% complexity, 40% churn)
35
- - Colorblind-safe: add an optional pattern overlay (dots = high complexity, stripes = high churn) for accessibility
36
-
37
- **Tests**: `test/ui/heatmap.test.ts`
38
- - HeatmapLegend renders with three mode options
39
- - FileTree applies correct color class based on score
40
- - Tooltip content matches mock data
41
- - Directory aggregation: max of children used for critical display
42
-
43
- **Verify**:
44
- ```bash
45
- npm run dev # Navigate to repo detail, enable heatmap — file tree should show colored risk indicators
46
- ```
47
-
48
- ---
49
-
50
- ## Task 164: Symbol Change Timeline
51
-
52
- Display the git history of a symbol as an interactive timeline in the symbol view page, showing who changed it, when, and how frequently.
53
-
54
- **Current state**: The symbol view page (`src/ui/src/pages/SymbolView.tsx`) shows source code, signature, summary, and related symbols. There is no git history view.
55
-
56
- **Deliverables**:
57
-
58
- - `src/ui/src/components/SymbolTimeline.tsx` — new component:
59
- - Horizontal timeline with commit dots on a date axis (last 12 months or N commits)
60
- - Each dot represents a commit; size indicates lines changed
61
- - Hover tooltip: author avatar (initials), date, commit message
62
- - Click to expand: show the diff summary for that commit (lines added/removed in the symbol's range)
63
- - Color coding: dots colored by author (consistent per-author color derived from name hash)
64
- - Churn score badge: "12 commits in 90d — Volatile"
65
- - `src/ui/src/pages/SymbolView.tsx` — add "History" tab alongside "Source" and "Related":
66
- - Tab shows `SymbolTimeline` component
67
- - Tab is hidden if no git history data available for the repo
68
- - `src/ui/src/api/client.ts` — add `api.getSymbolHistory(repoId, symbolId, limit?)`
69
- - `src/server/http-server.ts` — add `GET /api/repos/:id/symbols/:symbolId/history?limit=...`
70
- - `src/ui/src/api/types.ts` — add `SymbolHistoryResponse`, `SymbolCommit` types
71
-
72
- **Key technical notes**:
73
- - Author color: `hsl(hash(authorEmail) % 360, 70%, 50%)` — deterministic, visually distinct
74
- - Commit message should be truncated at 60 chars with ellipsis in the timeline dot tooltip
75
- - If `get_symbol_history` returns no results (non-git repo), the tab is hidden
76
- - Timeline D3 axis: use `scaleTime` for the x-axis; 12-month window by default, zoom to all-time via button
77
- - The "diff summary" on commit click is optional (lines +/-) — derive from `linesAdded`/`linesRemoved` stored in git_metadata
78
-
79
- **Tests**: `test/ui/symbolTimeline.test.ts`
80
- - Timeline renders correct number of dots for mock history
81
- - Tooltip appears on hover with author, date, message
82
- - Churn score badge shows correct value
83
- - "History" tab hidden when history empty
84
-
85
- **Verify**:
86
- ```bash
87
- npm run dev # Navigate to a symbol in a git-indexed repo, click "History" tab
88
- ```
89
-
90
- ---
91
-
92
- ## Task 165: Test Coverage Overlay
93
-
94
- Show which symbols in the file tree and symbol view have associated test coverage, and link directly to the test file/symbol.
95
-
96
- **Current state**: PureContext indexes test files (they end up in the symbol index) but does not link test symbols to the production symbols they test. There is no visual coverage indicator anywhere in the UI.
97
-
98
- **Deliverables**:
99
-
100
- - `src/core/test-mapper.ts` — new module:
101
- ```typescript
102
- interface TestMapping {
103
- symbolId: string; // Production symbol
104
- testSymbolIds: string[]; // Test symbols that reference this production symbol
105
- testFilePaths: string[];
106
- coverageStatus: 'tested' | 'untested' | 'unknown';
107
- }
108
-
109
- async function buildTestMappings(repoId: string, db: Database): Promise<TestMapping[]>
110
- ```
111
- - Heuristic: test files are in `test/`, `__tests__/`, `spec/`, or end with `.test.ts`, `.spec.ts`
112
- - For each test file, find referenced production symbol names via `find_references` logic
113
- - Map test → production symbol by name match within the same repo
114
- - Store in `provider_metadata` table: `(repoId, 'test-mapper', symbolId)` → `{ testFiles: [...] }`
115
- - `src/core/index-manager.ts` — run `buildTestMappings` after indexing completes (same pattern as context providers, Task 139)
116
- - UI components:
117
- - `src/ui/src/components/FileTree.tsx` — add coverage dot: green = tested, red = untested, gray = unknown
118
- - `src/ui/src/pages/SymbolView.tsx` — add "Tests" section below "Related Symbols": list test files with links to navigate to the test symbol
119
- - `src/ui/src/pages/Search.tsx` — add `coverageStatus` filter in the filter panel
120
- - `src/server/http-server.ts` — `GET /api/repos/:id/coverage?symbolId=...`
121
- - `src/ui/src/api/client.ts` — add `api.getCoverage(repoId, symbolId?)`
122
-
123
- **Key technical notes**:
124
- - This is a heuristic, not instrumented coverage (no Vitest/Jest integration required) — the goal is "does a test exist that references this symbol?" not "does the test actually execute this code path?"
125
- - Heuristic accuracy: TypeScript projects with co-located tests achieve ~85% accuracy. Flag this clearly in the UI: "Based on symbol references — not instrumented coverage"
126
- - `coverageStatus: 'unknown'` for symbols in files where no test heuristic applies (e.g. types, interfaces)
127
- - Update `buildTestMappings` incrementally on re-index (same as provider pattern)
128
-
129
- **Tests**: `test/core/test-mapper.test.ts`
130
- - Production symbol referenced in test file → `coverageStatus: 'tested'`
131
- - Symbol with no test references → `coverageStatus: 'untested'`
132
- - Interface/type → `coverageStatus: 'unknown'`
133
- - Fixture: `test/fixtures/basic-ts-project/` (already has test files)
134
-
135
- **Verify**:
136
- ```bash
137
- npm run dev # File tree should show coverage dots; SymbolView should show "Tests" section
138
- ```
139
-
140
- ---
141
-
142
- ## Task 166: Multi-Repo Workspace Panel
143
-
144
- Allow users to manage and search across multiple repos in the Web UI without navigating away from the current view.
145
-
146
- **Current state**: The Web UI is single-repo focused. Switching repos requires navigating to the repo list, selecting a different repo, and then navigating back. Cross-repo search from the UI is not possible.
147
-
148
- **Deliverables**:
149
-
150
- - `src/ui/src/components/WorkspacePanel.tsx` — new collapsible sidebar panel:
151
- - Shows all indexed repos as a list with last-indexed date and symbol count
152
- - Each repo can be pinned to a "workspace" (persisted in localStorage)
153
- - Active workspace = set of pinned repos
154
- - "Search all" button triggers cross-repo search across pinned repos
155
- - `src/ui/src/pages/Search.tsx` — update to support multi-repo mode:
156
- - When workspace has > 1 repo, the repo selector becomes a multi-select
157
- - Results show repo name badge on each result card
158
- - `repoIds` passed to `api.searchSymbols()` (uses Task 150 cross-repo search)
159
- - `src/ui/src/stores/workspaceStore.ts` — Zustand store:
160
- ```typescript
161
- interface WorkspaceStore {
162
- pinnedRepos: string[];
163
- activeRepoId: string | null;
164
- pin(repoId: string): void;
165
- unpin(repoId: string): void;
166
- setActive(repoId: string): void;
167
- }
168
- ```
169
- - `src/ui/src/App.tsx` — add workspace panel toggle button in the header (grid icon)
170
- - `src/ui/src/api/client.ts` — update `searchSymbols` to accept `repoIds?: string[]`
171
-
172
- **Key technical notes**:
173
- - Workspace is UI-only state (localStorage) — no server-side persistence needed
174
- - The `WorkspacePanel` opens as an overlay sidebar, not replacing the main content area
175
- - Repos with 0 symbols (failed index) should be visually distinct (gray with error icon)
176
- - Multi-repo search: use the cross-repo search endpoint from Task 150 — results include `repoName` badge
177
-
178
- **Tests**: `test/ui/workspacePanel.test.ts`
179
- - Pin/unpin repos persists to localStorage
180
- - Multi-select search sends `repoIds` array
181
- - Results include repo name badge
182
- - "Search all" triggers search across all pinned repos
183
-
184
- **Verify**:
185
- ```bash
186
- npm run dev # Pin 2 repos in the workspace panel, search — results should show from both repos
187
- ```
188
-
189
- ---
190
-
191
- ## Task 167: Advanced Dependency Graph
192
-
193
- Upgrade the existing dependency graph UI with filtering, clustering, minimap navigation, and path highlighting between two nodes.
194
-
195
- **Current state**: The dependency graph (`src/ui/src/pages/DependencyGraph.tsx`) shows a force-directed graph using React Flow. It supports focus mode and three layouts but lacks filtering, path highlighting, and navigation aids for large graphs.
196
-
197
- **Deliverables**:
198
-
199
- - `src/ui/src/components/GraphControls.tsx` — extend with:
200
- - **Language filter**: dropdown to show only nodes of a specific language (`*.ts`, `*.py`, etc.)
201
- - **Symbol kind filter**: show only files containing routes, or classes, etc.
202
- - **Path highlighter**: two-node selector — click "From" + "From" on any node, then "Find Path" — highlights the shortest import path between them
203
- - **Minimap**: small overview map (React Flow has built-in `<MiniMap>` component — enable it)
204
- - **Cluster by directory**: group nodes into visual clusters by their parent directory
205
- - `src/ui/src/components/GraphViewer.tsx` — add path highlighting:
206
- - BFS from source to target in the current adjacency map (client-side)
207
- - Highlighted path: edges turn blue, non-path nodes dim to 20% opacity
208
- - "Clear path" button to reset
209
- - `src/ui/src/components/GraphNode.tsx` — add:
210
- - Quality indicator dot: colored ring around node based on heatmap score (if available)
211
- - Churn indicator: pulsing animation for hotspot files
212
- - `src/server/http-server.ts` — no new endpoints needed (uses existing `/api/repos/:id/graph`)
213
-
214
- **Key technical notes**:
215
- - Path finding: BFS on the client-side adjacency map (already built in `GraphViewer`). For disconnected graphs, show "No path found" message
216
- - Clustering: React Flow supports node groups/subflows — group nodes by `path.dirname(filePath)`
217
- - Minimap: React Flow's `<MiniMap>` is available — enable and style to match the theme
218
- - Performance: filter changes should re-render immediately — filter on client-side data, not re-fetch from server
219
- - The quality dot and churn pulsing should be opt-in (loaded only when heatmap data is available)
220
-
221
- **Tests**: `test/ui/advancedGraph.test.ts`
222
- - Language filter correctly hides non-matching nodes
223
- - Path highlighting finds shortest path in test graph
224
- - "No path found" message when nodes are disconnected
225
- - Minimap renders
226
- - Cluster mode groups nodes by directory
227
-
228
- **Verify**:
229
- ```bash
230
- npm run dev # Dependency graph → language filter → path highlight between two nodes
231
- ```
232
-
233
- ---
234
-
235
- ## Order of Execution
236
-
237
- ```
238
- 163 (heatmap) ── requires Phase 25 Task 158 (quality metrics) and Phase 24 Task 157 (churn) to be useful
239
- 164 (timeline) ── requires Phase 24 Task 155 (symbol history) to be useful
240
- 165 (test coverage) ── independent (test-mapper runs at index time)
241
- 166 (multi-repo) ── requires Phase 23 Task 150 (cross-repo search)
242
- 167 (adv. graph) ── independent (builds on existing graph UI)
243
- ```
244
-
245
- Recommended sequence: 167 → 165 → 163 → 164 → 166 (so data from earlier phases is available when UI features land)
246
-
247
- ---
248
-
249
- ## Phase 26 Completion
250
-
251
- **Before**: The Web UI is a capable browser. jCodeMunch has nothing comparable.
252
-
253
- **After**: The Web UI is a visual architecture intelligence dashboard. Risk is visible at a glance on the file tree. Symbol history is explorable without leaving the browser. Test coverage is overlaid. Multiple repos are navigable as a single workspace. Dependency paths are traceable with a click. This UI is not just "nice to have" — it's a product differentiator that makes PureContext accessible to non-agent users: architects, tech leads, and code reviewers.
@@ -1,410 +0,0 @@
1
- # Phase 27 — Distribution & Platform
2
-
3
- **Goal**: Remove all friction from PureContext adoption. Let teams share pre-built indexes instantly, auto-reindex on every push, integrate with CI pipelines, browse popular open-source repos without indexing, and access PureContext from their editor without switching to the browser.
4
-
5
- **Scope rationale**: A tool with this much capability is only valuable if it's easy to adopt and stays up to date. jCodeMunch requires manual indexing and has no ecosystem integrations. This phase makes PureContext the ambient intelligence layer for any engineering team — always current, available everywhere, zero setup for common OSS repos.
6
-
7
- ---
8
-
9
- ## Task 168: Index Export & Import
10
-
11
- Serialize a repo's index (SQLite rows + HNSW vectors) into a portable bundle that can be shared between team members, stored in CI artifacts, or loaded on a new machine.
12
-
13
- **Current state**: Indexes live in `~/.purecontext/indexes/` as SQLite databases. Sharing an index requires copying the raw SQLite file — fragile (path coupling), large (includes all repos in one DB), and undocumented.
14
-
15
- **Deliverables**:
16
-
17
- - `src/server/tools/export-index.ts` — new MCP tool:
18
- ```typescript
19
- interface ExportIndexInput {
20
- repoId: string;
21
- outputPath: string; // Where to write the .pcx bundle
22
- includeSource?: boolean; // Default true — include cached file content
23
- includeVectors?: boolean; // Default true — include HNSW embeddings
24
- compress?: boolean; // Default true — gzip the bundle
25
- }
26
-
27
- interface ExportIndexOutput {
28
- outputPath: string;
29
- bundleSize: number; // Bytes
30
- symbolCount: number;
31
- fileCount: number;
32
- vectorCount: number;
33
- repoId: string;
34
- exportedAt: string;
35
- _meta: ResponseMeta;
36
- }
37
- ```
38
- - `src/server/tools/import-index.ts` — new MCP tool:
39
- ```typescript
40
- interface ImportIndexInput {
41
- bundlePath: string; // Path to .pcx bundle
42
- repoPath?: string; // Override the stored root path (for new machines)
43
- merge?: boolean; // Default false — skip if repo already indexed
44
- }
45
-
46
- interface ImportIndexOutput {
47
- repoId: string;
48
- repoPath: string;
49
- symbolCount: number;
50
- fileCount: number;
51
- alreadyExisted: boolean;
52
- _meta: ResponseMeta;
53
- }
54
- ```
55
- - Bundle format (`.pcx` — PureContext index):
56
- ```
57
- header.json — { version, repoId, repoPath, exportedAt, symbolCount }
58
- symbols.json.gz — Array of SymbolRecord
59
- files.json.gz — Array of FileRecord (with content if includeSource: true)
60
- dep_edges.json.gz — Array of DepEdge
61
- vectors.bin.gz — HNSW index binary (if includeVectors: true)
62
- ```
63
- - Export: query all rows for the repo, serialize to the bundle format, gzip each section
64
- - Import: decompress, validate header version, upsert rows into local SQLite, load vectors into HNSW
65
- - Version compatibility: `header.version` must match current schema version; reject older incompatible bundles with a clear error
66
- - `src/config/cli.ts` — add CLI commands:
67
- ```bash
68
- npx purecontext-mcp export --repo /path/to/repo --out ./bundle.pcx
69
- npx purecontext-mcp import --bundle ./bundle.pcx
70
- ```
71
-
72
- **Key technical notes**:
73
- - The bundle is repo-scoped, not full-DB — one repo per bundle for granularity and shareability
74
- - `repoPath` override on import: needed when the bundle was created on a different machine. Stored root path in `repos` table is updated to the local path
75
- - Bundle size: for a 10k-file repo with embeddings, expect ~50MB uncompressed, ~15MB compressed
76
- - The `.pcx` format is versioned — document the schema so third-party tools can consume it
77
-
78
- **Tests**: `test/server/export-import.test.ts`
79
- - Export creates bundle at specified path
80
- - Import restores all symbols and files
81
- - `repoPath` override applied correctly on import
82
- - Version mismatch → clear error
83
- - `merge: false` → skip if repo exists
84
- - Round-trip: export then import produces identical symbol count
85
-
86
- **Verify**:
87
- ```bash
88
- npx purecontext-mcp export --repo ./my-project --out /tmp/my-project.pcx
89
- # Copy to another machine or clone the repo fresh
90
- npx purecontext-mcp import --bundle /tmp/my-project.pcx
91
- ```
92
-
93
- ---
94
-
95
- ## Task 169: Pre-Built Index Registry
96
-
97
- Publish and serve pre-built indexes for the most popular open-source repositories so users can search them without indexing.
98
-
99
- **Current state**: Every user must index a repo before they can search it — even for projects like `expressjs/express` or `facebook/react` that thousands of PureContext users will all index independently.
100
-
101
- **Deliverables**:
102
-
103
- - `src/server/tools/fetch-public-index.ts` — new MCP tool:
104
- ```typescript
105
- interface FetchPublicIndexInput {
106
- repo: string; // "owner/repo" format (GitHub)
107
- version?: string; // Git tag or "latest" (default)
108
- force?: boolean; // Re-download even if cached
109
- }
110
-
111
- interface FetchPublicIndexOutput {
112
- repoId: string;
113
- repo: string;
114
- version: string;
115
- symbolCount: number;
116
- cachedAt: string;
117
- source: 'cache' | 'registry';
118
- _meta: ResponseMeta;
119
- }
120
- ```
121
- - Registry URL: `https://registry.purecontext.dev/indexes/{owner}/{repo}/{version}.pcx`
122
- - Served from a CDN (Cloudflare R2 or similar)
123
- - `latest` resolves to the most recently published version
124
- - Download flow:
125
- 1. Check if repo already indexed locally
126
- 2. Fetch `.pcx` bundle from registry CDN
127
- 3. Import using Task 168's import logic
128
- 4. Mark repo as `source: 'registry'` in `repos` table
129
- - `src/config/cli.ts` — add:
130
- ```bash
131
- npx purecontext-mcp fetch expressjs/express
132
- npx purecontext-mcp list-public # List available pre-built indexes
133
- ```
134
- - Registry manifest: `https://registry.purecontext.dev/manifest.json` — list of available repos + versions + bundle sizes
135
- - Initial corpus (publish as part of this task):
136
- - `expressjs/express`, `fastify/fastify`, `nestjs/nest`
137
- - `facebook/react`, `vuejs/core`, `angular/angular`
138
- - `django/django`, `fastapi/fastapi`, `flask/flask`
139
- - `golang/go` (stdlib), `tokio-rs/axum`, `spring-projects/spring-boot`
140
-
141
- **Key technical notes**:
142
- - Bundle signing: bundles in the registry should be signed (SHA-256 hash in manifest) and verified on download
143
- - CDN caching: bundles are immutable per `{repo}/{sha}.pcx` — cache forever. `latest` pointer changes on new publish
144
- - Update detection: check `repos.git_head` vs registry `latest_sha` — if behind, prompt user to refresh
145
- - Publishing pipeline: a separate GitHub Action runs on the PureContext infra, indexes popular repos nightly, publishes updated bundles. This is infrastructure work not in this task file
146
- - Privacy: only public repos are in the registry — no private repo content ever published
147
-
148
- **Tests**: `test/server/fetch-public-index.test.ts` (mocked CDN)
149
- - Download bundle from mocked registry URL
150
- - Signature verified before import
151
- - `source: 'registry'` set in repos table
152
- - Already cached → no re-download (unless `force: true`)
153
- - Unknown repo → clear error with link to registry manifest
154
-
155
- **Verify**:
156
- ```bash
157
- npx purecontext-mcp fetch expressjs/express
158
- # Should download and import without cloning — search immediately available
159
- ```
160
-
161
- ---
162
-
163
- ## Task 170: Webhook Auto-Reindex
164
-
165
- HTTP endpoint that receives push webhooks from GitHub/GitLab/Bitbucket and automatically triggers re-indexing of the affected repo.
166
-
167
- **Current state**: Indexes go stale after code is pushed. Users must manually call `index_folder` or `index_repo` to refresh. In team environments with shared MCP servers (Phase 18), stale indexes are a usability problem.
168
-
169
- **Deliverables**:
170
-
171
- - `src/server/http-server.ts` — add webhook endpoint:
172
- ```
173
- POST /webhooks/github — GitHub push webhook
174
- POST /webhooks/gitlab — GitLab push webhook
175
- POST /webhooks/generic — Generic JSON webhook
176
- ```
177
- - `src/server/webhooks/github-webhook.ts`:
178
- ```typescript
179
- interface GitHubPushPayload {
180
- ref: string; // e.g. "refs/heads/main"
181
- repository: { full_name: string; clone_url: string; };
182
- head_commit: { id: string; };
183
- commits: { added: string[]; modified: string[]; removed: string[]; }[];
184
- }
185
-
186
- async function handleGitHubPush(
187
- payload: GitHubPushPayload,
188
- secret: string
189
- ): Promise<void>
190
- ```
191
- - HMAC-SHA256 signature verification: GitHub sends `X-Hub-Signature-256` header — verify against configured `WEBHOOK_SECRET`
192
- - Reindex strategy:
193
- 1. Look up the repo by `repository.clone_url` or `full_name` in `repos` table
194
- 2. If found: extract changed file paths from the commits list; run `reindexFiles(repoId, changedPaths)` (incremental)
195
- 3. If not found: optionally auto-index (`AUTO_INDEX_ON_WEBHOOK=true` env var — default false)
196
- - GitLab webhook: analogous structure, different payload format; verify with `X-Gitlab-Token`
197
- - Generic webhook: `POST /webhooks/generic` with body `{ repoPath: string, changedFiles?: string[] }` — useful for custom CI scripts
198
- - `src/config/config-schema.ts` — add:
199
- ```json
200
- {
201
- "webhooks": {
202
- "enabled": true,
203
- "secret": "${WEBHOOK_SECRET}",
204
- "allowedRepos": ["owner/repo"], // Optional allowlist
205
- "autoIndex": false
206
- }
207
- }
208
- ```
209
-
210
- **Key technical notes**:
211
- - Webhook handler runs the reindex in a non-blocking background task — respond `202 Accepted` immediately
212
- - Rate limit webhook triggers: max 1 reindex per repo per 60 seconds (debounce rapid pushes)
213
- - For Docker deployments (Phase 18), the webhook endpoint is already accessible via the HTTP server — just needs to be documented in the Docker setup guide
214
- - Security: never log the raw webhook payload (may contain sensitive commit messages); verify signature before processing any payload content
215
-
216
- **Tests**: `test/server/webhooks.test.ts`
217
- - GitHub push payload triggers reindex of matched repo
218
- - Invalid HMAC signature → 403, no reindex
219
- - Repo not found → 404 (or 202 + auto-index if enabled)
220
- - Rate limiting: second trigger within 60s → 202 but no reindex
221
- - GitLab payload parsed correctly
222
-
223
- **Verify**:
224
- ```bash
225
- # Set up a GitHub webhook pointing to https://your-server/webhooks/github
226
- # Push a commit — the server should log "Incremental reindex triggered for repo X"
227
- ```
228
-
229
- ---
230
-
231
- ## Task 171: GitHub Actions Integration
232
-
233
- Publish a GitHub Actions composite action that indexes a repo, runs anti-pattern checks, posts a blast radius comment on PRs, and uploads the index bundle as an artifact.
234
-
235
- **Current state**: CI integration requires manually calling `npx purecontext-mcp` in shell steps. There is no ready-made GitHub Actions action, no PR comment automation, and no artifact upload.
236
-
237
- **Deliverables**:
238
-
239
- - `action.yml` — GitHub Actions composite action at repo root:
240
- ```yaml
241
- name: PureContext Analysis
242
- description: Index codebase, detect anti-patterns, analyze PR impact
243
- inputs:
244
- token:
245
- description: GitHub token for PR comments
246
- required: true
247
- anthropic-api-key:
248
- description: Optional — enable AI summaries
249
- required: false
250
- analyze-diff:
251
- description: Post blast radius comment on PR
252
- default: 'true'
253
- detect-antipatterns:
254
- description: Fail CI on critical anti-patterns
255
- default: 'false'
256
- upload-index:
257
- description: Upload .pcx bundle as workflow artifact
258
- default: 'true'
259
- runs:
260
- using: composite
261
- steps:
262
- - name: Index repository
263
- run: npx purecontext-mcp index-folder --path ${{ github.workspace }}
264
- - name: Analyze diff (on PR)
265
- if: github.event_name == 'pull_request' && inputs.analyze-diff == 'true'
266
- run: npx purecontext-mcp analyze-diff --diff $(git diff ${{ github.base_ref }}..HEAD)
267
- - name: Post PR comment
268
- uses: actions/github-script@v7
269
- # ... post the analyze-diff output as a PR comment
270
- - name: Detect anti-patterns
271
- if: inputs.detect-antipatterns == 'true'
272
- run: npx purecontext-mcp detect-antipatterns --fail-on-critical
273
- - name: Upload index bundle
274
- if: inputs.upload-index == 'true'
275
- uses: actions/upload-artifact@v4
276
- with:
277
- name: purecontext-index
278
- path: '*.pcx'
279
- ```
280
- - `src/config/cli.ts` — add CLI subcommands used by the action:
281
- - `npx purecontext-mcp analyze-diff --diff <patch>` — prints JSON + exits non-zero on critical findings
282
- - `npx purecontext-mcp detect-antipatterns --fail-on-critical` — exits non-zero if any `error` severity findings
283
- - `npx purecontext-mcp export --auto` — exports current index to `{repoName}-{sha}.pcx`
284
- - PR comment template (markdown):
285
- ```markdown
286
- ## PureContext Analysis
287
-
288
- **Impact Summary**: 3 symbols modified, blast radius: 7 files
289
- **Review Priority**: 🔴 High (1 signature break detected)
290
-
291
- | Symbol | Change | Blast Radius |
292
- |--------|--------|--------------|
293
- | `authenticate()` | Signature changed | 5 files |
294
- | `parseToken()` | Modified | 2 files |
295
-
296
- <details><summary>Anti-pattern findings (2 warnings)</summary>
297
- ...
298
- </details>
299
- ```
300
-
301
- **Key technical notes**:
302
- - The action should work on both public and private repos — GitHub token is required only for posting PR comments
303
- - Cache the PureContext index between runs using `actions/cache` keyed on the repo SHA
304
- - `--fail-on-critical` should produce a non-zero exit code only for `severity: 'error'` findings, not warnings
305
- - Publish the action to the GitHub Marketplace: `purecontext/analyze-action`
306
-
307
- **Tests**: `test/cli/ci-commands.test.ts`
308
- - `analyze-diff` CLI produces correct JSON output
309
- - `detect-antipatterns --fail-on-critical` exits non-zero on errors
310
- - `export --auto` creates correctly named bundle
311
-
312
- **Verify**:
313
- ```yaml
314
- # In a GitHub Actions workflow:
315
- - uses: purecontext/analyze-action@v1
316
- with:
317
- token: ${{ secrets.GITHUB_TOKEN }}
318
- detect-antipatterns: 'true'
319
- ```
320
-
321
- ---
322
-
323
- ## Task 172: VS Code Extension
324
-
325
- A lightweight VS Code extension that surfaces PureContext inline — symbol outline in the sidebar, inline blast radius on hover, and quick-open search — without requiring users to switch to the browser UI.
326
-
327
- **Current state**: PureContext is accessible via the MCP protocol (AI agents) and the Web UI (browser). There is no native editor integration. Developers who want to browse the index while coding must switch contexts.
328
-
329
- **Deliverables**:
330
-
331
- - `vscode-extension/` — separate directory at project root (published separately as `purecontext.purecontext-vscode`):
332
- ```
333
- vscode-extension/
334
- ├── package.json — VS Code extension manifest
335
- ├── src/
336
- │ ├── extension.ts — Activation, command registration
337
- │ ├── client.ts — HTTP client for PureContext server REST API
338
- │ ├── providers/
339
- │ │ ├── outline.ts — TreeDataProvider: file outline in Explorer sidebar
340
- │ │ ├── hover.ts — HoverProvider: blast radius on symbol hover
341
- │ │ └── search.ts — QuickPick: symbol search (Cmd+Shift+P → "PureContext: Search")
342
- │ └── views/
343
- │ └── symbolPanel.ts — WebviewPanel: show symbol detail
344
- └── README.md
345
- ```
346
- - **Sidebar outline** (`TreeDataProvider`):
347
- - Shows current file's symbols in the Explorer sidebar panel
348
- - Click a symbol → jump to its line in the editor
349
- - Symbols grouped by kind with icons
350
- - **Hover provider** (`HoverProvider`):
351
- - On hover over a function/class name: show signature, summary, and "Blast radius: N files" badge
352
- - Click the badge → open the Web UI blast radius page for that symbol
353
- - **Quick-open search** (VS Code QuickPick):
354
- - Command palette: "PureContext: Search Symbols"
355
- - Debounced input → results from `api.searchSymbols`
356
- - Select result → jump to file + line
357
- - **Configuration** (`contributes.configuration`):
358
- ```json
359
- {
360
- "purecontext.serverUrl": "http://localhost:3000",
361
- "purecontext.repoId": "", // Auto-detect if blank
362
- "purecontext.enableHover": true,
363
- "purecontext.enableOutline": true
364
- }
365
- ```
366
- - The extension communicates with PureContext via the existing REST API (`http-server.ts`) — no new server changes needed
367
- - Publish to VS Code Marketplace: `vsce package && vsce publish`
368
-
369
- **Key technical notes**:
370
- - The extension requires the PureContext server to be running (MCP server mode or `--server` flag from Phase 18)
371
- - Auto-detect `repoId`: use `GET /api/repos` and match against the open workspace folder path
372
- - No bundled Node.js or tree-sitter — the extension is purely a UI client over HTTP
373
- - Hover information is cached for 30 seconds per symbol to avoid hammering the server while the user is reading code
374
- - The extension should gracefully degrade when the server is not running (disable features, show status bar message "PureContext: offline")
375
-
376
- **Tests**: Manual testing only for this task (VS Code extension testing infrastructure is complex)
377
- - Sidebar outline shows correct symbols for a TypeScript file
378
- - Hover shows blast radius count
379
- - Quick-open search returns results in < 200ms
380
-
381
- **Verify**:
382
- ```bash
383
- cd vscode-extension && npm install && npm run build
384
- # Install the VSIX in VS Code, open a PureContext-indexed project
385
- # Verify sidebar outline, hover, and search work
386
- ```
387
-
388
- ---
389
-
390
- ## Order of Execution
391
-
392
- ```
393
- 168 (export/import) ── must come first — 169 and 171 depend on it
394
- 169 (public registry) ── depends on 168 (uses import logic)
395
- 170 (webhook) ── independent
396
- 171 (GitHub Actions) ── depends on 168 (uses export), benefits from 156 (analyze_diff)
397
- 172 (VS Code extension) ── independent (uses existing REST API)
398
- ```
399
-
400
- Recommended sequence: 168 → 170 → 172 → 169 → 171
401
-
402
- ---
403
-
404
- ## Phase 27 Completion
405
-
406
- **Before**: PureContext requires manual indexing, has no CI integration, no editor plugin, no way to share indexes, and no zero-setup path for popular OSS repos.
407
-
408
- **After**: Indexes are shareable artifacts. Popular OSS repos are available instantly from the registry. Every git push triggers an automatic reindex. CI pipelines get anti-pattern checks and PR impact comments. VS Code users get PureContext inline without a browser. The adoption barrier for a new team member drops from "set up and index" to "install and go."
409
-
410
- This is the distribution layer that turns a powerful tool into a platform — and positions PureContext as the standard for code intelligence in AI-native development workflows.