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.
- package/package.json +1 -1
- package/docs/dev/API_STABILITY.md +0 -319
- package/docs/dev/DECISIONS.md +0 -22
- package/docs/dev/DOCUMENTATION_PLAN.md +0 -113
- package/docs/dev/PHASE10_TASKS.md +0 -476
- package/docs/dev/PHASE11_TASKS.md +0 -385
- package/docs/dev/PHASE12_TASKS.md +0 -335
- package/docs/dev/PHASE13_TASKS.md +0 -381
- package/docs/dev/PHASE14_TASKS.md +0 -371
- package/docs/dev/PHASE15_TASKS.md +0 -256
- package/docs/dev/PHASE16_TASKS.md +0 -314
- package/docs/dev/PHASE17_TASKS.md +0 -321
- package/docs/dev/PHASE18_TASKS.md +0 -345
- package/docs/dev/PHASE19_TASKS.md +0 -261
- package/docs/dev/PHASE1_TASKS.md +0 -443
- package/docs/dev/PHASE20_TASKS.md +0 -280
- package/docs/dev/PHASE21_TASKS.md +0 -355
- package/docs/dev/PHASE22_TASKS.md +0 -371
- package/docs/dev/PHASE23_TASKS.md +0 -274
- package/docs/dev/PHASE24_TASKS.md +0 -326
- package/docs/dev/PHASE25_TASKS.md +0 -452
- package/docs/dev/PHASE26_TASKS.md +0 -253
- package/docs/dev/PHASE27_TASKS.md +0 -410
- package/docs/dev/PHASE2_TASKS.md +0 -328
- package/docs/dev/PHASE3_TASKS.md +0 -571
- package/docs/dev/PHASE4_TASKS.md +0 -531
- package/docs/dev/PHASE5_TASKS.md +0 -835
- package/docs/dev/PHASE6_TASKS.md +0 -347
- package/docs/dev/PHASE7_TASKS.md +0 -257
- package/docs/dev/PHASE8_TASKS.md +0 -299
- package/docs/dev/PHASE9_TASKS.md +0 -320
- package/docs/dev/PureContext_MCP_PRD_v1.0.docx +0 -0
- package/docs/dev/SELF_HOSTING.md +0 -142
- package/docs/dev/TEAM_SETUP.md +0 -316
- package/docs/dev/TELEMETRY.md +0 -99
- package/docs/dev/feature-analysis.md +0 -305
- 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.
|