project-graph-mcp 2.0.0 → 2.1.0
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/README.md +51 -31
- package/docs/img/explorer-compact.jpg +0 -0
- package/docs/img/explorer-expanded.jpg +0 -0
- package/package.json +1 -1
- package/src/.project-graph-cache.json +1 -1
- package/src/cli/cli-handlers.js +2 -2
- package/src/cli/cli.js +1 -1
- package/src/compact/.project-graph-cache.json +1 -0
- package/src/compact/compact-migrate.js +17 -0
- package/src/compact/compress.js +2 -1
- package/src/compact/mode-config.js +4 -4
- package/src/mcp/mcp-server.js +2 -2
- package/src/mcp/tool-defs.js +1 -1
- package/web/app.js +2 -1
package/README.md
CHANGED
|
@@ -4,10 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
# project-graph-mcp
|
|
6
6
|
|
|
7
|
-
An MCP server that
|
|
7
|
+
**Maximize your AI agent's context window.** An MCP server that lets agents read and edit your codebase in **compact mode** — minified source with all variable names preserved. Code tokens drop **↓40%**, and `.ctx` documentation is injected only in the focus zone. Fewer tokens per file → more files fit in context → **deeper understanding of your codebase**.
|
|
8
|
+
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
Includes a built-in [Web Dashboard](#web-dashboard) (`npx project-graph-mcp serve`) to visualize token metrics and compact ⇄ raw code in real-time.
|
|
8
14
|
|
|
9
15
|
> [!TIP]
|
|
10
|
-
> **18 MCP tools.** Add one line to your MCP config and the server downloads itself on the next IDE restart.
|
|
16
|
+
> **18 MCP tools, zero config.** Add one line to your MCP config and the server downloads itself on the next IDE restart.
|
|
11
17
|
|
|
12
18
|
### Project Skeleton (10-50x compression)
|
|
13
19
|
|
|
@@ -54,7 +60,7 @@ One call loads everything an agent needs to understand a project:
|
|
|
54
60
|
|
|
55
61
|
```javascript
|
|
56
62
|
get_ai_context({ path: "src/" })
|
|
57
|
-
// → { skeleton, docs, totalTokens:
|
|
63
|
+
// → { skeleton, docs, totalTokens: 3150, savings: "93%" }
|
|
58
64
|
```
|
|
59
65
|
|
|
60
66
|
- **Code compression** — Terser-minified source with export legend headers (20-55% per file)
|
|
@@ -107,16 +113,13 @@ get_focus_zone({ path: ".", useGitDiff: true })
|
|
|
107
113
|
// → Context for recently changed files only
|
|
108
114
|
```
|
|
109
115
|
|
|
110
|
-
**Real-world token budget** (45
|
|
116
|
+
**Real-world token budget** (this project's own benchmark, 45 files):
|
|
111
117
|
|
|
112
118
|
```
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
Focus (compact + 3 files ctx): 47.6K tok — same savings + semantic descriptions
|
|
119
|
+
Skeleton + docs only: 3.2K tok — 93% savings, full project overview
|
|
120
|
+
Compact source (agent reads): 46.9K tok — 20-55% savings per file
|
|
116
121
|
```
|
|
117
122
|
|
|
118
|
-
Compact code saves **27% on average** (34-38% for typical files) by stripping whitespace and comments while preserving all names. The `.ctx` cost is **per-file** (~200 tok each) and only loaded for the focus area — the agent gets typed signatures and descriptions that the raw source never had.
|
|
119
|
-
|
|
120
123
|
**Per-file metrics breakdown:**
|
|
121
124
|
|
|
122
125
|
| Layer | What | Tokens |
|
|
@@ -124,22 +127,31 @@ Compact code saves **27% on average** (34-38% for typical files) by stripping wh
|
|
|
124
127
|
| Code (compact .js) | Minified source, all names preserved | codeTok |
|
|
125
128
|
| Context (.ctx) | AST signatures, types, descriptions | ctxTok |
|
|
126
129
|
| Total (focus mode) | What agent reads when focusing | codeTok + ctxTok |
|
|
127
|
-
| Expanded (beautified) | What a human would read (raw source) | expanded |
|
|
128
130
|
|
|
129
131
|
### Compact Code Architecture
|
|
130
132
|
|
|
131
|
-
|
|
133
|
+
Two modes for AI-native codebase editing — configure per project via `.context/config.json`:
|
|
134
|
+
|
|
135
|
+
| Mode | Storage | Agent reads/writes | Human reviews |
|
|
136
|
+
|------|---------|-------------------|---------------|
|
|
137
|
+
| **1 — Compact** ⭐ | Minified JS | `src/` directly | `.expanded/` cache |
|
|
138
|
+
| **2 — Full** | Formatted JS | compressed view | `src/` directly |
|
|
139
|
+
|
|
140
|
+
**Mode 1 — Compact** (recommended for AI-first projects):
|
|
141
|
+
|
|
142
|
+
Source of truth is compact code. Agents read and write it directly — saving tokens in **both directions** (input and output). Since output tokens cost 3-5x more than input, compact output is the biggest cost saving. Humans review via auto-generated `.expanded/` cache with restored names and injected JSDoc.
|
|
132
143
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
144
|
+
```javascript
|
|
145
|
+
// Agent reads and edits compact source directly (20-55% fewer tokens both ways)
|
|
146
|
+
// After edits, validate and generate human-readable cache:
|
|
147
|
+
compact({ action: "validate_pipeline", path: ".", strict: true })
|
|
148
|
+
compact({ action: "expand_project", path: "." })
|
|
149
|
+
```
|
|
138
150
|
|
|
139
|
-
**Mode 2
|
|
151
|
+
**Mode 2 — Full** (for existing projects, no refactoring needed):
|
|
140
152
|
|
|
141
153
|
```javascript
|
|
142
|
-
// 1. Read compressed view (saves
|
|
154
|
+
// 1. Read compressed view (saves input tokens only)
|
|
143
155
|
get_compressed_file({ path: "src/parser.js" })
|
|
144
156
|
|
|
145
157
|
// 2. Edit by symbol name — server finds it via AST
|
|
@@ -153,6 +165,14 @@ edit_compressed({
|
|
|
153
165
|
validate_ctx_contracts({ path: "." })
|
|
154
166
|
```
|
|
155
167
|
|
|
168
|
+
**Migrating from Full to Compact:**
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
# Ensure git is clean, then run automated migration
|
|
172
|
+
npx project-graph-mcp compact-migrate .
|
|
173
|
+
# → compacts all JS, generates @names in .ctx, sets mode 1, validates
|
|
174
|
+
```
|
|
175
|
+
|
|
156
176
|
**`.ctx` typed signatures** — JSDoc types extracted into compact format:
|
|
157
177
|
|
|
158
178
|
```
|
|
@@ -160,8 +180,11 @@ parseFile(code:string,filename:string)→Promise<ParseResult>→parse,walk|parse
|
|
|
160
180
|
```
|
|
161
181
|
|
|
162
182
|
```bash
|
|
183
|
+
# Check current mode
|
|
184
|
+
npx project-graph-mcp mode .
|
|
185
|
+
|
|
163
186
|
# Set project mode
|
|
164
|
-
npx project-graph-mcp set-mode .
|
|
187
|
+
npx project-graph-mcp set-mode . 1
|
|
165
188
|
|
|
166
189
|
# Validate .ctx documentation matches source
|
|
167
190
|
npx project-graph-mcp validate-ctx . --strict
|
|
@@ -226,6 +249,8 @@ Every project-graph-mcp instance includes a built-in web UI at `http://localhost
|
|
|
226
249
|
- **Health panel** — analysis results
|
|
227
250
|
- **Live monitor** — real-time agent activity via WebSocket
|
|
228
251
|
|
|
252
|
+
|
|
253
|
+
|
|
229
254
|
With the optional gateway, all projects are accessible under `http://project-graph.local/{project-name}/`.
|
|
230
255
|
|
|
231
256
|
### Compression Metrics
|
|
@@ -263,20 +288,13 @@ Every tool response includes contextual coaching — if the agent finds a massiv
|
|
|
263
288
|
|
|
264
289
|
## Quick Start
|
|
265
290
|
|
|
266
|
-
|
|
291
|
+
Generate the MCP config for your IDE (with correct paths):
|
|
267
292
|
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
"mcpServers": {
|
|
271
|
-
"project-graph": {
|
|
272
|
-
"command": "npx",
|
|
273
|
-
"args": ["-y", "project-graph-mcp"]
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
}
|
|
293
|
+
```bash
|
|
294
|
+
npx -y project-graph-mcp config
|
|
277
295
|
```
|
|
278
296
|
|
|
279
|
-
|
|
297
|
+
Copy the output JSON into your IDE's MCP config file, then restart.
|
|
280
298
|
|
|
281
299
|
#### Grouped Tools (v2.0)
|
|
282
300
|
|
|
@@ -333,7 +351,9 @@ npx project-graph-mcp docs src/ # Project docs (doc-dialect)
|
|
|
333
351
|
npx project-graph-mcp generate-ctx src/ # Generate .context/ docs
|
|
334
352
|
npx project-graph-mcp validate-ctx . # Validate .ctx ↔ source
|
|
335
353
|
npx project-graph-mcp mode . # Show current editing mode
|
|
336
|
-
npx project-graph-mcp
|
|
354
|
+
npx project-graph-mcp compact-migrate . # Migrate formatted -> compact (git must be clean)
|
|
355
|
+
npx project-graph-mcp set-mode . 1 # Set mode (1=compact*, 2=full)
|
|
356
|
+
npx project-graph-mcp serve . # Start web dashboard
|
|
337
357
|
npx project-graph-mcp help # All commands
|
|
338
358
|
```
|
|
339
359
|
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":1,"path":"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src","mtimes":{"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/analysis-cache.js":1775932068076.741,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/complexity.js":1775932068098.837,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/custom-rules.js":1775932068138.1648,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/db-analysis.js":1775932068151.1123,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/dead-code.js":1775932068179.2783,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/full-analysis.js":1775932068199.422,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/jsdoc-checker.js":1775932068214.1042,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/jsdoc-generator.js":1775932068226.255,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/large-files.js":1775932068231.2554,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/outdated-patterns.js":1775932068241.3853,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/similar-functions.js":1775932068258.163,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/test-annotations.js":1775932068268.5154,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/type-checker.js":1775932068273.1277,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/undocumented.js":1775932068287.6243,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/cli/cli-handlers.js":1775932068298.3313,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/cli/cli.js":1775932068300.5159,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/ai-context.js":1775932068307.1665,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/compact.js":1775932562256.5852,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/compress.js":1775932068329.118,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/ctx-to-jsdoc.js":1775932068348.9448,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/doc-dialect.js":1775932068402.0254,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/expand.js":1775932068432.0977,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/framework-references.js":1775932068436.373,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/instructions.js":1775932068437.6816,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/mode-config.js":1775932068441.0076,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/validate-pipeline.js":1775932068445.2222,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/core/event-bus.js":1775932068446.521,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/core/filters.js":1775932068453.1003,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/core/graph-builder.js":1775932068467.494,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/core/parser.js":1775932068524.0032,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/core/workspace.js":1775932068530.74,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/lang/lang-go.js":1775932068546.679,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/lang/lang-python.js":1775932068554.9434,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/lang/lang-sql.js":1775932068573.637,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/lang/lang-typescript.js":1775932068582.2983,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/lang/lang-utils.js":1775932068585.4934,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/mcp/mcp-server.js":1775932068611.3706,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/mcp/tool-defs.js":1775932068615.0066,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/mcp/tools.js":1775932068628.6646,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/network/backend-lifecycle.js":1775932068638.9226,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/network/backend.js":1775932249992.6167,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/network/local-gateway.js":1775932068657.378,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/network/mdns.js":1775932068663.7195,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/network/server.js":1775932211325.8235,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/network/web-server.js":1775937659045.6243},"graph":{"v":1,"legend":{"computeContentHash":"CH","getCachePath":"CP","readCache":"rC","writeCache":"wC","isCacheValid":"CV","findJSFiles":"JSF","calculateComplexity":"cC","getRating":"gR","analyzeComplexityFile":"CF","analyzeFile":"aF","getComplexity":"gC","parseGraphignore":"pG","isGraphignored":"iG","loadRuleSets":"RS","saveRuleSet":"RS1","findFiles":"fF","isExcluded":"iE","isInStringOrComment":"ISO","isWithinContext":"WC","checkFileAgainstRule":"FAR","getCustomRules":"CR","setCustomRule":"CR1","deleteCustomRule":"CR2","detectProjectRuleSets":"PRS","checkCustomRules":"CR3","getDBSchema":"DBS","getTableUsage":"TU","getDBDeadTables":"DBD","collectReferencedColumns":"RC","findProjectRoot":"PR","analyzeFileLocals":"FL","getDeadCode":"DC","calculateHealthScore":"HS","runCacheableAnalyses":"CA","aggregateComplexity":"aC","aggregateUndocumented":"aU","aggregateJSDoc":"JSD","getFullAnalysis":"FA","getAnalysisSummaryOnly":"ASO","extractJSDocComments":"JSD1","findJSDocBefore":"JSD2","extractParamName":"PN","inferTypeFromDefault":"TFD","hasReturnValue":"RV","validateFunction":"vF","checkJSDocFile":"JSD3","checkJSDocConsistency":"JSD4","generateJSDoc":"JSD5","buildJSDoc":"JSD6","inferParamType":"PT","generateJSDocFor":"JSD7","getLargeFiles":"LF","analyzeFilePatterns":"FP","analyzePackageJson":"PJ","getOutdatedPatterns":"OP","extractSignatures":"eS","buildSignature":"bS","hashBodyStructure":"BS","calculateSimilarity":"cS","getSimilarFunctions":"SF","findCtxMdFiles":"CMF","parseAnnotations":"pA","groupByName":"BN","getAllFeatures":"AF","getPendingTests":"PT1","markTestPassed":"TP","markTestFailed":"TF","updateTestState":"TS","getTestSummary":"TS1","resetTestState":"TS2","detectTsc":"dT","parseDiagnosticLine":"DL","buildArgs":"bA","checkTypes":"cT","extractComments":"eC","checkMissing":"cM","checkUndocumentedFile":"UF","getUndocumented":"gU","getUndocumentedSummary":"US","getArg":"gA","getPath":"gP","printHelp":"pH","runCLI":"CLI","estimateTokens":"eT","getAiContext":"AC","walkJSFiles":"JSF1","addTopLevelNewlines":"TLN","resolveCtxPath":"CP1","compactFile":"cF","beautifyFile":"bF","compactProject":"cP","expandProject":"eP","extractLegend":"eL","compressFile":"cF1","editCompressed":"eC1","findSymbolRange":"SR","parseCtxFile":"CF1","buildJSDocBlock":"JSD8","findCtxFile":"CF2","findExportStart":"ES","injectJSDoc":"JSD9","stripJSDoc":"JSD10","splitTopLevelParams":"TLP","validateCtxContracts":"CC","generateDocDialect":"DD","walkCtxFiles":"CF3","resolveCtxMdPath":"CMP","readContextDocs":"CD","getProjectDocs":"PD","computeSignature":"cS1","parseCtxDescriptions":"CD1","checkStaleness":"cS2","buildFileTemplate":"FT","generateContextFiles":"CF4","processFileCtx":"FC","parseCtxSignatures":"CS","parseCtxParams":"CP2","extractReturnType":"RT","sanitizeJSDocText":"JSD11","parseCtxVars":"CV1","parseCtxNames":"CN","collectLocals":"cL","collectLocalDecls":"LD","restoreNames":"rN","expandFile":"eF","resolveCtx":"rC1","fetchReference":"fR","listAvailable":"lA","getFrameworkReference":"FR","getInstructions":"gI","getConfig":"gC1","setConfig":"sC","getModeDescription":"MD","getModeWorkflow":"MW","validatePipeline":"vP","emitToolCall":"TC","emitToolResult":"TR","onToolCall":"TC1","onToolResult":"TR1","removeToolListener":"TL","getFilters":"gF","setFilters":"sF","addExcludes":"aE","removeExcludes":"rE","resetFilters":"rF","parseGitignore":"pG1","shouldExcludeDir":"ED","shouldExcludeFile":"EF","matchWildcard":"mW","matchGitignorePattern":"GP","minifyLegend":"mL","createShortName":"SN","buildGraph":"bG","createSkeleton":"cS3","parseFile":"pF","extractCallsAndSQL":"CAS","getTagName":"TN","getCallMethodName":"CMN","extractStringValue":"SV","templateToString":"TS3","discoverSubProjects":"SP","parseProject":"pP","parseFileByExtension":"FBE","isSourceFile":"SF1","findAllProjectFiles":"APF","buildJSDocTypeMap":"JSD12","findJSDocForNode":"JSD13","enrichParamsWithTypes":"PWT","setRoots":"sR","getWorkspaceRoot":"WR","resolvePath":"rP","parseGo":"pG2","extractImports":"eI","getBody":"gB","extractCalls":"eC2","parsePython":"pP1","isSQLString":"SQL","isValidTableName":"VTN","extractSQLFromString":"SQL1","parseSQL":"SQL2","parseColumns":"pC","splitByTopLevelComma":"BTL","extractSQLFromCode":"SQL3","extractORMFromCode":"ORM","parseTypeScript":"TS4","extractParams":"eP1","stripStringsAndComments":"SAC","createServer":"cS4","startStdioServer":"SS","saveDiskCache":"DC1","loadDiskCache":"DC2","getGraph":"gG","detectChanges":"dC","snapshotMtimes":"sM","getSkeleton":"gS","getFocusZone":"FZ","expand":"ex","deps":"de","usages":"us","extractMethod":"eM","getCallChain":"CC1","invalidateCache":"iC","getPortFilePath":"PFP","readPortFile":"PF","writePortFile":"PF1","removePortFile":"PF2","listBackends":"lB","ensureBackend":"eB","encodeClientFrame":"CF5","decodeFrame":"dF","startStdioProxy":"SP1","cleanup":"cl","readRegistry":"rR","writeRegistry":"wR","registerService":"rS","resolveBackend":"rB","readGatewayPid":"GP1","isGatewayRunning":"GR","getGatewayPort":"GP2","startListening":"sL","ensureGateway":"eG","stopGateway":"sG","registerLocal":"rL","registerDnsSd":"DS","tryAvahi":"tA","registerMcast":"rM","serveStatic":"sS","computeWSAccept":"WSA","encodeWSFrame":"WSF","decodeWSFrame":"WSF1","broadcastRPC":"RPC","patchState":"pS","ensureSkeleton":"eS1","hasActiveClients":"AC1","resetShutdownTimer":"ST","startShutdownTimer":"ST1","touchActivity":"tA1","handleAPI":"API","startWebServer":"WS"},"reverseLegend":{"CH":"computeContentHash","CP":"getCachePath","rC":"readCache","wC":"writeCache","CV":"isCacheValid","JSF":"findJSFiles","cC":"calculateComplexity","gR":"getRating","CF":"analyzeComplexityFile","aF":"analyzeFile","gC":"getComplexity","pG":"parseGraphignore","iG":"isGraphignored","RS":"loadRuleSets","RS1":"saveRuleSet","fF":"findFiles","iE":"isExcluded","ISO":"isInStringOrComment","WC":"isWithinContext","FAR":"checkFileAgainstRule","CR":"getCustomRules","CR1":"setCustomRule","CR2":"deleteCustomRule","PRS":"detectProjectRuleSets","CR3":"checkCustomRules","DBS":"getDBSchema","TU":"getTableUsage","DBD":"getDBDeadTables","RC":"collectReferencedColumns","PR":"findProjectRoot","FL":"analyzeFileLocals","DC":"getDeadCode","HS":"calculateHealthScore","CA":"runCacheableAnalyses","aC":"aggregateComplexity","aU":"aggregateUndocumented","JSD":"aggregateJSDoc","FA":"getFullAnalysis","ASO":"getAnalysisSummaryOnly","JSD1":"extractJSDocComments","JSD2":"findJSDocBefore","PN":"extractParamName","TFD":"inferTypeFromDefault","RV":"hasReturnValue","vF":"validateFunction","JSD3":"checkJSDocFile","JSD4":"checkJSDocConsistency","JSD5":"generateJSDoc","JSD6":"buildJSDoc","PT":"inferParamType","JSD7":"generateJSDocFor","LF":"getLargeFiles","FP":"analyzeFilePatterns","PJ":"analyzePackageJson","OP":"getOutdatedPatterns","eS":"extractSignatures","bS":"buildSignature","BS":"hashBodyStructure","cS":"calculateSimilarity","SF":"getSimilarFunctions","CMF":"findCtxMdFiles","pA":"parseAnnotations","BN":"groupByName","AF":"getAllFeatures","PT1":"getPendingTests","TP":"markTestPassed","TF":"markTestFailed","TS":"updateTestState","TS1":"getTestSummary","TS2":"resetTestState","dT":"detectTsc","DL":"parseDiagnosticLine","bA":"buildArgs","cT":"checkTypes","eC":"extractComments","cM":"checkMissing","UF":"checkUndocumentedFile","gU":"getUndocumented","US":"getUndocumentedSummary","gA":"getArg","gP":"getPath","pH":"printHelp","CLI":"runCLI","eT":"estimateTokens","AC":"getAiContext","JSF1":"walkJSFiles","TLN":"addTopLevelNewlines","CP1":"resolveCtxPath","cF":"compactFile","bF":"beautifyFile","cP":"compactProject","eP":"expandProject","eL":"extractLegend","cF1":"compressFile","eC1":"editCompressed","SR":"findSymbolRange","CF1":"parseCtxFile","JSD8":"buildJSDocBlock","CF2":"findCtxFile","ES":"findExportStart","JSD9":"injectJSDoc","JSD10":"stripJSDoc","TLP":"splitTopLevelParams","CC":"validateCtxContracts","DD":"generateDocDialect","CF3":"walkCtxFiles","CMP":"resolveCtxMdPath","CD":"readContextDocs","PD":"getProjectDocs","cS1":"computeSignature","CD1":"parseCtxDescriptions","cS2":"checkStaleness","FT":"buildFileTemplate","CF4":"generateContextFiles","FC":"processFileCtx","CS":"parseCtxSignatures","CP2":"parseCtxParams","RT":"extractReturnType","JSD11":"sanitizeJSDocText","CV1":"parseCtxVars","CN":"parseCtxNames","cL":"collectLocals","LD":"collectLocalDecls","rN":"restoreNames","eF":"expandFile","rC1":"resolveCtx","fR":"fetchReference","lA":"listAvailable","FR":"getFrameworkReference","gI":"getInstructions","gC1":"getConfig","sC":"setConfig","MD":"getModeDescription","MW":"getModeWorkflow","vP":"validatePipeline","TC":"emitToolCall","TR":"emitToolResult","TC1":"onToolCall","TR1":"onToolResult","TL":"removeToolListener","gF":"getFilters","sF":"setFilters","aE":"addExcludes","rE":"removeExcludes","rF":"resetFilters","pG1":"parseGitignore","ED":"shouldExcludeDir","EF":"shouldExcludeFile","mW":"matchWildcard","GP":"matchGitignorePattern","mL":"minifyLegend","SN":"createShortName","bG":"buildGraph","cS3":"createSkeleton","pF":"parseFile","CAS":"extractCallsAndSQL","TN":"getTagName","CMN":"getCallMethodName","SV":"extractStringValue","TS3":"templateToString","SP":"discoverSubProjects","pP":"parseProject","FBE":"parseFileByExtension","SF1":"isSourceFile","APF":"findAllProjectFiles","JSD12":"buildJSDocTypeMap","JSD13":"findJSDocForNode","PWT":"enrichParamsWithTypes","sR":"setRoots","WR":"getWorkspaceRoot","rP":"resolvePath","pG2":"parseGo","eI":"extractImports","gB":"getBody","eC2":"extractCalls","pP1":"parsePython","SQL":"isSQLString","VTN":"isValidTableName","SQL1":"extractSQLFromString","SQL2":"parseSQL","pC":"parseColumns","BTL":"splitByTopLevelComma","SQL3":"extractSQLFromCode","ORM":"extractORMFromCode","TS4":"parseTypeScript","eP1":"extractParams","SAC":"stripStringsAndComments","cS4":"createServer","SS":"startStdioServer","DC1":"saveDiskCache","DC2":"loadDiskCache","gG":"getGraph","dC":"detectChanges","sM":"snapshotMtimes","gS":"getSkeleton","FZ":"getFocusZone","ex":"expand","de":"deps","us":"usages","eM":"extractMethod","CC1":"getCallChain","iC":"invalidateCache","PFP":"getPortFilePath","PF":"readPortFile","PF1":"writePortFile","PF2":"removePortFile","lB":"listBackends","eB":"ensureBackend","CF5":"encodeClientFrame","dF":"decodeFrame","SP1":"startStdioProxy","cl":"cleanup","rR":"readRegistry","wR":"writeRegistry","rS":"registerService","rB":"resolveBackend","GP1":"readGatewayPid","GR":"isGatewayRunning","GP2":"getGatewayPort","sL":"startListening","eG":"ensureGateway","sG":"stopGateway","rL":"registerLocal","DS":"registerDnsSd","tA":"tryAvahi","rM":"registerMcast","sS":"serveStatic","WSA":"computeWSAccept","WSF":"encodeWSFrame","WSF1":"decodeWSFrame","RPC":"broadcastRPC","pS":"patchState","eS1":"ensureSkeleton","AC1":"hasActiveClients","ST":"resetShutdownTimer","ST1":"startShutdownTimer","tA1":"touchActivity","API":"handleAPI","WS":"startWebServer"},"stats":{"files":45,"classes":0,"functions":260,"tables":0},"nodes":{"CH":{"t":"F","e":true,"f":"analysis/analysis-cache.js"},"CP":{"t":"F","e":true,"f":"analysis/analysis-cache.js"},"rC":{"t":"F","e":true,"f":"analysis/analysis-cache.js"},"wC":{"t":"F","e":true,"f":"analysis/analysis-cache.js"},"CV":{"t":"F","e":true,"f":"analysis/analysis-cache.js"},"JSF":{"t":"F","e":true,"f":"core/parser.js"},"cC":{"t":"F","e":false,"f":"analysis/complexity.js"},"gR":{"t":"F","e":false,"f":"analysis/complexity.js"},"CF":{"t":"F","e":true,"f":"analysis/complexity.js"},"aF":{"t":"F","e":false,"f":"analysis/large-files.js"},"gC":{"t":"F","e":true,"f":"analysis/complexity.js"},"pG":{"t":"F","e":false,"f":"analysis/custom-rules.js"},"iG":{"t":"F","e":false,"f":"analysis/custom-rules.js"},"RS":{"t":"F","e":false,"f":"analysis/custom-rules.js"},"RS1":{"t":"F","e":false,"f":"analysis/custom-rules.js"},"fF":{"t":"F","e":false,"f":"analysis/custom-rules.js"},"iE":{"t":"F","e":false,"f":"analysis/custom-rules.js"},"ISO":{"t":"F","e":false,"f":"analysis/custom-rules.js"},"WC":{"t":"F","e":false,"f":"analysis/custom-rules.js"},"FAR":{"t":"F","e":false,"f":"analysis/custom-rules.js"},"CR":{"t":"F","e":true,"f":"analysis/custom-rules.js"},"CR1":{"t":"F","e":true,"f":"analysis/custom-rules.js"},"CR2":{"t":"F","e":true,"f":"analysis/custom-rules.js"},"PRS":{"t":"F","e":true,"f":"analysis/custom-rules.js"},"CR3":{"t":"F","e":true,"f":"analysis/custom-rules.js"},"DBS":{"t":"F","e":true,"f":"analysis/db-analysis.js"},"TU":{"t":"F","e":true,"f":"analysis/db-analysis.js"},"DBD":{"t":"F","e":true,"f":"analysis/db-analysis.js"},"RC":{"t":"F","e":false,"f":"analysis/db-analysis.js"},"PR":{"t":"F","e":false,"f":"analysis/dead-code.js"},"FL":{"t":"F","e":false,"f":"analysis/dead-code.js"},"DC":{"t":"F","e":true,"f":"analysis/dead-code.js"},"HS":{"t":"F","e":false,"f":"analysis/full-analysis.js"},"CA":{"t":"F","e":false,"f":"analysis/full-analysis.js"},"aC":{"t":"F","e":false,"f":"analysis/full-analysis.js"},"aU":{"t":"F","e":false,"f":"analysis/full-analysis.js"},"JSD":{"t":"F","e":false,"f":"analysis/full-analysis.js"},"FA":{"t":"F","e":true,"f":"analysis/full-analysis.js"},"ASO":{"t":"F","e":true,"f":"analysis/full-analysis.js"},"JSD1":{"t":"F","e":false,"f":"analysis/jsdoc-checker.js"},"JSD2":{"t":"F","e":false,"f":"analysis/undocumented.js"},"PN":{"t":"F","e":false,"f":"analysis/similar-functions.js"},"TFD":{"t":"F","e":false,"f":"analysis/jsdoc-checker.js"},"RV":{"t":"F","e":false,"f":"analysis/jsdoc-checker.js"},"vF":{"t":"F","e":false,"f":"analysis/jsdoc-checker.js"},"JSD3":{"t":"F","e":true,"f":"analysis/jsdoc-checker.js"},"JSD4":{"t":"F","e":true,"f":"analysis/jsdoc-checker.js"},"JSD5":{"t":"F","e":false,"f":"compact/expand.js"},"JSD6":{"t":"F","e":false,"f":"analysis/jsdoc-generator.js"},"PT":{"t":"F","e":false,"f":"analysis/jsdoc-generator.js"},"JSD7":{"t":"F","e":true,"f":"analysis/jsdoc-generator.js"},"LF":{"t":"F","e":true,"f":"analysis/large-files.js"},"FP":{"t":"F","e":false,"f":"analysis/outdated-patterns.js"},"PJ":{"t":"F","e":false,"f":"analysis/outdated-patterns.js"},"OP":{"t":"F","e":true,"f":"analysis/outdated-patterns.js"},"eS":{"t":"F","e":false,"f":"analysis/similar-functions.js"},"bS":{"t":"F","e":false,"f":"analysis/similar-functions.js"},"BS":{"t":"F","e":false,"f":"analysis/similar-functions.js"},"cS":{"t":"F","e":false,"f":"analysis/similar-functions.js"},"SF":{"t":"F","e":true,"f":"analysis/similar-functions.js"},"CMF":{"t":"F","e":false,"f":"analysis/test-annotations.js"},"pA":{"t":"F","e":true,"f":"analysis/test-annotations.js"},"BN":{"t":"F","e":false,"f":"analysis/test-annotations.js"},"AF":{"t":"F","e":true,"f":"analysis/test-annotations.js"},"PT1":{"t":"F","e":true,"f":"analysis/test-annotations.js"},"TP":{"t":"F","e":true,"f":"analysis/test-annotations.js"},"TF":{"t":"F","e":true,"f":"analysis/test-annotations.js"},"TS":{"t":"F","e":false,"f":"analysis/test-annotations.js"},"TS1":{"t":"F","e":true,"f":"analysis/test-annotations.js"},"TS2":{"t":"F","e":true,"f":"analysis/test-annotations.js"},"dT":{"t":"F","e":false,"f":"analysis/type-checker.js"},"DL":{"t":"F","e":false,"f":"analysis/type-checker.js"},"bA":{"t":"F","e":false,"f":"analysis/type-checker.js"},"cT":{"t":"F","e":true,"f":"analysis/type-checker.js"},"eC":{"t":"F","e":false,"f":"analysis/undocumented.js"},"cM":{"t":"F","e":false,"f":"analysis/undocumented.js"},"UF":{"t":"F","e":true,"f":"analysis/undocumented.js"},"gU":{"t":"F","e":true,"f":"analysis/undocumented.js"},"US":{"t":"F","e":true,"f":"analysis/undocumented.js"},"gA":{"t":"F","e":false,"f":"cli/cli-handlers.js"},"gP":{"t":"F","e":false,"f":"cli/cli-handlers.js"},"pH":{"t":"F","e":true,"f":"cli/cli.js"},"CLI":{"t":"F","e":true,"f":"cli/cli.js"},"eT":{"t":"F","e":false,"f":"compact/validate-pipeline.js"},"AC":{"t":"F","e":true,"f":"compact/ai-context.js"},"JSF1":{"t":"F","e":false,"f":"compact/validate-pipeline.js"},"TLN":{"t":"F","e":false,"f":"compact/compact.js"},"CP1":{"t":"F","e":false,"f":"compact/doc-dialect.js"},"cF":{"t":"F","e":false,"f":"compact/compact.js"},"bF":{"t":"F","e":false,"f":"compact/compact.js"},"cP":{"t":"F","e":true,"f":"compact/compact.js"},"eP":{"t":"F","e":true,"f":"compact/expand.js"},"eL":{"t":"F","e":false,"f":"compact/compress.js"},"cF1":{"t":"F","e":true,"f":"compact/compress.js"},"eC1":{"t":"F","e":true,"f":"compact/compress.js"},"SR":{"t":"F","e":false,"f":"compact/compress.js"},"CF1":{"t":"F","e":true,"f":"compact/ctx-to-jsdoc.js"},"JSD8":{"t":"F","e":false,"f":"compact/ctx-to-jsdoc.js"},"CF2":{"t":"F","e":false,"f":"compact/ctx-to-jsdoc.js"},"ES":{"t":"F","e":false,"f":"compact/ctx-to-jsdoc.js"},"JSD9":{"t":"F","e":true,"f":"compact/ctx-to-jsdoc.js"},"JSD10":{"t":"F","e":true,"f":"compact/ctx-to-jsdoc.js"},"TLP":{"t":"F","e":false,"f":"compact/ctx-to-jsdoc.js"},"CC":{"t":"F","e":true,"f":"compact/ctx-to-jsdoc.js"},"DD":{"t":"F","e":true,"f":"compact/doc-dialect.js"},"CF3":{"t":"F","e":false,"f":"compact/doc-dialect.js"},"CMP":{"t":"F","e":false,"f":"compact/doc-dialect.js"},"CD":{"t":"F","e":true,"f":"compact/doc-dialect.js"},"PD":{"t":"F","e":true,"f":"compact/doc-dialect.js"},"cS1":{"t":"F","e":false,"f":"compact/doc-dialect.js"},"CD1":{"t":"F","e":false,"f":"compact/doc-dialect.js"},"cS2":{"t":"F","e":true,"f":"compact/doc-dialect.js"},"FT":{"t":"F","e":false,"f":"compact/doc-dialect.js"},"CF4":{"t":"F","e":true,"f":"compact/doc-dialect.js"},"FC":{"t":"F","e":false,"f":"compact/doc-dialect.js"},"CS":{"t":"F","e":false,"f":"compact/expand.js"},"CP2":{"t":"F","e":false,"f":"compact/expand.js"},"RT":{"t":"F","e":false,"f":"compact/expand.js"},"JSD11":{"t":"F","e":false,"f":"compact/expand.js"},"CV1":{"t":"F","e":false,"f":"compact/expand.js"},"CN":{"t":"F","e":false,"f":"compact/expand.js"},"cL":{"t":"F","e":false,"f":"compact/expand.js"},"LD":{"t":"F","e":false,"f":"compact/expand.js"},"rN":{"t":"F","e":false,"f":"compact/expand.js"},"eF":{"t":"F","e":true,"f":"compact/expand.js"},"rC1":{"t":"F","e":false,"f":"compact/expand.js"},"fR":{"t":"F","e":false,"f":"compact/framework-references.js"},"lA":{"t":"F","e":false,"f":"compact/framework-references.js"},"FR":{"t":"F","e":true,"f":"compact/framework-references.js"},"gI":{"t":"F","e":true,"f":"compact/instructions.js"},"gC1":{"t":"F","e":true,"f":"compact/mode-config.js"},"sC":{"t":"F","e":true,"f":"compact/mode-config.js"},"MD":{"t":"F","e":true,"f":"compact/mode-config.js"},"MW":{"t":"F","e":true,"f":"compact/mode-config.js"},"vP":{"t":"F","e":true,"f":"compact/validate-pipeline.js"},"TC":{"t":"F","e":true,"f":"core/event-bus.js"},"TR":{"t":"F","e":true,"f":"core/event-bus.js"},"TC1":{"t":"F","e":true,"f":"core/event-bus.js"},"TR1":{"t":"F","e":true,"f":"core/event-bus.js"},"TL":{"t":"F","e":true,"f":"core/event-bus.js"},"gF":{"t":"F","e":true,"f":"core/filters.js"},"sF":{"t":"F","e":true,"f":"core/filters.js"},"aE":{"t":"F","e":true,"f":"core/filters.js"},"rE":{"t":"F","e":true,"f":"core/filters.js"},"rF":{"t":"F","e":true,"f":"core/filters.js"},"pG1":{"t":"F","e":true,"f":"core/filters.js"},"ED":{"t":"F","e":true,"f":"core/filters.js"},"EF":{"t":"F","e":true,"f":"core/filters.js"},"mW":{"t":"F","e":false,"f":"core/filters.js"},"GP":{"t":"F","e":false,"f":"core/filters.js"},"mL":{"t":"F","e":true,"f":"core/graph-builder.js"},"SN":{"t":"F","e":false,"f":"core/graph-builder.js"},"bG":{"t":"F","e":true,"f":"core/graph-builder.js"},"cS3":{"t":"F","e":true,"f":"core/graph-builder.js"},"pF":{"t":"F","e":true,"f":"core/parser.js"},"CAS":{"t":"F","e":false,"f":"core/parser.js"},"TN":{"t":"F","e":false,"f":"core/parser.js"},"CMN":{"t":"F","e":false,"f":"core/parser.js"},"SV":{"t":"F","e":false,"f":"core/parser.js"},"TS3":{"t":"F","e":false,"f":"core/parser.js"},"SP":{"t":"F","e":true,"f":"core/parser.js"},"pP":{"t":"F","e":true,"f":"core/parser.js"},"FBE":{"t":"F","e":false,"f":"core/parser.js"},"SF1":{"t":"F","e":false,"f":"core/parser.js"},"APF":{"t":"F","e":true,"f":"core/parser.js"},"JSD12":{"t":"F","e":false,"f":"core/parser.js"},"JSD13":{"t":"F","e":false,"f":"core/parser.js"},"PWT":{"t":"F","e":false,"f":"core/parser.js"},"sR":{"t":"F","e":true,"f":"core/workspace.js"},"WR":{"t":"F","e":true,"f":"core/workspace.js"},"rP":{"t":"F","e":true,"f":"core/workspace.js"},"pG2":{"t":"F","e":true,"f":"lang/lang-go.js"},"eI":{"t":"F","e":false,"f":"lang/lang-go.js"},"gB":{"t":"F","e":false,"f":"lang/lang-go.js"},"eC2":{"t":"F","e":false,"f":"lang/lang-go.js"},"pP1":{"t":"F","e":true,"f":"lang/lang-python.js"},"SQL":{"t":"F","e":true,"f":"lang/lang-sql.js"},"VTN":{"t":"F","e":false,"f":"lang/lang-sql.js"},"SQL1":{"t":"F","e":true,"f":"lang/lang-sql.js"},"SQL2":{"t":"F","e":true,"f":"lang/lang-sql.js"},"pC":{"t":"F","e":false,"f":"lang/lang-sql.js"},"BTL":{"t":"F","e":false,"f":"lang/lang-sql.js"},"SQL3":{"t":"F","e":true,"f":"lang/lang-sql.js"},"ORM":{"t":"F","e":true,"f":"lang/lang-sql.js"},"TS4":{"t":"F","e":true,"f":"lang/lang-typescript.js"},"eP1":{"t":"F","e":false,"f":"lang/lang-typescript.js"},"SAC":{"t":"F","e":true,"f":"lang/lang-utils.js"},"cS4":{"t":"F","e":true,"f":"mcp/mcp-server.js"},"SS":{"t":"F","e":true,"f":"mcp/mcp-server.js"},"DC1":{"t":"F","e":false,"f":"mcp/tools.js"},"DC2":{"t":"F","e":false,"f":"mcp/tools.js"},"gG":{"t":"F","e":true,"f":"mcp/tools.js"},"dC":{"t":"F","e":false,"f":"mcp/tools.js"},"sM":{"t":"F","e":false,"f":"mcp/tools.js"},"gS":{"t":"F","e":true,"f":"mcp/tools.js"},"FZ":{"t":"F","e":true,"f":"mcp/tools.js"},"ex":{"t":"F","e":true,"f":"mcp/tools.js"},"de":{"t":"F","e":true,"f":"mcp/tools.js"},"us":{"t":"F","e":true,"f":"mcp/tools.js"},"eM":{"t":"F","e":false,"f":"mcp/tools.js"},"CC1":{"t":"F","e":true,"f":"mcp/tools.js"},"iC":{"t":"F","e":true,"f":"mcp/tools.js"},"PFP":{"t":"F","e":false,"f":"network/backend-lifecycle.js"},"PF":{"t":"F","e":false,"f":"network/backend-lifecycle.js"},"PF1":{"t":"F","e":true,"f":"network/backend-lifecycle.js"},"PF2":{"t":"F","e":true,"f":"network/backend-lifecycle.js"},"lB":{"t":"F","e":true,"f":"network/backend-lifecycle.js"},"eB":{"t":"F","e":true,"f":"network/backend-lifecycle.js"},"CF5":{"t":"F","e":false,"f":"network/backend-lifecycle.js"},"dF":{"t":"F","e":false,"f":"network/backend-lifecycle.js"},"SP1":{"t":"F","e":true,"f":"network/backend-lifecycle.js"},"cl":{"t":"F","e":false,"f":"network/backend.js"},"rR":{"t":"F","e":false,"f":"network/local-gateway.js"},"wR":{"t":"F","e":false,"f":"network/local-gateway.js"},"rS":{"t":"F","e":true,"f":"network/local-gateway.js"},"rB":{"t":"F","e":false,"f":"network/local-gateway.js"},"GP1":{"t":"F","e":false,"f":"network/local-gateway.js"},"GR":{"t":"F","e":false,"f":"network/local-gateway.js"},"GP2":{"t":"F","e":true,"f":"network/local-gateway.js"},"sL":{"t":"F","e":false,"f":"network/local-gateway.js"},"eG":{"t":"F","e":false,"f":"network/local-gateway.js"},"sG":{"t":"F","e":false,"f":"network/local-gateway.js"},"rL":{"t":"F","e":true,"f":"network/mdns.js"},"DS":{"t":"F","e":false,"f":"network/mdns.js"},"tA":{"t":"F","e":false,"f":"network/mdns.js"},"rM":{"t":"F","e":false,"f":"network/mdns.js"},"sS":{"t":"F","e":false,"f":"network/web-server.js"},"WSA":{"t":"F","e":false,"f":"network/web-server.js"},"WSF":{"t":"F","e":false,"f":"network/web-server.js"},"WSF1":{"t":"F","e":false,"f":"network/web-server.js"},"RPC":{"t":"F","e":false,"f":"network/web-server.js"},"pS":{"t":"F","e":false,"f":"network/web-server.js"},"eS1":{"t":"F","e":false,"f":"network/web-server.js"},"AC1":{"t":"F","e":false,"f":"network/web-server.js"},"ST":{"t":"F","e":false,"f":"network/web-server.js"},"ST1":{"t":"F","e":false,"f":"network/web-server.js"},"tA1":{"t":"F","e":false,"f":"network/web-server.js"},"API":{"t":"F","e":false,"f":"network/web-server.js"},"WS":{"t":"F","e":true,"f":"network/web-server.js"}},"edges":[],"orphans":["calculateComplexity","getRating","analyzeFile","parseGraphignore","isGraphignored","loadRuleSets","saveRuleSet","findFiles","isExcluded","isInStringOrComment","isWithinContext","checkFileAgainstRule","collectReferencedColumns","findProjectRoot","analyzeFileLocals","calculateHealthScore","runCacheableAnalyses","aggregateComplexity","aggregateUndocumented","aggregateJSDoc","extractJSDocComments","findJSDocBefore","extractParamName","inferTypeFromDefault","hasReturnValue","validateFunction","generateJSDoc","buildJSDoc","inferParamType","analyzeFilePatterns","analyzePackageJson","extractSignatures","buildSignature","hashBodyStructure","calculateSimilarity","findCtxMdFiles","groupByName","updateTestState","detectTsc","parseDiagnosticLine","buildArgs","extractComments","checkMissing","getArg","getPath","estimateTokens","walkJSFiles","addTopLevelNewlines","resolveCtxPath","compactFile","beautifyFile","extractLegend","findSymbolRange","buildJSDocBlock","findCtxFile","findExportStart","splitTopLevelParams","walkCtxFiles","resolveCtxMdPath","computeSignature","parseCtxDescriptions","buildFileTemplate","processFileCtx","parseCtxSignatures","parseCtxParams","extractReturnType","sanitizeJSDocText","parseCtxVars","parseCtxNames","collectLocals","collectLocalDecls","restoreNames","resolveCtx","fetchReference","listAvailable","matchWildcard","matchGitignorePattern","createShortName","extractCallsAndSQL","getTagName","getCallMethodName","extractStringValue","templateToString","parseFileByExtension","isSourceFile","buildJSDocTypeMap","findJSDocForNode","enrichParamsWithTypes","extractImports","getBody","extractCalls","isValidTableName","parseColumns","splitByTopLevelComma","extractParams","saveDiskCache","loadDiskCache","detectChanges","snapshotMtimes","extractMethod","getPortFilePath","readPortFile","encodeClientFrame","decodeFrame","cleanup","readRegistry","writeRegistry","resolveBackend","readGatewayPid","isGatewayRunning","startListening","ensureGateway","stopGateway","registerDnsSd","tryAvahi","registerMcast","serveStatic","computeWSAccept","encodeWSFrame","decodeWSFrame","broadcastRPC","patchState","ensureSkeleton","hasActiveClients","resetShutdownTimer","startShutdownTimer","touchActivity","handleAPI"],"duplicates":{},"files":["analysis/analysis-cache.js","analysis/complexity.js","analysis/custom-rules.js","analysis/db-analysis.js","analysis/dead-code.js","analysis/full-analysis.js","analysis/jsdoc-checker.js","analysis/jsdoc-generator.js","analysis/large-files.js","analysis/outdated-patterns.js","analysis/similar-functions.js","analysis/test-annotations.js","analysis/type-checker.js","analysis/undocumented.js","cli/cli-handlers.js","cli/cli.js","compact/ai-context.js","compact/compact.js","compact/compress.js","compact/ctx-to-jsdoc.js","compact/doc-dialect.js","compact/expand.js","compact/framework-references.js","compact/instructions.js","compact/mode-config.js","compact/validate-pipeline.js","core/event-bus.js","core/filters.js","core/graph-builder.js","core/parser.js","core/workspace.js","lang/lang-go.js","lang/lang-python.js","lang/lang-sql.js","lang/lang-typescript.js","lang/lang-utils.js","mcp/mcp-server.js","mcp/tool-defs.js","mcp/tools.js","network/backend-lifecycle.js","network/backend.js","network/local-gateway.js","network/mdns.js","network/server.js","network/web-server.js"]}}
|
|
1
|
+
{"version":1,"path":"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src","mtimes":{"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/analysis-cache.js":1775932068076.741,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/complexity.js":1775932068098.837,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/custom-rules.js":1775932068138.1648,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/db-analysis.js":1775932068151.1123,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/dead-code.js":1775932068179.2783,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/full-analysis.js":1775932068199.422,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/jsdoc-checker.js":1775932068214.1042,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/jsdoc-generator.js":1775932068226.255,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/large-files.js":1775932068231.2554,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/outdated-patterns.js":1775932068241.3853,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/similar-functions.js":1775932068258.163,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/test-annotations.js":1775932068268.5154,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/type-checker.js":1775932068273.1277,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis/undocumented.js":1775932068287.6243,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/cli/cli-handlers.js":1775932068298.3313,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/cli/cli.js":1775932068300.5159,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/ai-context.js":1775932068307.1665,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/compact.js":1775932562256.5852,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/compress.js":1775958722177.8923,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/ctx-to-jsdoc.js":1775932068348.9448,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/doc-dialect.js":1775932068402.0254,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/expand.js":1775932068432.0977,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/framework-references.js":1775932068436.373,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/instructions.js":1775932068437.6816,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/mode-config.js":1775932068441.0076,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/validate-pipeline.js":1775932068445.2222,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/core/event-bus.js":1775932068446.521,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/core/filters.js":1775932068453.1003,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/core/graph-builder.js":1775932068467.494,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/core/parser.js":1775932068524.0032,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/core/workspace.js":1775932068530.74,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/lang/lang-go.js":1775932068546.679,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/lang/lang-python.js":1775932068554.9434,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/lang/lang-sql.js":1775932068573.637,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/lang/lang-typescript.js":1775932068582.2983,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/lang/lang-utils.js":1775932068585.4934,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/mcp/mcp-server.js":1775932068611.3706,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/mcp/tool-defs.js":1775932068615.0066,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/mcp/tools.js":1775932068628.6646,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/network/backend-lifecycle.js":1775932068638.9226,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/network/backend.js":1775932249992.6167,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/network/local-gateway.js":1775932068657.378,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/network/mdns.js":1775932068663.7195,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/network/server.js":1775932211325.8235,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/network/web-server.js":1775942632249.3735},"graph":{"v":1,"legend":{"computeContentHash":"CH","getCachePath":"CP","readCache":"rC","writeCache":"wC","isCacheValid":"CV","findJSFiles":"JSF","calculateComplexity":"cC","getRating":"gR","analyzeComplexityFile":"CF","analyzeFile":"aF","getComplexity":"gC","parseGraphignore":"pG","isGraphignored":"iG","loadRuleSets":"RS","saveRuleSet":"RS1","findFiles":"fF","isExcluded":"iE","isInStringOrComment":"ISO","isWithinContext":"WC","checkFileAgainstRule":"FAR","getCustomRules":"CR","setCustomRule":"CR1","deleteCustomRule":"CR2","detectProjectRuleSets":"PRS","checkCustomRules":"CR3","getDBSchema":"DBS","getTableUsage":"TU","getDBDeadTables":"DBD","collectReferencedColumns":"RC","findProjectRoot":"PR","analyzeFileLocals":"FL","getDeadCode":"DC","calculateHealthScore":"HS","runCacheableAnalyses":"CA","aggregateComplexity":"aC","aggregateUndocumented":"aU","aggregateJSDoc":"JSD","getFullAnalysis":"FA","getAnalysisSummaryOnly":"ASO","extractJSDocComments":"JSD1","findJSDocBefore":"JSD2","extractParamName":"PN","inferTypeFromDefault":"TFD","hasReturnValue":"RV","validateFunction":"vF","checkJSDocFile":"JSD3","checkJSDocConsistency":"JSD4","generateJSDoc":"JSD5","buildJSDoc":"JSD6","inferParamType":"PT","generateJSDocFor":"JSD7","getLargeFiles":"LF","analyzeFilePatterns":"FP","analyzePackageJson":"PJ","getOutdatedPatterns":"OP","extractSignatures":"eS","buildSignature":"bS","hashBodyStructure":"BS","calculateSimilarity":"cS","getSimilarFunctions":"SF","findCtxMdFiles":"CMF","parseAnnotations":"pA","groupByName":"BN","getAllFeatures":"AF","getPendingTests":"PT1","markTestPassed":"TP","markTestFailed":"TF","updateTestState":"TS","getTestSummary":"TS1","resetTestState":"TS2","detectTsc":"dT","parseDiagnosticLine":"DL","buildArgs":"bA","checkTypes":"cT","extractComments":"eC","checkMissing":"cM","checkUndocumentedFile":"UF","getUndocumented":"gU","getUndocumentedSummary":"US","getArg":"gA","getPath":"gP","printHelp":"pH","runCLI":"CLI","estimateTokens":"eT","getAiContext":"AC","walkJSFiles":"JSF1","addTopLevelNewlines":"TLN","resolveCtxPath":"CP1","compactFile":"cF","beautifyFile":"bF","compactProject":"cP","expandProject":"eP","extractLegend":"eL","compressFile":"cF1","editCompressed":"eC1","findSymbolRange":"SR","parseCtxFile":"CF1","buildJSDocBlock":"JSD8","findCtxFile":"CF2","findExportStart":"ES","injectJSDoc":"JSD9","stripJSDoc":"JSD10","splitTopLevelParams":"TLP","validateCtxContracts":"CC","generateDocDialect":"DD","walkCtxFiles":"CF3","resolveCtxMdPath":"CMP","readContextDocs":"CD","getProjectDocs":"PD","computeSignature":"cS1","parseCtxDescriptions":"CD1","checkStaleness":"cS2","buildFileTemplate":"FT","generateContextFiles":"CF4","processFileCtx":"FC","parseCtxSignatures":"CS","parseCtxParams":"CP2","extractReturnType":"RT","sanitizeJSDocText":"JSD11","parseCtxVars":"CV1","parseCtxNames":"CN","collectLocals":"cL","collectLocalDecls":"LD","restoreNames":"rN","expandFile":"eF","resolveCtx":"rC1","fetchReference":"fR","listAvailable":"lA","getFrameworkReference":"FR","getInstructions":"gI","getConfig":"gC1","setConfig":"sC","getModeDescription":"MD","getModeWorkflow":"MW","validatePipeline":"vP","emitToolCall":"TC","emitToolResult":"TR","onToolCall":"TC1","onToolResult":"TR1","removeToolListener":"TL","getFilters":"gF","setFilters":"sF","addExcludes":"aE","removeExcludes":"rE","resetFilters":"rF","parseGitignore":"pG1","shouldExcludeDir":"ED","shouldExcludeFile":"EF","matchWildcard":"mW","matchGitignorePattern":"GP","minifyLegend":"mL","createShortName":"SN","buildGraph":"bG","createSkeleton":"cS3","parseFile":"pF","extractCallsAndSQL":"CAS","getTagName":"TN","getCallMethodName":"CMN","extractStringValue":"SV","templateToString":"TS3","discoverSubProjects":"SP","parseProject":"pP","parseFileByExtension":"FBE","isSourceFile":"SF1","findAllProjectFiles":"APF","buildJSDocTypeMap":"JSD12","findJSDocForNode":"JSD13","enrichParamsWithTypes":"PWT","setRoots":"sR","getWorkspaceRoot":"WR","resolvePath":"rP","parseGo":"pG2","extractImports":"eI","getBody":"gB","extractCalls":"eC2","parsePython":"pP1","isSQLString":"SQL","isValidTableName":"VTN","extractSQLFromString":"SQL1","parseSQL":"SQL2","parseColumns":"pC","splitByTopLevelComma":"BTL","extractSQLFromCode":"SQL3","extractORMFromCode":"ORM","parseTypeScript":"TS4","extractParams":"eP1","stripStringsAndComments":"SAC","createServer":"cS4","startStdioServer":"SS","saveDiskCache":"DC1","loadDiskCache":"DC2","getGraph":"gG","detectChanges":"dC","snapshotMtimes":"sM","getSkeleton":"gS","getFocusZone":"FZ","expand":"ex","deps":"de","usages":"us","extractMethod":"eM","getCallChain":"CC1","invalidateCache":"iC","getPortFilePath":"PFP","readPortFile":"PF","writePortFile":"PF1","removePortFile":"PF2","listBackends":"lB","ensureBackend":"eB","encodeClientFrame":"CF5","decodeFrame":"dF","startStdioProxy":"SP1","cleanup":"cl","readRegistry":"rR","writeRegistry":"wR","registerService":"rS","resolveBackend":"rB","readGatewayPid":"GP1","isGatewayRunning":"GR","getGatewayPort":"GP2","startListening":"sL","ensureGateway":"eG","stopGateway":"sG","registerLocal":"rL","registerDnsSd":"DS","tryAvahi":"tA","registerMcast":"rM","serveStatic":"sS","computeWSAccept":"WSA","encodeWSFrame":"WSF","decodeWSFrame":"WSF1","broadcastRPC":"RPC","patchState":"pS","ensureSkeleton":"eS1","hasActiveClients":"AC1","resetShutdownTimer":"ST","startShutdownTimer":"ST1","touchActivity":"tA1","handleAPI":"API","startWebServer":"WS"},"reverseLegend":{"CH":"computeContentHash","CP":"getCachePath","rC":"readCache","wC":"writeCache","CV":"isCacheValid","JSF":"findJSFiles","cC":"calculateComplexity","gR":"getRating","CF":"analyzeComplexityFile","aF":"analyzeFile","gC":"getComplexity","pG":"parseGraphignore","iG":"isGraphignored","RS":"loadRuleSets","RS1":"saveRuleSet","fF":"findFiles","iE":"isExcluded","ISO":"isInStringOrComment","WC":"isWithinContext","FAR":"checkFileAgainstRule","CR":"getCustomRules","CR1":"setCustomRule","CR2":"deleteCustomRule","PRS":"detectProjectRuleSets","CR3":"checkCustomRules","DBS":"getDBSchema","TU":"getTableUsage","DBD":"getDBDeadTables","RC":"collectReferencedColumns","PR":"findProjectRoot","FL":"analyzeFileLocals","DC":"getDeadCode","HS":"calculateHealthScore","CA":"runCacheableAnalyses","aC":"aggregateComplexity","aU":"aggregateUndocumented","JSD":"aggregateJSDoc","FA":"getFullAnalysis","ASO":"getAnalysisSummaryOnly","JSD1":"extractJSDocComments","JSD2":"findJSDocBefore","PN":"extractParamName","TFD":"inferTypeFromDefault","RV":"hasReturnValue","vF":"validateFunction","JSD3":"checkJSDocFile","JSD4":"checkJSDocConsistency","JSD5":"generateJSDoc","JSD6":"buildJSDoc","PT":"inferParamType","JSD7":"generateJSDocFor","LF":"getLargeFiles","FP":"analyzeFilePatterns","PJ":"analyzePackageJson","OP":"getOutdatedPatterns","eS":"extractSignatures","bS":"buildSignature","BS":"hashBodyStructure","cS":"calculateSimilarity","SF":"getSimilarFunctions","CMF":"findCtxMdFiles","pA":"parseAnnotations","BN":"groupByName","AF":"getAllFeatures","PT1":"getPendingTests","TP":"markTestPassed","TF":"markTestFailed","TS":"updateTestState","TS1":"getTestSummary","TS2":"resetTestState","dT":"detectTsc","DL":"parseDiagnosticLine","bA":"buildArgs","cT":"checkTypes","eC":"extractComments","cM":"checkMissing","UF":"checkUndocumentedFile","gU":"getUndocumented","US":"getUndocumentedSummary","gA":"getArg","gP":"getPath","pH":"printHelp","CLI":"runCLI","eT":"estimateTokens","AC":"getAiContext","JSF1":"walkJSFiles","TLN":"addTopLevelNewlines","CP1":"resolveCtxPath","cF":"compactFile","bF":"beautifyFile","cP":"compactProject","eP":"expandProject","eL":"extractLegend","cF1":"compressFile","eC1":"editCompressed","SR":"findSymbolRange","CF1":"parseCtxFile","JSD8":"buildJSDocBlock","CF2":"findCtxFile","ES":"findExportStart","JSD9":"injectJSDoc","JSD10":"stripJSDoc","TLP":"splitTopLevelParams","CC":"validateCtxContracts","DD":"generateDocDialect","CF3":"walkCtxFiles","CMP":"resolveCtxMdPath","CD":"readContextDocs","PD":"getProjectDocs","cS1":"computeSignature","CD1":"parseCtxDescriptions","cS2":"checkStaleness","FT":"buildFileTemplate","CF4":"generateContextFiles","FC":"processFileCtx","CS":"parseCtxSignatures","CP2":"parseCtxParams","RT":"extractReturnType","JSD11":"sanitizeJSDocText","CV1":"parseCtxVars","CN":"parseCtxNames","cL":"collectLocals","LD":"collectLocalDecls","rN":"restoreNames","eF":"expandFile","rC1":"resolveCtx","fR":"fetchReference","lA":"listAvailable","FR":"getFrameworkReference","gI":"getInstructions","gC1":"getConfig","sC":"setConfig","MD":"getModeDescription","MW":"getModeWorkflow","vP":"validatePipeline","TC":"emitToolCall","TR":"emitToolResult","TC1":"onToolCall","TR1":"onToolResult","TL":"removeToolListener","gF":"getFilters","sF":"setFilters","aE":"addExcludes","rE":"removeExcludes","rF":"resetFilters","pG1":"parseGitignore","ED":"shouldExcludeDir","EF":"shouldExcludeFile","mW":"matchWildcard","GP":"matchGitignorePattern","mL":"minifyLegend","SN":"createShortName","bG":"buildGraph","cS3":"createSkeleton","pF":"parseFile","CAS":"extractCallsAndSQL","TN":"getTagName","CMN":"getCallMethodName","SV":"extractStringValue","TS3":"templateToString","SP":"discoverSubProjects","pP":"parseProject","FBE":"parseFileByExtension","SF1":"isSourceFile","APF":"findAllProjectFiles","JSD12":"buildJSDocTypeMap","JSD13":"findJSDocForNode","PWT":"enrichParamsWithTypes","sR":"setRoots","WR":"getWorkspaceRoot","rP":"resolvePath","pG2":"parseGo","eI":"extractImports","gB":"getBody","eC2":"extractCalls","pP1":"parsePython","SQL":"isSQLString","VTN":"isValidTableName","SQL1":"extractSQLFromString","SQL2":"parseSQL","pC":"parseColumns","BTL":"splitByTopLevelComma","SQL3":"extractSQLFromCode","ORM":"extractORMFromCode","TS4":"parseTypeScript","eP1":"extractParams","SAC":"stripStringsAndComments","cS4":"createServer","SS":"startStdioServer","DC1":"saveDiskCache","DC2":"loadDiskCache","gG":"getGraph","dC":"detectChanges","sM":"snapshotMtimes","gS":"getSkeleton","FZ":"getFocusZone","ex":"expand","de":"deps","us":"usages","eM":"extractMethod","CC1":"getCallChain","iC":"invalidateCache","PFP":"getPortFilePath","PF":"readPortFile","PF1":"writePortFile","PF2":"removePortFile","lB":"listBackends","eB":"ensureBackend","CF5":"encodeClientFrame","dF":"decodeFrame","SP1":"startStdioProxy","cl":"cleanup","rR":"readRegistry","wR":"writeRegistry","rS":"registerService","rB":"resolveBackend","GP1":"readGatewayPid","GR":"isGatewayRunning","GP2":"getGatewayPort","sL":"startListening","eG":"ensureGateway","sG":"stopGateway","rL":"registerLocal","DS":"registerDnsSd","tA":"tryAvahi","rM":"registerMcast","sS":"serveStatic","WSA":"computeWSAccept","WSF":"encodeWSFrame","WSF1":"decodeWSFrame","RPC":"broadcastRPC","pS":"patchState","eS1":"ensureSkeleton","AC1":"hasActiveClients","ST":"resetShutdownTimer","ST1":"startShutdownTimer","tA1":"touchActivity","API":"handleAPI","WS":"startWebServer"},"stats":{"files":45,"classes":0,"functions":260,"tables":0},"nodes":{"CH":{"t":"F","e":true,"f":"analysis/analysis-cache.js"},"CP":{"t":"F","e":true,"f":"analysis/analysis-cache.js"},"rC":{"t":"F","e":true,"f":"analysis/analysis-cache.js"},"wC":{"t":"F","e":true,"f":"analysis/analysis-cache.js"},"CV":{"t":"F","e":true,"f":"analysis/analysis-cache.js"},"JSF":{"t":"F","e":true,"f":"core/parser.js"},"cC":{"t":"F","e":false,"f":"analysis/complexity.js"},"gR":{"t":"F","e":false,"f":"analysis/complexity.js"},"CF":{"t":"F","e":true,"f":"analysis/complexity.js"},"aF":{"t":"F","e":false,"f":"analysis/large-files.js"},"gC":{"t":"F","e":true,"f":"analysis/complexity.js"},"pG":{"t":"F","e":false,"f":"analysis/custom-rules.js"},"iG":{"t":"F","e":false,"f":"analysis/custom-rules.js"},"RS":{"t":"F","e":false,"f":"analysis/custom-rules.js"},"RS1":{"t":"F","e":false,"f":"analysis/custom-rules.js"},"fF":{"t":"F","e":false,"f":"analysis/custom-rules.js"},"iE":{"t":"F","e":false,"f":"analysis/custom-rules.js"},"ISO":{"t":"F","e":false,"f":"analysis/custom-rules.js"},"WC":{"t":"F","e":false,"f":"analysis/custom-rules.js"},"FAR":{"t":"F","e":false,"f":"analysis/custom-rules.js"},"CR":{"t":"F","e":true,"f":"analysis/custom-rules.js"},"CR1":{"t":"F","e":true,"f":"analysis/custom-rules.js"},"CR2":{"t":"F","e":true,"f":"analysis/custom-rules.js"},"PRS":{"t":"F","e":true,"f":"analysis/custom-rules.js"},"CR3":{"t":"F","e":true,"f":"analysis/custom-rules.js"},"DBS":{"t":"F","e":true,"f":"analysis/db-analysis.js"},"TU":{"t":"F","e":true,"f":"analysis/db-analysis.js"},"DBD":{"t":"F","e":true,"f":"analysis/db-analysis.js"},"RC":{"t":"F","e":false,"f":"analysis/db-analysis.js"},"PR":{"t":"F","e":false,"f":"analysis/dead-code.js"},"FL":{"t":"F","e":false,"f":"analysis/dead-code.js"},"DC":{"t":"F","e":true,"f":"analysis/dead-code.js"},"HS":{"t":"F","e":false,"f":"analysis/full-analysis.js"},"CA":{"t":"F","e":false,"f":"analysis/full-analysis.js"},"aC":{"t":"F","e":false,"f":"analysis/full-analysis.js"},"aU":{"t":"F","e":false,"f":"analysis/full-analysis.js"},"JSD":{"t":"F","e":false,"f":"analysis/full-analysis.js"},"FA":{"t":"F","e":true,"f":"analysis/full-analysis.js"},"ASO":{"t":"F","e":true,"f":"analysis/full-analysis.js"},"JSD1":{"t":"F","e":false,"f":"analysis/jsdoc-checker.js"},"JSD2":{"t":"F","e":false,"f":"analysis/undocumented.js"},"PN":{"t":"F","e":false,"f":"analysis/similar-functions.js"},"TFD":{"t":"F","e":false,"f":"analysis/jsdoc-checker.js"},"RV":{"t":"F","e":false,"f":"analysis/jsdoc-checker.js"},"vF":{"t":"F","e":false,"f":"analysis/jsdoc-checker.js"},"JSD3":{"t":"F","e":true,"f":"analysis/jsdoc-checker.js"},"JSD4":{"t":"F","e":true,"f":"analysis/jsdoc-checker.js"},"JSD5":{"t":"F","e":false,"f":"compact/expand.js"},"JSD6":{"t":"F","e":false,"f":"analysis/jsdoc-generator.js"},"PT":{"t":"F","e":false,"f":"analysis/jsdoc-generator.js"},"JSD7":{"t":"F","e":true,"f":"analysis/jsdoc-generator.js"},"LF":{"t":"F","e":true,"f":"analysis/large-files.js"},"FP":{"t":"F","e":false,"f":"analysis/outdated-patterns.js"},"PJ":{"t":"F","e":false,"f":"analysis/outdated-patterns.js"},"OP":{"t":"F","e":true,"f":"analysis/outdated-patterns.js"},"eS":{"t":"F","e":false,"f":"analysis/similar-functions.js"},"bS":{"t":"F","e":false,"f":"analysis/similar-functions.js"},"BS":{"t":"F","e":false,"f":"analysis/similar-functions.js"},"cS":{"t":"F","e":false,"f":"analysis/similar-functions.js"},"SF":{"t":"F","e":true,"f":"analysis/similar-functions.js"},"CMF":{"t":"F","e":false,"f":"analysis/test-annotations.js"},"pA":{"t":"F","e":true,"f":"analysis/test-annotations.js"},"BN":{"t":"F","e":false,"f":"analysis/test-annotations.js"},"AF":{"t":"F","e":true,"f":"analysis/test-annotations.js"},"PT1":{"t":"F","e":true,"f":"analysis/test-annotations.js"},"TP":{"t":"F","e":true,"f":"analysis/test-annotations.js"},"TF":{"t":"F","e":true,"f":"analysis/test-annotations.js"},"TS":{"t":"F","e":false,"f":"analysis/test-annotations.js"},"TS1":{"t":"F","e":true,"f":"analysis/test-annotations.js"},"TS2":{"t":"F","e":true,"f":"analysis/test-annotations.js"},"dT":{"t":"F","e":false,"f":"analysis/type-checker.js"},"DL":{"t":"F","e":false,"f":"analysis/type-checker.js"},"bA":{"t":"F","e":false,"f":"analysis/type-checker.js"},"cT":{"t":"F","e":true,"f":"analysis/type-checker.js"},"eC":{"t":"F","e":false,"f":"analysis/undocumented.js"},"cM":{"t":"F","e":false,"f":"analysis/undocumented.js"},"UF":{"t":"F","e":true,"f":"analysis/undocumented.js"},"gU":{"t":"F","e":true,"f":"analysis/undocumented.js"},"US":{"t":"F","e":true,"f":"analysis/undocumented.js"},"gA":{"t":"F","e":false,"f":"cli/cli-handlers.js"},"gP":{"t":"F","e":false,"f":"cli/cli-handlers.js"},"pH":{"t":"F","e":true,"f":"cli/cli.js"},"CLI":{"t":"F","e":true,"f":"cli/cli.js"},"eT":{"t":"F","e":false,"f":"compact/validate-pipeline.js"},"AC":{"t":"F","e":true,"f":"compact/ai-context.js"},"JSF1":{"t":"F","e":false,"f":"compact/validate-pipeline.js"},"TLN":{"t":"F","e":false,"f":"compact/compact.js"},"CP1":{"t":"F","e":false,"f":"compact/doc-dialect.js"},"cF":{"t":"F","e":false,"f":"compact/compact.js"},"bF":{"t":"F","e":false,"f":"compact/compact.js"},"cP":{"t":"F","e":true,"f":"compact/compact.js"},"eP":{"t":"F","e":true,"f":"compact/expand.js"},"eL":{"t":"F","e":false,"f":"compact/compress.js"},"cF1":{"t":"F","e":true,"f":"compact/compress.js"},"eC1":{"t":"F","e":true,"f":"compact/compress.js"},"SR":{"t":"F","e":false,"f":"compact/compress.js"},"CF1":{"t":"F","e":true,"f":"compact/ctx-to-jsdoc.js"},"JSD8":{"t":"F","e":false,"f":"compact/ctx-to-jsdoc.js"},"CF2":{"t":"F","e":false,"f":"compact/ctx-to-jsdoc.js"},"ES":{"t":"F","e":false,"f":"compact/ctx-to-jsdoc.js"},"JSD9":{"t":"F","e":true,"f":"compact/ctx-to-jsdoc.js"},"JSD10":{"t":"F","e":true,"f":"compact/ctx-to-jsdoc.js"},"TLP":{"t":"F","e":false,"f":"compact/ctx-to-jsdoc.js"},"CC":{"t":"F","e":true,"f":"compact/ctx-to-jsdoc.js"},"DD":{"t":"F","e":true,"f":"compact/doc-dialect.js"},"CF3":{"t":"F","e":false,"f":"compact/doc-dialect.js"},"CMP":{"t":"F","e":false,"f":"compact/doc-dialect.js"},"CD":{"t":"F","e":true,"f":"compact/doc-dialect.js"},"PD":{"t":"F","e":true,"f":"compact/doc-dialect.js"},"cS1":{"t":"F","e":false,"f":"compact/doc-dialect.js"},"CD1":{"t":"F","e":false,"f":"compact/doc-dialect.js"},"cS2":{"t":"F","e":true,"f":"compact/doc-dialect.js"},"FT":{"t":"F","e":false,"f":"compact/doc-dialect.js"},"CF4":{"t":"F","e":true,"f":"compact/doc-dialect.js"},"FC":{"t":"F","e":false,"f":"compact/doc-dialect.js"},"CS":{"t":"F","e":false,"f":"compact/expand.js"},"CP2":{"t":"F","e":false,"f":"compact/expand.js"},"RT":{"t":"F","e":false,"f":"compact/expand.js"},"JSD11":{"t":"F","e":false,"f":"compact/expand.js"},"CV1":{"t":"F","e":false,"f":"compact/expand.js"},"CN":{"t":"F","e":false,"f":"compact/expand.js"},"cL":{"t":"F","e":false,"f":"compact/expand.js"},"LD":{"t":"F","e":false,"f":"compact/expand.js"},"rN":{"t":"F","e":false,"f":"compact/expand.js"},"eF":{"t":"F","e":true,"f":"compact/expand.js"},"rC1":{"t":"F","e":false,"f":"compact/expand.js"},"fR":{"t":"F","e":false,"f":"compact/framework-references.js"},"lA":{"t":"F","e":false,"f":"compact/framework-references.js"},"FR":{"t":"F","e":true,"f":"compact/framework-references.js"},"gI":{"t":"F","e":true,"f":"compact/instructions.js"},"gC1":{"t":"F","e":true,"f":"compact/mode-config.js"},"sC":{"t":"F","e":true,"f":"compact/mode-config.js"},"MD":{"t":"F","e":true,"f":"compact/mode-config.js"},"MW":{"t":"F","e":true,"f":"compact/mode-config.js"},"vP":{"t":"F","e":true,"f":"compact/validate-pipeline.js"},"TC":{"t":"F","e":true,"f":"core/event-bus.js"},"TR":{"t":"F","e":true,"f":"core/event-bus.js"},"TC1":{"t":"F","e":true,"f":"core/event-bus.js"},"TR1":{"t":"F","e":true,"f":"core/event-bus.js"},"TL":{"t":"F","e":true,"f":"core/event-bus.js"},"gF":{"t":"F","e":true,"f":"core/filters.js"},"sF":{"t":"F","e":true,"f":"core/filters.js"},"aE":{"t":"F","e":true,"f":"core/filters.js"},"rE":{"t":"F","e":true,"f":"core/filters.js"},"rF":{"t":"F","e":true,"f":"core/filters.js"},"pG1":{"t":"F","e":true,"f":"core/filters.js"},"ED":{"t":"F","e":true,"f":"core/filters.js"},"EF":{"t":"F","e":true,"f":"core/filters.js"},"mW":{"t":"F","e":false,"f":"core/filters.js"},"GP":{"t":"F","e":false,"f":"core/filters.js"},"mL":{"t":"F","e":true,"f":"core/graph-builder.js"},"SN":{"t":"F","e":false,"f":"core/graph-builder.js"},"bG":{"t":"F","e":true,"f":"core/graph-builder.js"},"cS3":{"t":"F","e":true,"f":"core/graph-builder.js"},"pF":{"t":"F","e":true,"f":"core/parser.js"},"CAS":{"t":"F","e":false,"f":"core/parser.js"},"TN":{"t":"F","e":false,"f":"core/parser.js"},"CMN":{"t":"F","e":false,"f":"core/parser.js"},"SV":{"t":"F","e":false,"f":"core/parser.js"},"TS3":{"t":"F","e":false,"f":"core/parser.js"},"SP":{"t":"F","e":true,"f":"core/parser.js"},"pP":{"t":"F","e":true,"f":"core/parser.js"},"FBE":{"t":"F","e":false,"f":"core/parser.js"},"SF1":{"t":"F","e":false,"f":"core/parser.js"},"APF":{"t":"F","e":true,"f":"core/parser.js"},"JSD12":{"t":"F","e":false,"f":"core/parser.js"},"JSD13":{"t":"F","e":false,"f":"core/parser.js"},"PWT":{"t":"F","e":false,"f":"core/parser.js"},"sR":{"t":"F","e":true,"f":"core/workspace.js"},"WR":{"t":"F","e":true,"f":"core/workspace.js"},"rP":{"t":"F","e":true,"f":"core/workspace.js"},"pG2":{"t":"F","e":true,"f":"lang/lang-go.js"},"eI":{"t":"F","e":false,"f":"lang/lang-go.js"},"gB":{"t":"F","e":false,"f":"lang/lang-go.js"},"eC2":{"t":"F","e":false,"f":"lang/lang-go.js"},"pP1":{"t":"F","e":true,"f":"lang/lang-python.js"},"SQL":{"t":"F","e":true,"f":"lang/lang-sql.js"},"VTN":{"t":"F","e":false,"f":"lang/lang-sql.js"},"SQL1":{"t":"F","e":true,"f":"lang/lang-sql.js"},"SQL2":{"t":"F","e":true,"f":"lang/lang-sql.js"},"pC":{"t":"F","e":false,"f":"lang/lang-sql.js"},"BTL":{"t":"F","e":false,"f":"lang/lang-sql.js"},"SQL3":{"t":"F","e":true,"f":"lang/lang-sql.js"},"ORM":{"t":"F","e":true,"f":"lang/lang-sql.js"},"TS4":{"t":"F","e":true,"f":"lang/lang-typescript.js"},"eP1":{"t":"F","e":false,"f":"lang/lang-typescript.js"},"SAC":{"t":"F","e":true,"f":"lang/lang-utils.js"},"cS4":{"t":"F","e":true,"f":"mcp/mcp-server.js"},"SS":{"t":"F","e":true,"f":"mcp/mcp-server.js"},"DC1":{"t":"F","e":false,"f":"mcp/tools.js"},"DC2":{"t":"F","e":false,"f":"mcp/tools.js"},"gG":{"t":"F","e":true,"f":"mcp/tools.js"},"dC":{"t":"F","e":false,"f":"mcp/tools.js"},"sM":{"t":"F","e":false,"f":"mcp/tools.js"},"gS":{"t":"F","e":true,"f":"mcp/tools.js"},"FZ":{"t":"F","e":true,"f":"mcp/tools.js"},"ex":{"t":"F","e":true,"f":"mcp/tools.js"},"de":{"t":"F","e":true,"f":"mcp/tools.js"},"us":{"t":"F","e":true,"f":"mcp/tools.js"},"eM":{"t":"F","e":false,"f":"mcp/tools.js"},"CC1":{"t":"F","e":true,"f":"mcp/tools.js"},"iC":{"t":"F","e":true,"f":"mcp/tools.js"},"PFP":{"t":"F","e":false,"f":"network/backend-lifecycle.js"},"PF":{"t":"F","e":false,"f":"network/backend-lifecycle.js"},"PF1":{"t":"F","e":true,"f":"network/backend-lifecycle.js"},"PF2":{"t":"F","e":true,"f":"network/backend-lifecycle.js"},"lB":{"t":"F","e":true,"f":"network/backend-lifecycle.js"},"eB":{"t":"F","e":true,"f":"network/backend-lifecycle.js"},"CF5":{"t":"F","e":false,"f":"network/backend-lifecycle.js"},"dF":{"t":"F","e":false,"f":"network/backend-lifecycle.js"},"SP1":{"t":"F","e":true,"f":"network/backend-lifecycle.js"},"cl":{"t":"F","e":false,"f":"network/backend.js"},"rR":{"t":"F","e":false,"f":"network/local-gateway.js"},"wR":{"t":"F","e":false,"f":"network/local-gateway.js"},"rS":{"t":"F","e":true,"f":"network/local-gateway.js"},"rB":{"t":"F","e":false,"f":"network/local-gateway.js"},"GP1":{"t":"F","e":false,"f":"network/local-gateway.js"},"GR":{"t":"F","e":false,"f":"network/local-gateway.js"},"GP2":{"t":"F","e":true,"f":"network/local-gateway.js"},"sL":{"t":"F","e":false,"f":"network/local-gateway.js"},"eG":{"t":"F","e":false,"f":"network/local-gateway.js"},"sG":{"t":"F","e":false,"f":"network/local-gateway.js"},"rL":{"t":"F","e":true,"f":"network/mdns.js"},"DS":{"t":"F","e":false,"f":"network/mdns.js"},"tA":{"t":"F","e":false,"f":"network/mdns.js"},"rM":{"t":"F","e":false,"f":"network/mdns.js"},"sS":{"t":"F","e":false,"f":"network/web-server.js"},"WSA":{"t":"F","e":false,"f":"network/web-server.js"},"WSF":{"t":"F","e":false,"f":"network/web-server.js"},"WSF1":{"t":"F","e":false,"f":"network/web-server.js"},"RPC":{"t":"F","e":false,"f":"network/web-server.js"},"pS":{"t":"F","e":false,"f":"network/web-server.js"},"eS1":{"t":"F","e":false,"f":"network/web-server.js"},"AC1":{"t":"F","e":false,"f":"network/web-server.js"},"ST":{"t":"F","e":false,"f":"network/web-server.js"},"ST1":{"t":"F","e":false,"f":"network/web-server.js"},"tA1":{"t":"F","e":false,"f":"network/web-server.js"},"API":{"t":"F","e":false,"f":"network/web-server.js"},"WS":{"t":"F","e":true,"f":"network/web-server.js"}},"edges":[],"orphans":["calculateComplexity","getRating","analyzeFile","parseGraphignore","isGraphignored","loadRuleSets","saveRuleSet","findFiles","isExcluded","isInStringOrComment","isWithinContext","checkFileAgainstRule","collectReferencedColumns","findProjectRoot","analyzeFileLocals","calculateHealthScore","runCacheableAnalyses","aggregateComplexity","aggregateUndocumented","aggregateJSDoc","extractJSDocComments","findJSDocBefore","extractParamName","inferTypeFromDefault","hasReturnValue","validateFunction","generateJSDoc","buildJSDoc","inferParamType","analyzeFilePatterns","analyzePackageJson","extractSignatures","buildSignature","hashBodyStructure","calculateSimilarity","findCtxMdFiles","groupByName","updateTestState","detectTsc","parseDiagnosticLine","buildArgs","extractComments","checkMissing","getArg","getPath","estimateTokens","walkJSFiles","addTopLevelNewlines","resolveCtxPath","compactFile","beautifyFile","extractLegend","findSymbolRange","buildJSDocBlock","findCtxFile","findExportStart","splitTopLevelParams","walkCtxFiles","resolveCtxMdPath","computeSignature","parseCtxDescriptions","buildFileTemplate","processFileCtx","parseCtxSignatures","parseCtxParams","extractReturnType","sanitizeJSDocText","parseCtxVars","parseCtxNames","collectLocals","collectLocalDecls","restoreNames","resolveCtx","fetchReference","listAvailable","matchWildcard","matchGitignorePattern","createShortName","extractCallsAndSQL","getTagName","getCallMethodName","extractStringValue","templateToString","parseFileByExtension","isSourceFile","buildJSDocTypeMap","findJSDocForNode","enrichParamsWithTypes","extractImports","getBody","extractCalls","isValidTableName","parseColumns","splitByTopLevelComma","extractParams","saveDiskCache","loadDiskCache","detectChanges","snapshotMtimes","extractMethod","getPortFilePath","readPortFile","encodeClientFrame","decodeFrame","cleanup","readRegistry","writeRegistry","resolveBackend","readGatewayPid","isGatewayRunning","startListening","ensureGateway","stopGateway","registerDnsSd","tryAvahi","registerMcast","serveStatic","computeWSAccept","encodeWSFrame","decodeWSFrame","broadcastRPC","patchState","ensureSkeleton","hasActiveClients","resetShutdownTimer","startShutdownTimer","touchActivity","handleAPI"],"duplicates":{},"files":["analysis/analysis-cache.js","analysis/complexity.js","analysis/custom-rules.js","analysis/db-analysis.js","analysis/dead-code.js","analysis/full-analysis.js","analysis/jsdoc-checker.js","analysis/jsdoc-generator.js","analysis/large-files.js","analysis/outdated-patterns.js","analysis/similar-functions.js","analysis/test-annotations.js","analysis/type-checker.js","analysis/undocumented.js","cli/cli-handlers.js","cli/cli.js","compact/ai-context.js","compact/compact.js","compact/compress.js","compact/ctx-to-jsdoc.js","compact/doc-dialect.js","compact/expand.js","compact/framework-references.js","compact/instructions.js","compact/mode-config.js","compact/validate-pipeline.js","core/event-bus.js","core/filters.js","core/graph-builder.js","core/parser.js","core/workspace.js","lang/lang-go.js","lang/lang-python.js","lang/lang-sql.js","lang/lang-typescript.js","lang/lang-utils.js","mcp/mcp-server.js","mcp/tool-defs.js","mcp/tools.js","network/backend-lifecycle.js","network/backend.js","network/local-gateway.js","network/mdns.js","network/server.js","network/web-server.js"]}}
|
package/src/cli/cli-handlers.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @ctx .context/src/cli/cli-handlers.ctx
|
|
2
|
-
import{getSkeleton as r,expand as e,deps as s,usages as t}from"../mcp/tools.js";import{getPendingTests as a,getTestSummary as n}from"../analysis/test-annotations.js";import{getFilters as o}from"../core/filters.js";import{getInstructions as c}from"../compact/instructions.js";import{getUndocumentedSummary as i}from"../analysis/undocumented.js";import{getDeadCode as d}from"../analysis/dead-code.js";import{generateJSDoc as l}from"../analysis/jsdoc-generator.js";import{getSimilarFunctions as m}from"../analysis/similar-functions.js";import{getComplexity as g}from"../analysis/complexity.js";import{getLargeFiles as u}from"../analysis/large-files.js";import{getOutdatedPatterns as p}from"../analysis/outdated-patterns.js";import{getFullAnalysis as y}from"../analysis/full-analysis.js";import{compressFile as h}from"../compact/compress.js";import{getProjectDocs as f,generateContextFiles as j}from"../compact/doc-dialect.js";import{getGraph as A}from"../mcp/tools.js";import{parseProject as P}from"../core/parser.js";import{resolvePath as q}from"../core/workspace.js";import{checkJSDocConsistency as x}from"../analysis/jsdoc-checker.js";import{checkTypes as E}from"../analysis/type-checker.js";import{compactProject as b,expandProject as w}from"../compact/compact.js";import{injectJSDoc as S,stripJSDoc as U,validateCtxContracts as k}from"../compact/ctx-to-jsdoc.js";import{getConfig as C,setConfig as v,getModeDescription as D,getModeWorkflow as I}from"../compact/mode-config.js";function getArg(r,e){const s=r.find(r=>r.startsWith(`--${e}=`));return s?s.split("=")[1]:void 0}
|
|
2
|
+
import{getSkeleton as r,expand as e,deps as s,usages as t}from"../mcp/tools.js";import{getPendingTests as a,getTestSummary as n}from"../analysis/test-annotations.js";import{getFilters as o}from"../core/filters.js";import{getInstructions as c}from"../compact/instructions.js";import{getUndocumentedSummary as i}from"../analysis/undocumented.js";import{getDeadCode as d}from"../analysis/dead-code.js";import{generateJSDoc as l}from"../analysis/jsdoc-generator.js";import{getSimilarFunctions as m}from"../analysis/similar-functions.js";import{getComplexity as g}from"../analysis/complexity.js";import{getLargeFiles as u}from"../analysis/large-files.js";import{getOutdatedPatterns as p}from"../analysis/outdated-patterns.js";import{getFullAnalysis as y}from"../analysis/full-analysis.js";import{compressFile as h}from"../compact/compress.js";import{getProjectDocs as f,generateContextFiles as j}from"../compact/doc-dialect.js";import{getGraph as A}from"../mcp/tools.js";import{parseProject as P}from"../core/parser.js";import{resolvePath as q}from"../core/workspace.js";import{checkJSDocConsistency as x}from"../analysis/jsdoc-checker.js";import{checkTypes as E}from"../analysis/type-checker.js";import{compactProject as b,expandProject as w}from"../compact/compact.js";import{injectJSDoc as S,stripJSDoc as U,validateCtxContracts as k}from"../compact/ctx-to-jsdoc.js";import{getConfig as C,setConfig as v,getModeDescription as D,getModeWorkflow as I}from"../compact/mode-config.js";import{compactMigrate as M}from"../compact/compact-migrate.js";function getArg(r,e){const s=r.find(r=>r.startsWith(`--${e}=`));return s?s.split("=")[1]:void 0}
|
|
3
3
|
function getPath(r){const e=r.find(r=>!r.startsWith("--"))||".";return q(e)}
|
|
4
|
-
export const CLI_HANDLERS={skeleton:{requiresArg:!0,argError:"Path required: skeleton <path>",handler:async e=>r(q(e[0]))},expand:{requiresArg:!0,argError:"Symbol required: expand <symbol>",handler:async r=>e(r[0])},deps:{requiresArg:!0,argError:"Symbol required: deps <symbol>",handler:async r=>s(r[0])},usages:{requiresArg:!0,argError:"Symbol required: usages <symbol>",handler:async r=>t(r[0])},pending:{handler:async r=>a(getPath(r))},summary:{handler:async r=>n(getPath(r))},filters:{handler:async()=>o()},instructions:{rawOutput:!0,handler:async()=>c()},undocumented:{handler:async r=>{const e=getArg(r,"level")||"tests";return i(getPath(r),e)}},deadcode:{handler:async r=>d(getPath(r))},jsdoc:{requiresArg:!0,argError:"Usage: jsdoc <file>",handler:async r=>l(q(r[0]))},similar:{handler:async r=>{const e=parseInt(getArg(r,"threshold"))||60;return m(getPath(r),{threshold:e})}},complexity:{handler:async r=>{const e=parseInt(getArg(r,"min"))||1,s=r.includes("--problematic");return g(getPath(r),{minComplexity:e,onlyProblematic:s})}},largefiles:{handler:async r=>{const e=r.includes("--problematic");return u(getPath(r),{onlyProblematic:e})}},outdated:{handler:async r=>{const e=r.includes("--code"),s=r.includes("--deps");return p(getPath(r),{codeOnly:e,depsOnly:s})}},analyze:{handler:async r=>{const e=r.includes("--items");return y(getPath(r),{includeItems:e})}},"jsdoc-check":{handler:async r=>x(getPath(r))},types:{handler:async r=>{const e=parseInt(getArg(r,"max"))||50;return E(getPath(r),{maxDiagnostics:e})}},compress:{requiresArg:!0,argError:"Usage: compress <file> [--no-beautify] [--no-legend]",handler:async r=>{const e=!r.includes("--no-beautify"),s=!r.includes("--no-legend");return h(q(r[0]),{beautify:e,legend:s})}},docs:{requiresArg:!0,argError:"Usage: docs <path> [--file=<filename>]",handler:async r=>{const e=q(r[0]),s=await A(e),t=r.find(r=>r.startsWith("--file="))?.split("=")[1];return f(s,e,{file:t})}},"generate-ctx":{requiresArg:!0,argError:"Usage: generate-ctx <path> [--overwrite] [--scope=focus|all]",handler:async r=>{const e=q(r[0]),s=await A(e),t=await P(e),a=r.includes("--overwrite"),n=r.find(r=>r.startsWith("--scope="))?.split("=")[1]||"all";return j(s,e,t,{overwrite:a,scope:n})}},compact:{requiresArg:!0,argError:"Usage: compact <path> [--dry-run]",handler:async r=>{const e=q(r[0]),s=r.includes("--dry-run");return b(e,{dryRun:s})}},beautify:{requiresArg:!0,argError:"Usage: beautify <path> [--dry-run]",handler:async r=>{const e=q(r[0]),s=r.includes("--dry-run");return w(e,{dryRun:s})}},"inject-jsdoc":{requiresArg:!0,argError:"Usage: inject-jsdoc <path> [--dry-run]",handler:async r=>{const e=q(r[0]),s=r.includes("--dry-run");return S(e,{dryRun:s})}},"strip-jsdoc":{requiresArg:!0,argError:"Usage: strip-jsdoc <path> [--dry-run]",handler:async r=>{const e=q(r[0]),s=r.includes("--dry-run");return U(e,{dryRun:s})}},"validate-ctx":{requiresArg:!0,argError:"Usage: validate-ctx <path> [--strict]",handler:async r=>{const e=q(r[0]),s=r.includes("--strict");return k(e,{strict:s})}},mode:{requiresArg:!0,argError:"Usage: mode <path>",handler:async r=>{const e=q(r[0]),s=C(e);return{...s,description:D(s.mode),workflow:I(s.mode)}}},"set-mode":{requiresArg:!0,argError:"Usage: set-mode <path> <1|2
|
|
4
|
+
export const CLI_HANDLERS={config:{rawOutput:!0,handler:async()=>{const{execSync:x}=await import("child_process");let npx;try{npx=x("which npx",{encoding:"utf-8"}).trim()}catch{npx="npx"}const cfg={mcpServers:{"project-graph":{command:npx,args:["-y","project-graph-mcp"]}}};console.log("Add this to your MCP config:\n");return JSON.stringify(cfg,null,2)}},skeleton:{requiresArg:!0,argError:"Path required: skeleton <path>",handler:async e=>r(q(e[0]))},expand:{requiresArg:!0,argError:"Symbol required: expand <symbol>",handler:async r=>e(r[0])},deps:{requiresArg:!0,argError:"Symbol required: deps <symbol>",handler:async r=>s(r[0])},usages:{requiresArg:!0,argError:"Symbol required: usages <symbol>",handler:async r=>t(r[0])},pending:{handler:async r=>a(getPath(r))},summary:{handler:async r=>n(getPath(r))},filters:{handler:async()=>o()},instructions:{rawOutput:!0,handler:async()=>c()},undocumented:{handler:async r=>{const e=getArg(r,"level")||"tests";return i(getPath(r),e)}},deadcode:{handler:async r=>d(getPath(r))},jsdoc:{requiresArg:!0,argError:"Usage: jsdoc <file>",handler:async r=>l(q(r[0]))},similar:{handler:async r=>{const e=parseInt(getArg(r,"threshold"))||60;return m(getPath(r),{threshold:e})}},complexity:{handler:async r=>{const e=parseInt(getArg(r,"min"))||1,s=r.includes("--problematic");return g(getPath(r),{minComplexity:e,onlyProblematic:s})}},largefiles:{handler:async r=>{const e=r.includes("--problematic");return u(getPath(r),{onlyProblematic:e})}},outdated:{handler:async r=>{const e=r.includes("--code"),s=r.includes("--deps");return p(getPath(r),{codeOnly:e,depsOnly:s})}},analyze:{handler:async r=>{const e=r.includes("--items");return y(getPath(r),{includeItems:e})}},"jsdoc-check":{handler:async r=>x(getPath(r))},types:{handler:async r=>{const e=parseInt(getArg(r,"max"))||50;return E(getPath(r),{maxDiagnostics:e})}},compress:{requiresArg:!0,argError:"Usage: compress <file> [--no-beautify] [--no-legend]",handler:async r=>{const e=!r.includes("--no-beautify"),s=!r.includes("--no-legend");return h(q(r[0]),{beautify:e,legend:s})}},docs:{requiresArg:!0,argError:"Usage: docs <path> [--file=<filename>]",handler:async r=>{const e=q(r[0]),s=await A(e),t=r.find(r=>r.startsWith("--file="))?.split("=")[1];return f(s,e,{file:t})}},"generate-ctx":{requiresArg:!0,argError:"Usage: generate-ctx <path> [--overwrite] [--scope=focus|all]",handler:async r=>{const e=q(r[0]),s=await A(e),t=await P(e),a=r.includes("--overwrite"),n=r.find(r=>r.startsWith("--scope="))?.split("=")[1]||"all";return j(s,e,t,{overwrite:a,scope:n})}},compact:{requiresArg:!0,argError:"Usage: compact <path> [--dry-run]",handler:async r=>{const e=q(r[0]),s=r.includes("--dry-run");return b(e,{dryRun:s})}},beautify:{requiresArg:!0,argError:"Usage: beautify <path> [--dry-run]",handler:async r=>{const e=q(r[0]),s=r.includes("--dry-run");return w(e,{dryRun:s})}},"inject-jsdoc":{requiresArg:!0,argError:"Usage: inject-jsdoc <path> [--dry-run]",handler:async r=>{const e=q(r[0]),s=r.includes("--dry-run");return S(e,{dryRun:s})}},"strip-jsdoc":{requiresArg:!0,argError:"Usage: strip-jsdoc <path> [--dry-run]",handler:async r=>{const e=q(r[0]),s=r.includes("--dry-run");return U(e,{dryRun:s})}},"validate-ctx":{requiresArg:!0,argError:"Usage: validate-ctx <path> [--strict]",handler:async r=>{const e=q(r[0]),s=r.includes("--strict");return k(e,{strict:s})}},mode:{requiresArg:!0,argError:"Usage: mode <path>",handler:async r=>{const e=q(r[0]),s=C(e);return{...s,description:D(s.mode),workflow:I(s.mode)}}},"compact-migrate":{requiresArg:!0,argError:"Usage: compact-migrate <path>",handler:async r=>{const e=q(r[0]),s=r.includes("--dry-run");return M(e,{dryRun:s})}},"set-mode":{requiresArg:!0,argError:"Usage: set-mode <path> <1|2>",handler:async r=>{const e=q(r[0]),s=parseInt(r[1],10);if(!s||![1,2].includes(s))throw new Error("Mode must be 1 (compact) or 2 (full)");return v(e,{mode:s})}}};
|
package/src/cli/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @ctx .context/src/cli/cli.ctx
|
|
2
2
|
import{CLI_HANDLERS as e}from"./cli-handlers.js";
|
|
3
|
-
export function printHelp(){console.log("\nproject-graph-mcp - MCP server for AI agents\n\nUsage:\n npx project-graph-mcp Start MCP stdio server\n npx project-graph-mcp <command> [args] Run CLI command\n\nCommands:\n skeleton <path> Get compact project overview\n expand <symbol> Expand minified symbol (e.g., SN, SN.togglePin)\n deps <symbol> Get dependency tree\n usages <symbol> Find all usages\n pending <path> List pending .ctx.md test checklists\n summary <path> Get test progress summary\n undocumented <path> Find missing JSDoc (--level=tests|params|all)\n deadcode <path> Find unused functions/classes\n jsdoc <file> Generate JSDoc for file\n similar <path> Find similar functions (--threshold=60)\n complexity <path> Analyze cyclomatic complexity (--min=1)\n largefiles <path> Find files needing split (--problematic)\n outdated <path> Find legacy patterns & redundant deps\n analyze <path> Run ALL checks with Health Score\n jsdoc-check <path> Validate JSDoc
|
|
3
|
+
export function printHelp(){console.log("\nproject-graph-mcp - MCP server for AI agents\n\nUsage:\n npx project-graph-mcp Start MCP stdio server\n npx project-graph-mcp <command> [args] Run CLI command\n\nCommands:\n config Generate MCP config with correct paths\n skeleton <path> Get compact project overview\n expand <symbol> Expand minified symbol (e.g., SN, SN.togglePin)\n deps <symbol> Get dependency tree\n usages <symbol> Find all usages\n pending <path> List pending .ctx.md test checklists\n summary <path> Get test progress summary\n undocumented <path> Find missing JSDoc (--level=tests|params|all)\n deadcode <path> Find unused functions/classes\n jsdoc <file> Generate JSDoc for file\n similar <path> Find similar functions (--threshold=60)\n complexity <path> Analyze cyclomatic complexity (--min=1)\n largefiles <path> Find files needing split (--problematic)\n outdated <path> Find legacy patterns & redundant deps\n analyze <path> Run ALL checks with Health Score\n jsdoc-check <path> Validate JSDoc vs function signatures\n types <path> Run tsc type checking (--max=50)\n compress <file> Compress JS file for AI (--no-beautify, --no-legend)\n compact <path> Compact all JS files (--dry-run)\n beautify <path> Beautify/expand all JS files (--dry-run)\n inject-jsdoc <path> Generate JSDoc from .ctx files and inject into source\n strip-jsdoc <path> Strip all JSDoc blocks from source files\n docs <path> Get project docs in doc-dialect format (--file=<name>)\n generate-ctx <path> Generate .context/ docs (--overwrite --scope=focus)\n validate-ctx <path> Validate .ctx contracts against source AST (--strict)\n mode <path> Show current compact code mode and workflow\n compact-migrate <path> Migrate formatted source to compact mode (git must be clean)\n set-mode <path> <1|2> Set mode (1=compact*, 2=full)\n serve <path> Start web dashboard (--port=N)\n filters Show current filter configuration\n instructions Show agent guidelines (JSDoc, Arch)\n help Show this help\n\nQuick Start:\n npx project-graph-mcp config # Get MCP config for your IDE\n\nWeb Dashboard:\n npx project-graph-mcp serve . # Start at auto-assigned port\n npx project-graph-mcp serve . --port 3000\n # Then open http://localhost:{port}/ or http://project-graph.local/{name}/\n\nExamples:\n npx project-graph-mcp skeleton src/components\n npx project-graph-mcp expand SN\n npx project-graph-mcp compact src/ --dry-run\n")}
|
|
4
4
|
export async function runCLI(n,t){if(!n||"help"===n||"--help"===n||"-h"===n)return void printHelp();
|
|
5
5
|
const o=e[n];o||(console.error(`Unknown command: ${n}`),console.error('Run with "help" for usage information'),process.exit(1)),o.requiresArg&&!t[0]&&(console.error(o.argError||`Argument required for: ${n}`),process.exit(1));try{const e=await o.handler(t);o.rawOutput?console.log(e):console.log(JSON.stringify(e,null,2))}catch(e){console.error("Error:",e.message),process.exit(1)}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":1,"path":"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact","mtimes":{"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/ai-context.js":1775932068307.1665,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/compact-migrate.js":1776001462202.9746,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/compact.js":1775932562256.5852,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/compress.js":1775958722177.8923,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/ctx-to-jsdoc.js":1775932068348.9448,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/doc-dialect.js":1775932068402.0254,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/expand.js":1775932068432.0977,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/framework-references.js":1775932068436.373,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/instructions.js":1775932068437.6816,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/mode-config.js":1776001388446.0337,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact/validate-pipeline.js":1775932068445.2222},"graph":{"v":1,"legend":{"estimateTokens":"eT","getAiContext":"AC","walkJS":"JS","checkGitClean":"GC","extractNames":"eN","buildNamesDirective":"ND","updateCtxNames":"CN","S":"sS","compactMigrate":"cM","walkJSFiles":"JSF","addTopLevelNewlines":"TLN","resolveCtxPath":"CP","compactFile":"cF","beautifyFile":"bF","compactProject":"cP","expandProject":"eP","extractLegend":"eL","compressFile":"cF1","editCompressed":"eC","findSymbolRange":"SR","parseCtxFile":"CF","buildJSDocBlock":"JSD","findCtxFile":"CF1","findExportStart":"ES","injectJSDoc":"JSD1","stripJSDoc":"JSD2","splitTopLevelParams":"TLP","validateCtxContracts":"CC","generateDocDialect":"DD","walkCtxFiles":"CF2","resolveCtxMdPath":"CMP","readContextDocs":"CD","getProjectDocs":"PD","computeSignature":"cS","parseCtxDescriptions":"CD1","checkStaleness":"cS1","buildFileTemplate":"FT","generateContextFiles":"CF3","processFileCtx":"FC","parseCtxSignatures":"CS","parseCtxParams":"CP1","extractReturnType":"RT","sanitizeJSDocText":"JSD3","generateJSDoc":"JSD4","parseCtxVars":"CV","parseCtxNames":"CN1","collectLocals":"cL","collectLocalDecls":"LD","restoreNames":"rN","expandFile":"eF","resolveCtx":"rC","fetchReference":"fR","listAvailable":"lA","getFrameworkReference":"FR","getInstructions":"gI","getConfig":"gC","setConfig":"sC","getModeDescription":"MD","getModeWorkflow":"MW","validatePipeline":"vP"},"reverseLegend":{"eT":"estimateTokens","AC":"getAiContext","JS":"walkJS","GC":"checkGitClean","eN":"extractNames","ND":"buildNamesDirective","CN":"updateCtxNames","sS":"S","cM":"compactMigrate","JSF":"walkJSFiles","TLN":"addTopLevelNewlines","CP":"resolveCtxPath","cF":"compactFile","bF":"beautifyFile","cP":"compactProject","eP":"expandProject","eL":"extractLegend","cF1":"compressFile","eC":"editCompressed","SR":"findSymbolRange","CF":"parseCtxFile","JSD":"buildJSDocBlock","CF1":"findCtxFile","ES":"findExportStart","JSD1":"injectJSDoc","JSD2":"stripJSDoc","TLP":"splitTopLevelParams","CC":"validateCtxContracts","DD":"generateDocDialect","CF2":"walkCtxFiles","CMP":"resolveCtxMdPath","CD":"readContextDocs","PD":"getProjectDocs","cS":"computeSignature","CD1":"parseCtxDescriptions","cS1":"checkStaleness","FT":"buildFileTemplate","CF3":"generateContextFiles","FC":"processFileCtx","CS":"parseCtxSignatures","CP1":"parseCtxParams","RT":"extractReturnType","JSD3":"sanitizeJSDocText","JSD4":"generateJSDoc","CV":"parseCtxVars","CN1":"parseCtxNames","cL":"collectLocals","LD":"collectLocalDecls","rN":"restoreNames","eF":"expandFile","rC":"resolveCtx","fR":"fetchReference","lA":"listAvailable","FR":"getFrameworkReference","gI":"getInstructions","gC":"getConfig","sC":"setConfig","MD":"getModeDescription","MW":"getModeWorkflow","vP":"validatePipeline"},"stats":{"files":11,"classes":0,"functions":67,"tables":0},"nodes":{"eT":{"t":"F","e":false,"f":"validate-pipeline.js"},"AC":{"t":"F","e":true,"f":"ai-context.js"},"JS":{"t":"F","e":false,"f":"compact-migrate.js"},"GC":{"t":"F","e":false,"f":"compact-migrate.js"},"eN":{"t":"F","e":false,"f":"compact-migrate.js"},"ND":{"t":"F","e":false,"f":"compact-migrate.js"},"CN":{"t":"F","e":false,"f":"compact-migrate.js"},"sS":{"t":"F","e":false,"f":"compact-migrate.js"},"cM":{"t":"F","e":true,"f":"compact-migrate.js"},"JSF":{"t":"F","e":false,"f":"validate-pipeline.js"},"TLN":{"t":"F","e":false,"f":"compact.js"},"CP":{"t":"F","e":false,"f":"doc-dialect.js"},"cF":{"t":"F","e":false,"f":"compact.js"},"bF":{"t":"F","e":false,"f":"compact.js"},"cP":{"t":"F","e":true,"f":"compact.js"},"eP":{"t":"F","e":true,"f":"expand.js"},"eL":{"t":"F","e":false,"f":"compress.js"},"cF1":{"t":"F","e":true,"f":"compress.js"},"eC":{"t":"F","e":true,"f":"compress.js"},"SR":{"t":"F","e":false,"f":"compress.js"},"CF":{"t":"F","e":true,"f":"ctx-to-jsdoc.js"},"JSD":{"t":"F","e":false,"f":"ctx-to-jsdoc.js"},"CF1":{"t":"F","e":false,"f":"ctx-to-jsdoc.js"},"ES":{"t":"F","e":false,"f":"ctx-to-jsdoc.js"},"JSD1":{"t":"F","e":true,"f":"ctx-to-jsdoc.js"},"JSD2":{"t":"F","e":true,"f":"ctx-to-jsdoc.js"},"TLP":{"t":"F","e":false,"f":"ctx-to-jsdoc.js"},"CC":{"t":"F","e":true,"f":"ctx-to-jsdoc.js"},"DD":{"t":"F","e":true,"f":"doc-dialect.js"},"CF2":{"t":"F","e":false,"f":"doc-dialect.js"},"CMP":{"t":"F","e":false,"f":"doc-dialect.js"},"CD":{"t":"F","e":true,"f":"doc-dialect.js"},"PD":{"t":"F","e":true,"f":"doc-dialect.js"},"cS":{"t":"F","e":false,"f":"doc-dialect.js"},"CD1":{"t":"F","e":false,"f":"doc-dialect.js"},"cS1":{"t":"F","e":true,"f":"doc-dialect.js"},"FT":{"t":"F","e":false,"f":"doc-dialect.js"},"CF3":{"t":"F","e":true,"f":"doc-dialect.js"},"FC":{"t":"F","e":false,"f":"doc-dialect.js"},"CS":{"t":"F","e":false,"f":"expand.js"},"CP1":{"t":"F","e":false,"f":"expand.js"},"RT":{"t":"F","e":false,"f":"expand.js"},"JSD3":{"t":"F","e":false,"f":"expand.js"},"JSD4":{"t":"F","e":false,"f":"expand.js"},"CV":{"t":"F","e":false,"f":"expand.js"},"CN1":{"t":"F","e":false,"f":"expand.js"},"cL":{"t":"F","e":false,"f":"expand.js"},"LD":{"t":"F","e":false,"f":"expand.js"},"rN":{"t":"F","e":false,"f":"expand.js"},"eF":{"t":"F","e":true,"f":"expand.js"},"rC":{"t":"F","e":false,"f":"expand.js"},"fR":{"t":"F","e":false,"f":"framework-references.js"},"lA":{"t":"F","e":false,"f":"framework-references.js"},"FR":{"t":"F","e":true,"f":"framework-references.js"},"gI":{"t":"F","e":true,"f":"instructions.js"},"gC":{"t":"F","e":true,"f":"mode-config.js"},"sC":{"t":"F","e":true,"f":"mode-config.js"},"MD":{"t":"F","e":true,"f":"mode-config.js"},"MW":{"t":"F","e":true,"f":"mode-config.js"},"vP":{"t":"F","e":true,"f":"validate-pipeline.js"}},"edges":[],"orphans":["estimateTokens","walkJS","checkGitClean","extractNames","buildNamesDirective","updateCtxNames","S","walkJSFiles","addTopLevelNewlines","resolveCtxPath","compactFile","beautifyFile","extractLegend","findSymbolRange","buildJSDocBlock","findCtxFile","findExportStart","splitTopLevelParams","walkCtxFiles","resolveCtxMdPath","computeSignature","parseCtxDescriptions","buildFileTemplate","processFileCtx","parseCtxSignatures","parseCtxParams","extractReturnType","sanitizeJSDocText","generateJSDoc","parseCtxVars","parseCtxNames","collectLocals","collectLocalDecls","restoreNames","resolveCtx","fetchReference","listAvailable"],"duplicates":{},"files":["ai-context.js","compact-migrate.js","compact.js","compress.js","ctx-to-jsdoc.js","doc-dialect.js","expand.js","framework-references.js","instructions.js","mode-config.js","validate-pipeline.js"]}}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// @ctx .context/src/compact/compact-migrate.ctx
|
|
2
|
+
import{readFileSync as R,writeFileSync as W,readdirSync as n,statSync as o,existsSync as s}from"fs";import{join as r,extname as c,relative as a,basename as i,dirname as l}from"path";import{execSync as u}from"child_process";import{compactProject as d}from"./compact.js";import{validatePipeline as m}from"./validate-pipeline.js";import{setConfig as f}from"./mode-config.js";
|
|
3
|
+
const g=new Set([".js",".mjs"]),h=new Set(["node_modules",".git","vendor",".context","dev-docs",".agent",".agents",".expanded"]);
|
|
4
|
+
function walkJS(e,t=e){const s=[];try{for(const a of n(e)){if(a.startsWith(".")&&"."!==a)continue;
|
|
5
|
+
const n=r(e,a);o(n).isDirectory()?h.has(a)||s.push(...walkJS(n,t)):g.has(c(a).toLowerCase())&&s.push(n)}}catch{}return s}
|
|
6
|
+
function checkGitClean(e){try{const t=u("git status --porcelain",{cwd:e,encoding:"utf-8"}).trim();if(t)throw new Error("Working directory is not clean. Commit or stash changes first.\n\nDirty files:\n"+t)}catch(e){if(e.message.includes("not clean"))throw e;throw new Error("Not a git repository or git not available: "+e.message)}}
|
|
7
|
+
async function extractNames(e){const t=R(e,"utf-8"),n=new Set;try{const{parse:o}=await import("../../vendor/acorn.mjs"),{simple:s}=await import("../../vendor/walk.mjs"),r=o(t,{ecmaVersion:"latest",sourceType:"module"});s(r,{FunctionDeclaration(e){e.id?.name&&n.add(e.id.name)},ClassDeclaration(e){e.id?.name&&n.add(e.id.name)},VariableDeclarator(e){e.id?.name&&n.add(e.id.name)},ImportSpecifier(e){e.local?.name&&n.add(e.local.name)},ImportDefaultSpecifier(e){e.local?.name&&n.add(e.local.name)},AssignmentExpression(e){"Identifier"===e.left?.type&&n.add(e.left.name)}})}catch{const o=/(?:function\s+(\w+)|(\w+)\s*(?:=\s*(?:async\s+)?(?:function|\([^)]*\)\s*=>))|(?:const|let|var)\s+(\w+))/g;let s;while(s=o.exec(t)){const e=s[1]||s[2]||s[3];e&&e.length>1&&n.add(e)}}return[...n].filter(e=>e.length>1)}
|
|
8
|
+
function buildNamesDirective(e,t){const n=t.split("\n"),o=new Set;const s=/(?:^|[^a-zA-Z_$])([a-z])(?:\s*[=,)}\];:]|$)/g;for(const e of n){let t;while(t=s.exec(e)){o.add(t[1])}}const r=new Map;for(const t of e){const e=t.charAt(0).toLowerCase();if(o.has(e)&&!r.has(e)){r.set(e,t)}}if(0===r.size)return null;return"@names "+[...r.entries()].map(([e,t])=>`${e}=${t}`).join(",")}
|
|
9
|
+
function updateCtxNames(e,t,n){const o=a(n,e),s=i(o,c(o))+".ctx",u=l(o),d=r(n,".context",u,s);if(!S(d))return;try{let e=R(d,"utf-8");if(e.includes("@names")){e=e.replace(/@names .*/,t)}else{const n=e.indexOf("\n");e=-1===n?t+"\n"+e:e.slice(0,n+1)+t+"\n"+e.slice(n+1)}W(d,e,"utf-8")}catch{}}
|
|
10
|
+
function S(e){return s(e)}
|
|
11
|
+
export async function compactMigrate(e,t={}){const{dryRun:n=!1}=t;checkGitClean(e);
|
|
12
|
+
const o=walkJS(e),p=[];for(const t of o){const n=a(e,t),o=await extractNames(t),s=R(t,"utf-8");p.push({file:n,namesCount:o.length,names:o,originalSize:s.length})}
|
|
13
|
+
if(n)return{dryRun:!0,files:p.length,fileSummary:p.map(e=>({file:e.file,identifiers:e.namesCount,originalSize:e.originalSize}))};
|
|
14
|
+
const v=await d(e,{dryRun:!1});for(const t of o){const n=R(t,"utf-8"),o=p.find(e=>t.endsWith(e.file));if(o&&o.names.length>0){const s=buildNamesDirective(o.names,n);s&&updateCtxNames(t,s,e)}}
|
|
15
|
+
let b;try{b=await m(e,{strict:!1})}catch(e){b={status:"SKIP",reason:e.message}}
|
|
16
|
+
f(e,{mode:1});
|
|
17
|
+
return{migrated:!0,files:v.files,savings:v.savings,originalBytes:v.originalBytes,compactedBytes:v.compactedBytes,validation:b?.status||"SKIP",mode:"compact (1)",hint:"Run 'expand_project' to generate .expanded/ cache for human review"}}
|
package/src/compact/compress.js
CHANGED
|
@@ -6,7 +6,8 @@ let s="";if(t.start>0){const n=Math.max(0,t.start-500),a=e.slice(n,t.start).trim
|
|
|
6
6
|
export async function compressFile(t,s={}){const{beautify:r=!0,legend:i=!0}=s,c=n(t).toLowerCase();if(!o.has(c))throw new Error(`Unsupported file type: ${c}. Supported: ${[...o].join(", ")}`);
|
|
7
7
|
const l=e(t,"utf-8"),m=estimateTokens(l);if(!l.trim())return{code:"",legend:"",original:0,compressed:0,savings:"0%"};
|
|
8
8
|
const d={compress:{dead_code:!0,drop_console:!1,passes:2},mangle:!1,module:!0,output:{beautify:r,comments:!1,semicolons:!r}};
|
|
9
|
-
let p;try{const e=await a(l,d);if(e.error)throw e.error;p=e.code}catch(e){p=l.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*/g,"").replace(/\n{3,}/g,"\n\n").trim()}
|
|
9
|
+
let p;try{const e=await a(l,d);if(e.error)throw e.error;p=e.code}catch(e){p=l.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*/g,"").replace(/\n{3,}/g,"\n\n").trim()}// Join consecutive import lines into single line
|
|
10
|
+
p=p.replace(/(import\s.+?;)\n+(?=import\s)/g,"$1");const f=i?extractLegend(l,t):"",u=f?`/*\n${f}\n*/\n${p}`:p,y=estimateTokens(u);return{code:u,legend:f,original:m,compressed:y,savings:`${m>0?Math.round(100*(1-y/m)):0}%`}}
|
|
10
11
|
export async function editCompressed(t,n,r,o={}){const{beautify:i=!0,dryRun:c=!1}=o,l=e(t,"utf-8");
|
|
11
12
|
let m;try{m=s(l,{ecmaVersion:"latest",sourceType:"module",locations:!0})}catch(e){throw new Error(`Failed to parse ${t}: ${e.message}`)}const d=findSymbolRange(m,l,n);if(!d)throw new Error(`Symbol "${n}" not found in ${t}`);
|
|
12
13
|
let p=l.slice(0,d.start)+r+l.slice(d.end);if(i)try{const e=await a(p,{compress:!1,mangle:!1,module:!0,output:{beautify:!0,comments:!0,semicolons:!1}});e.code&&(p=e.code)}catch{}try{s(p,{ecmaVersion:"latest",sourceType:"module"})}catch(e){throw new Error(`Edit would create invalid syntax: ${e.message}`)}if(!c){const{writeFileSync:e}=await import("fs");e(t,p,"utf-8")}return{success:!0,file:t,symbol:n,oldRange:{start:d.start,end:d.end},newLength:r.length,...c?{dryRun:!0}:{}}}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// @ctx .context/src/compact/mode-config.ctx
|
|
2
2
|
import{readFileSync as e,writeFileSync as t,existsSync as d,mkdirSync as o}from"fs";import{join as a,dirname as n}from"path";
|
|
3
3
|
const r=".context/config.json",c={mode:2,beautify:!0,autoValidate:!1,stripJSDoc:!1};
|
|
4
|
-
export function getConfig(t){const o=a(t,r);if(!d(o))return{...c};try{const t=e(o,"utf-8"),d=JSON.parse(t)
|
|
4
|
+
export function getConfig(t){const o=a(t,r);if(!d(o))return{...c};try{const t=e(o,"utf-8"),d=JSON.parse(t),s={...c,...d};if(![1,2].includes(s.mode)){s.mode=2}return s}catch{return{...c}}}
|
|
5
5
|
export function setConfig(e,c){const i=a(e,r),s=n(i);d(s)||o(s,{recursive:!0});
|
|
6
|
-
const f={...getConfig(e),...c};if(![1,2
|
|
7
|
-
export function getModeDescription(e){switch(e){case 1:return"Compact —
|
|
8
|
-
export function getModeWorkflow(e){switch(e){case 1:return{read:"Read .js files directly (
|
|
6
|
+
const f={...getConfig(e),...c};if(![1,2].includes(f.mode))throw new Error(`Invalid mode: ${f.mode}. Valid: 1 (compact), 2 (full)`);return t(i,JSON.stringify(f,null,2)+"\n","utf-8"),{saved:!0,path:i,config:f}}
|
|
7
|
+
export function getModeDescription(e){switch(e){case 1:return"Compact — minified source + .expanded/ cache for human review (recommended)";case 2:return"Full — formatted source, agents use compressed view for reading";default:return`Unknown mode: ${e}`}}
|
|
8
|
+
export function getModeWorkflow(e){switch(e){case 1:return{read:"Read .js files directly (compact source = fewer tokens)",write:"Write .js files directly (compact output = cheaper output tokens)",review:".expanded/ cache with restored names + JSDoc for human review",validate:"Run validate_pipeline → contracts + expand + AST verify",expand:"Run expand_project to regenerate .expanded/ from compact + .ctx",migrate:"Run compact-migrate to convert formatted source → compact"};case 2:return{read:"Use get_compressed_file for token-efficient reading",write:"Use edit_compressed(path, symbol, code) for AST-safe editing",review:"Read source files directly (already formatted)",validate:"Run validate-ctx to check .ctx ↔ AST consistency"};default:return{read:"N/A",write:"N/A",review:"N/A",validate:"N/A"}}}
|
package/src/mcp/mcp-server.js
CHANGED
|
@@ -6,10 +6,10 @@ const r=new RegExp(`## ${s.topic}`,"i"),n=a.match(r);if(!n)return`Topic '${s.top
|
|
|
6
6
|
const i=n.index;
|
|
7
7
|
let c=a.indexOf("\n## ",i+1);return-1===c&&(c=a.length),a.substring(i,c).trim()}catch(e){return`Failed to read usage guide: ${e.message}`}},get_agent_instructions:()=>b(),get_undocumented:e=>k(A(e.path),e.level||"tests"),get_dead_code:e=>S(A(e.path)),generate_jsdoc:e=>e.name?R(A(e.path),e.name):$(A(e.path)),get_similar_functions:e=>F(A(e.path),{threshold:e.threshold}),get_complexity:e=>E(A(e.path),{minComplexity:e.minComplexity,onlyProblematic:e.onlyProblematic}),get_large_files:e=>C(A(e.path),{onlyProblematic:e.onlyProblematic}),get_outdated_patterns:e=>T(A(e.path),{codeOnly:e.codeOnly,depsOnly:e.depsOnly}),get_full_analysis:e=>U(A(e.path),{includeItems:e.includeItems}),get_custom_rules:()=>P(),set_custom_rule:e=>O(e.ruleSet,e.rule),check_custom_rules:e=>I(A(e.path),{ruleSet:e.ruleSet,severity:e.severity}),get_framework_reference:e=>J({framework:e.framework,path:e.path?A(e.path):void 0}),get_db_schema:e=>N(A(e.path)),get_table_usage:e=>L(A(e.path),e.table),get_db_dead_tables:e=>M(A(e.path)),get_compressed_file:e=>B(A(e.path),{beautify:e.beautify,legend:e.legend}),get_project_docs:async e=>{const t=A(e.path),s=await Q(t),o=G(s,t,{file:e.file});try{const e=await Y(t),s=W(t,e);return{docs:o,staleFiles:s.stale,freshCount:s.fresh}}catch{return{docs:o}}},generate_context_docs:async e=>{const t=A(e.path),s=await Q(t),o=await Y(t);return V(s,t,o,{overwrite:e.overwrite,scope:e.scope})},check_stale_docs:async e=>{const t=A(e.path),s=await Y(t);return W(t,s)},get_ai_context:async e=>{const t=A(e.path),s=await Z(t,{includeFiles:e.includeFiles,includeDocs:e.includeDocs,includeSkeleton:e.includeSkeleton});try{const e=await Y(t),o=W(t,e);s.staleFiles=o.stale}catch{}return s},check_jsdoc_consistency:e=>K(A(e.path)),check_types:async e=>X(A(e.path),{files:e.files,maxDiagnostics:e.maxDiagnostics}),discover_sub_projects:e=>H(A(e.path)),get_analysis_summary:e=>D(A(e.path)),compact_project:e=>ee(A(e.path),{dryRun:e.dryRun||!1}),beautify_project:e=>te(A(e.path),{dryRun:e.dryRun||!1}),validate_ctx_contracts:e=>re(A(e.path),{strict:e.strict||!1}),edit_compressed:e=>z(A(e.path),e.symbol,e.code,{beautify:!1!==e.beautify,dryRun:e.dryRun||!1}),get_mode:e=>{const t=A(e.path),s=ne(t);return{...s,description:ce(s.mode),workflow:de(s.mode)}},set_mode:e=>{const t=A(e.path),s={mode:e.mode};return void 0!==e.beautify&&(s.beautify=e.beautify),void 0!==e.autoValidate&&(s.autoValidate=e.autoValidate),void 0!==e.stripJSDoc&&(s.stripJSDoc=e.stripJSDoc),ie(t,s)},expand_file:async e=>{const s=A(e.path),o=t.dirname(t.dirname(s)),a=t.relative(o,s),r=t.basename(a,t.extname(a))+".ctx",n=t.dirname(a);
|
|
8
8
|
let i=null;
|
|
9
|
-
const c=t.join(o,n,r),d=t.join(o,".context",n,r);return pe(c)?i=le(c,"utf-8"):pe(d)&&(i=le(d,"utf-8")),se(s,i)},expand_project:e=>oe(A(e.path),{dryRun:e.dryRun||!1}),validate_pipeline:e=>ae(A(e.path),{strict:e.strict||!1})},_e={get_skeleton:()=>['💡 Use expand("SYMBOL") to see code for a specific class.','💡 Use deps("SYMBOL") to see architecture dependencies.',"💡 After code changes, run invalidate_cache() to refresh the graph."],expand:e=>{const t=[];return e.methods?.length>10&&t.push("💡 Large class detected. Run get_complexity() to find refactoring targets."),t.push("💡 Use deps() to see what depends on this symbol."),e.file&&t.push(`📝 No .ctx for ${e.file}? Run generate_context_docs({ scope: ["${e.file}"] }) to create documentation.`),t},deps:()=>["💡 Use usages() for cross-project reference search."],get_call_chain:e=>e.error?[]:["💡 Use expand() on intermediate steps to understand how data is passed along the chain."],invalidate_cache:()=>["✅ Cache cleared. Run get_skeleton() to rebuild the project graph."],get_dead_code:e=>{const t=["💡 Review each item before removing — some may be used dynamically."];return e.unusedExports?.length>20&&t.push('💡 Consider delegating cleanup to agent-pool: delegate_task({ prompt: "Remove dead code..." })'),t},get_full_analysis:()=>['💡 Focus on items with "critical" severity first.',"💡 Run individual tools (get_complexity, get_dead_code) for detailed breakdowns."],get_complexity:()=>["💡 Functions with complexity >10 are candidates for refactoring.","💡 Use expand() to read the function code before refactoring."],get_undocumented:()=>["💡 Use generate_jsdoc() to auto-generate documentation templates."],get_similar_functions:()=>["💡 Consider extracting duplicated logic into a shared utility."],get_pending_tests:()=>["💡 Use mark_test_passed(testId) or mark_test_failed(testId, reason) to track progress."],get_db_schema:e=>{const t=[];return e.totalTables>0?t.push(`💡 Found ${e.totalTables} tables. Use get_table_usage() to see which code reads/writes them.`):t.push("💡 No .sql schema files found. Add schema.sql or migrations/*.sql to your project."),t},get_table_usage:e=>{const t=["💡 Use get_db_dead_tables() to find tables defined in schema but never queried."];return 0===e.totalTables&&t.push("💡 No SQL queries detected. This tool finds SQL in .query(), .execute(), sql`...` patterns."),t},get_db_dead_tables:()=>["💡 Dead columns detection is best-effort — verify before removing."],get_compressed_file:e=>{const t=[`💡 Saved ${e.savings} tokens (${e.original} → ${e.compressed}).`];return t.push("💡 Use get_ai_context() for full project boot: skeleton + docs + compressed files."),e.file&&t.push(`📝 Working on ${e.file}? Run generate_context_docs({ scope: ["${e.file}"] }) to document it.`),t},get_project_docs:e=>{const t=["💡 Enrich docs by editing .context/*.ctx files — they are git-tracked.","💡 Use generate_context_docs() to create initial .ctx stubs."];return e.staleFiles?.length>0&&t.push(`⚠️ ${e.staleFiles.length} .ctx files are STALE: ${e.staleFiles.slice(0,5).join(", ")}. Run generate_context_docs({ scope: ${JSON.stringify(e.staleFiles)}, overwrite: true }) to update (descriptions will be preserved).`),t},check_stale_docs:e=>{const t=[];return e.stale?.length>0?(t.push(`⚠️ ${e.stale.length} stale: ${e.stale.join(", ")}`),t.push(`💡 Run generate_context_docs({ scope: ${JSON.stringify(e.stale)}, overwrite: true }) — existing descriptions will be preserved.`)):t.push("✅ All .ctx docs are up to date."),e.unknown>0&&t.push(`ℹ️ ${e.unknown} .ctx files without @sig header (pre-staleness format).`),t},generate_context_docs:e=>{const t=[];return e.created?.length>0&&t.push(`✅ Created ${e.created.length} .ctx files with @sig hashes.`),e.skipped?.length>0&&t.push(`ℹ️ Skipped ${e.skipped.length} existing files. Use overwrite=true to regenerate (descriptions are preserved via merge).`),e.templates&&Object.keys(e.templates).length>0&&(t.push("📝 .ctx files have {DESCRIBE} markers. To enrich automatically:"),t.push(' delegate_task({ prompt: "Enrich .context/*.ctx files — replace {DESCRIBE} with compact descriptions", skill: "doc-enricher" })'),t.push(" Or enrich manually: read source files and replace {DESCRIBE} markers with pipe-separated descriptions (max 80 chars).")),t},get_ai_context:e=>{const t=[`💡 Context loaded: ${e.totalTokens} tokens (${e.savings} savings vs ${e.vsOriginal} original).`];return t.push("💡 Use expand() to drill into specific symbols. Use get_compressed_file() for additional files."),t.push("📋 Read .context/*.ctx files for typed signatures and documentation. Check .gemini/AGENTS.md for project-specific rules."),e.staleFiles?.length>0&&t.push(`⚠️ ${e.staleFiles.length} .ctx docs are stale. Run generate_context_docs({ scope: ${JSON.stringify(e.staleFiles)}, overwrite: true }) then delegate_task({ skill: "doc-enricher" }) to update.`),t},validate_ctx_contracts:e=>{const t=[];return e.summary?.errors>0?t.push(`⚠️ ${e.summary.errors} contract violations found. Run generate_context_docs({ overwrite: true }) to regenerate .ctx files.`):t.push("✅ All .ctx contracts valid — documentation matches source."),t},edit_compressed:e=>{const t=[];return e.success&&(t.push(`✅ Symbol "${e.symbol}" replaced in ${e.file}.`),t.push("💡 Run invalidate_cache() to refresh the graph after editing."),t.push("💡 Run validate_ctx_contracts() to check if .ctx docs need updating.")),t},get_mode:e=>{const t=[`📋 Current mode: ${e.mode} — ${e.description}`];return 2===e.mode&&t.push("💡
|
|
9
|
+
const c=t.join(o,n,r),d=t.join(o,".context",n,r);return pe(c)?i=le(c,"utf-8"):pe(d)&&(i=le(d,"utf-8")),se(s,i)},expand_project:e=>oe(A(e.path),{dryRun:e.dryRun||!1}),validate_pipeline:e=>ae(A(e.path),{strict:e.strict||!1})},_e={get_skeleton:()=>['💡 Use expand("SYMBOL") to see code for a specific class.','💡 Use deps("SYMBOL") to see architecture dependencies.',"💡 After code changes, run invalidate_cache() to refresh the graph.","🌐 Web explorer: run `npx project-graph-mcp serve .` to browse code visually."],expand:e=>{const t=[];return e.methods?.length>10&&t.push("💡 Large class detected. Run get_complexity() to find refactoring targets."),t.push("💡 Use deps() to see what depends on this symbol."),e.file&&t.push(`📝 No .ctx for ${e.file}? Run generate_context_docs({ scope: ["${e.file}"] }) to create documentation.`),t},deps:()=>["💡 Use usages() for cross-project reference search."],get_call_chain:e=>e.error?[]:["💡 Use expand() on intermediate steps to understand how data is passed along the chain."],invalidate_cache:()=>["✅ Cache cleared. Run get_skeleton() to rebuild the project graph."],get_dead_code:e=>{const t=["💡 Review each item before removing — some may be used dynamically."];return e.unusedExports?.length>20&&t.push('💡 Consider delegating cleanup to agent-pool: delegate_task({ prompt: "Remove dead code..." })'),t},get_full_analysis:()=>['💡 Focus on items with "critical" severity first.',"💡 Run individual tools (get_complexity, get_dead_code) for detailed breakdowns."],get_complexity:()=>["💡 Functions with complexity >10 are candidates for refactoring.","💡 Use expand() to read the function code before refactoring."],get_undocumented:()=>["💡 Use generate_jsdoc() to auto-generate documentation templates."],get_similar_functions:()=>["💡 Consider extracting duplicated logic into a shared utility."],get_pending_tests:()=>["💡 Use mark_test_passed(testId) or mark_test_failed(testId, reason) to track progress."],get_db_schema:e=>{const t=[];return e.totalTables>0?t.push(`💡 Found ${e.totalTables} tables. Use get_table_usage() to see which code reads/writes them.`):t.push("💡 No .sql schema files found. Add schema.sql or migrations/*.sql to your project."),t},get_table_usage:e=>{const t=["💡 Use get_db_dead_tables() to find tables defined in schema but never queried."];return 0===e.totalTables&&t.push("💡 No SQL queries detected. This tool finds SQL in .query(), .execute(), sql`...` patterns."),t},get_db_dead_tables:()=>["💡 Dead columns detection is best-effort — verify before removing."],get_compressed_file:e=>{const t=[`💡 Saved ${e.savings} tokens (${e.original} → ${e.compressed}).`];return t.push("💡 Use get_ai_context() for full project boot: skeleton + docs + compressed files."),e.file&&t.push(`📝 Working on ${e.file}? Run generate_context_docs({ scope: ["${e.file}"] }) to document it.`),t},get_project_docs:e=>{const t=["💡 Enrich docs by editing .context/*.ctx files — they are git-tracked.","💡 Use generate_context_docs() to create initial .ctx stubs."];return e.staleFiles?.length>0&&t.push(`⚠️ ${e.staleFiles.length} .ctx files are STALE: ${e.staleFiles.slice(0,5).join(", ")}. Run generate_context_docs({ scope: ${JSON.stringify(e.staleFiles)}, overwrite: true }) to update (descriptions will be preserved).`),t},check_stale_docs:e=>{const t=[];return e.stale?.length>0?(t.push(`⚠️ ${e.stale.length} stale: ${e.stale.join(", ")}`),t.push(`💡 Run generate_context_docs({ scope: ${JSON.stringify(e.stale)}, overwrite: true }) — existing descriptions will be preserved.`)):t.push("✅ All .ctx docs are up to date."),e.unknown>0&&t.push(`ℹ️ ${e.unknown} .ctx files without @sig header (pre-staleness format).`),t},generate_context_docs:e=>{const t=[];return e.created?.length>0&&t.push(`✅ Created ${e.created.length} .ctx files with @sig hashes.`),e.skipped?.length>0&&t.push(`ℹ️ Skipped ${e.skipped.length} existing files. Use overwrite=true to regenerate (descriptions are preserved via merge).`),e.templates&&Object.keys(e.templates).length>0&&(t.push("📝 .ctx files have {DESCRIBE} markers. To enrich automatically:"),t.push(' delegate_task({ prompt: "Enrich .context/*.ctx files — replace {DESCRIBE} with compact descriptions", skill: "doc-enricher" })'),t.push(" Or enrich manually: read source files and replace {DESCRIBE} markers with pipe-separated descriptions (max 80 chars).")),t},get_ai_context:e=>{const t=[`💡 Context loaded: ${e.totalTokens} tokens (${e.savings} savings vs ${e.vsOriginal} original).`];return t.push("💡 Use expand() to drill into specific symbols. Use get_compressed_file() for additional files."),t.push("📋 Read .context/*.ctx files for typed signatures and documentation. Check .gemini/AGENTS.md for project-specific rules."),e.staleFiles?.length>0&&t.push(`⚠️ ${e.staleFiles.length} .ctx docs are stale. Run generate_context_docs({ scope: ${JSON.stringify(e.staleFiles)}, overwrite: true }) then delegate_task({ skill: "doc-enricher" }) to update.`),t},validate_ctx_contracts:e=>{const t=[];return e.summary?.errors>0?t.push(`⚠️ ${e.summary.errors} contract violations found. Run generate_context_docs({ overwrite: true }) to regenerate .ctx files.`):t.push("✅ All .ctx contracts valid — documentation matches source."),t},edit_compressed:e=>{const t=[];return e.success&&(t.push(`✅ Symbol "${e.symbol}" replaced in ${e.file}.`),t.push("💡 Run invalidate_cache() to refresh the graph after editing."),t.push("💡 Run validate_ctx_contracts() to check if .ctx docs need updating.")),t},get_mode:e=>{const t=[`📋 Current mode: ${e.mode} — ${e.description}`];return 1===e.mode&&(t.push("💡 Compact mode: read/write .js directly. Run expand_project to update .expanded/ for human review."),t.push("🌐 Web explorer: `npx project-graph-mcp serve .` for visual code browsing with compression stats.")),2===e.mode&&(t.push("💡 Full mode: get_compressed_file() → read → edit_compressed() → write."),t.push("🌐 Web explorer: `npx project-graph-mcp serve .` for visual code browsing with compression stats.")),t},set_mode:e=>e.saved?[`✅ Mode set to ${e.config.mode}. Saved to ${e.path}.`]:[],validate_pipeline:e=>{const t=[`${"PASS"===e.status?"✅":"❌"} Pipeline ${e.status} (${e.duration}): ${e.summary.contractErrors} contract errors, ${e.summary.astErrors} AST errors.`];return"PASS"===e.status&&t.push(`💡 ${e.summary.jsdocInjected} JSDoc blocks injected. Token savings: ${e.summary.tokenSavings}.`),e.summary.contractErrors>0&&t.push("⚠️ Fix .ctx contract errors first, then re-run validate_pipeline."),t},expand_project:e=>[`✅ Expanded ${e.files} files → ${e.outputDir}. ${e.totalJSDocInjected} JSDoc blocks injected.`]},ge={navigate:e=>{const t={expand:"expand",deps:"deps",usages:"usages",call_chain:"get_call_chain",sub_projects:"discover_sub_projects"}[e.action];if(!t)throw new Error(`Unknown navigate action: ${e.action}`);return me[t](e)},analyze:e=>{const t={dead_code:"get_dead_code",similar_functions:"get_similar_functions",complexity:"get_complexity",large_files:"get_large_files",outdated_patterns:"get_outdated_patterns",full_analysis:"get_full_analysis",analysis_summary:"get_analysis_summary",undocumented:"get_undocumented"}[e.action];if(!t)throw new Error(`Unknown analyze action: ${e.action}`);return me[t](e)},testing:e=>{const t={pending:"get_pending_tests",pass:"mark_test_passed",fail:"mark_test_failed",summary:"get_test_summary",reset:"reset_test_state"}[e.action];if(!t)throw new Error(`Unknown testing action: ${e.action}`);return me[t](e)},filters:e=>{const t={get:"get_filters",set:"set_filters",add_excludes:"add_excludes",remove_excludes:"remove_excludes",reset:"reset_filters"}[e.action];if(!t)throw new Error(`Unknown filters action: ${e.action}`);return me[t](e)},jsdoc:e=>{const t={check_consistency:"check_jsdoc_consistency",check_types:"check_types",generate:"generate_jsdoc"}[e.action];if(!t)throw new Error(`Unknown jsdoc action: ${e.action}`);return me[t](e)},docs:e=>{const t={get:"get_project_docs",generate:"generate_context_docs",check_stale:"check_stale_docs",validate_contracts:"validate_ctx_contracts"}[e.action];if(!t)throw new Error(`Unknown docs action: ${e.action}`);return me[t](e)},compact:e=>{const t={compact_file:"get_compressed_file",edit:"edit_compressed",compact_all:"compact_project",beautify:"beautify_project",expand_file:"expand_file",expand_project:"expand_project",validate_pipeline:"validate_pipeline",get_mode:"get_mode",set_mode:"set_mode"}[e.action];if(!t)throw new Error(`Unknown compact action: ${e.action}`);return me[t](e)},db:e=>{const t={schema:"get_db_schema",table_usage:"get_table_usage",dead_tables:"get_db_dead_tables"}[e.action];if(!t)throw new Error(`Unknown db action: ${e.action}`);return me[t](e)}},he={navigate:(e,t)=>{const s=_e[{expand:"expand",deps:"deps",call_chain:"get_call_chain"}[t.action]];return s?s(e):[]},analyze:(e,t)=>{const s=_e[{dead_code:"get_dead_code",full_analysis:"get_full_analysis",complexity:"get_complexity",undocumented:"get_undocumented",similar_functions:"get_similar_functions"}[t.action]];return s?s(e):[]},testing:(e,t)=>"pending"===t.action&&_e.get_pending_tests?.(e)||[],docs:(e,t)=>{const s=_e[{get:"get_project_docs",check_stale:"check_stale_docs",generate:"generate_context_docs",validate_contracts:"validate_ctx_contracts"}[t.action]];return s?s(e):[]},compact:(e,t)=>{const s=_e[{compact_file:"get_compressed_file",edit:"edit_compressed",get_mode:"get_mode",set_mode:"set_mode",validate_pipeline:"validate_pipeline",expand_project:"expand_project"}[t.action]];return s?s(e):[]},db:(e,t)=>{const s=_e[{schema:"get_db_schema",table_usage:"get_table_usage",dead_tables:"get_db_dead_tables"}[t.action]];return s?s(e):[]}};
|
|
10
10
|
export function createServer(s){let n=1;
|
|
11
11
|
const i=new Map;
|
|
12
|
-
let c=!1;return{pendingRequests:i,async handleMessage(s){if(void 0!==s.result||void 0!==s.error){const e=i.get(s.id);return e&&(i.delete(s.id),s.error?e.reject(new Error(s.error.message)):e.resolve(s.result)),null}const{method:a,params:r,id:n}=s;if(void 0===n)return await this.handleNotification(a,r),null;try{switch(a){case"initialize":return r?.capabilities?.roots&&(c=!0),r?.roots&&q(r.roots),{jsonrpc:"2.0",id:n,result:{protocolVersion:"2024-11-05",capabilities:{tools:{},resources:{}},serverInfo:{name:"project-graph",version:"2.
|
|
12
|
+
let c=!1;return{pendingRequests:i,async handleMessage(s){if(void 0!==s.result||void 0!==s.error){const e=i.get(s.id);return e&&(i.delete(s.id),s.error?e.reject(new Error(s.error.message)):e.resolve(s.result)),null}const{method:a,params:r,id:n}=s;if(void 0===n)return await this.handleNotification(a,r),null;try{switch(a){case"initialize":return r?.capabilities?.roots&&(c=!0),r?.roots&&q(r.roots),{jsonrpc:"2.0",id:n,result:{protocolVersion:"2024-11-05",capabilities:{tools:{},resources:{}},serverInfo:{name:"project-graph",version:"2.1.0"}}};case"resources/list":return{jsonrpc:"2.0",id:n,result:{resources:[{uri:"project-graph://guide",name:"Project Graph Usage Guide",description:"Comprehensive guide with workflows and examples",mimeType:"text/markdown"}]}};case"resources/read":return"project-graph://guide"!==r.uri?{jsonrpc:"2.0",id:n,error:{code:-32602,message:`Resource not found: ${r.uri}`}}:{jsonrpc:"2.0",id:n,result:{contents:[{uri:"project-graph://guide",mimeType:"text/markdown",text:e.readFileSync(t.join(ue,"..","..","GUIDE.md"),"utf8")}]}};case"tools/list":return{jsonrpc:"2.0",id:n,result:{tools:o}};case"tools/call":{const e=await this.executeTool(r.name,r.arguments),t=[{type:"text",text:JSON.stringify(e,null,2)}];
|
|
13
13
|
let s=[];
|
|
14
14
|
const o=he[r.name];if(o&&r.arguments?.action)s=o(e,r.arguments);else{const t=_e[r.name];t&&(s=t(e))}return s.length>0&&t.push({type:"text",text:"\n"+s.join("\n")}),{jsonrpc:"2.0",id:n,result:{content:t}}}default:return{jsonrpc:"2.0",id:n,error:{code:-32601,message:`Method not found: ${a}`}}}}catch(e){return{jsonrpc:"2.0",id:n,error:{code:-32e3,message:e.message}}}},async handleNotification(e,t){switch(e){case"notifications/initialized":if(c)try{const e=await this.requestRoots();e&&e.length>0&&q(e)}catch(e){console.error(`[project-graph] Failed to get roots: ${e.message}`)}break;case"notifications/roots/list_changed":if(c)try{const e=await this.requestRoots();e&&e.length>0&&(q(e),p())}catch(e){console.error(`[project-graph] Failed to refresh roots: ${e.message}`)}}},requestRoots:()=>new Promise((e,t)=>{const o=n++,a=setTimeout(()=>{i.delete(o),t(new Error("roots/list request timed out"))},5e3);i.set(o,{resolve:t=>{clearTimeout(a),e(t.roots||[])},reject:e=>{clearTimeout(a),t(e)}}),s({jsonrpc:"2.0",id:o,method:"roots/list"})}),async executeTool(e,t){a(e,t);
|
|
15
15
|
const s=Date.now();try{const o=ge[e];
|
package/src/mcp/tool-defs.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @ctx .context/src/mcp/tool-defs.ctx
|
|
2
2
|
const e={get_skeleton:{name:"get_skeleton",description:"Get compact minified project overview (10-50x smaller than source). Returns legend, stats, and node summaries.",inputSchema:{type:"object",properties:{path:{type:"string",description:'Path to scan (e.g., "src/components")'}},required:["path"]}},get_focus_zone:{name:"get_focus_zone",description:"Get enriched context for recently modified files. Auto-detects from git or accepts explicit file list.",inputSchema:{type:"object",properties:{path:{type:"string"},useGitDiff:{type:"boolean",description:"Auto-detect from git diff"},recentFiles:{type:"array",items:{type:"string"},description:"Explicit list of files to expand"}}}},get_ai_context:{name:"get_ai_context",description:"Boot AI agent context: skeleton + doc-dialect + optional compressed files in one call. Call FIRST when starting work on a new project. Returns totalTokens and savings vs reading raw source.",inputSchema:{type:"object",properties:{path:{type:"string",description:"Project root path"},includeFiles:{type:"array",items:{type:"string"},description:'Specific files to include compressed (e.g., ["parser.js", "tools.js"])'},includeDocs:{type:"boolean",description:"Include doc-dialect documentation (default: true)"},includeSkeleton:{type:"boolean",description:"Include project skeleton (default: true)"}},required:["path"]}},invalidate_cache:{name:"invalidate_cache",description:"Invalidate the cached graph. Use after making code changes.",inputSchema:{type:"object",properties:{}}},get_usage_guide:{name:"get_usage_guide",description:"Get the comprehensive usage guide for project-graph with examples and best practices.\nCall this FIRST when planning how to analyze, navigate, or audit a codebase.\nReturns practical examples and recommended workflow for each feature area.\n\nAvailable topics: navigation, analysis, testing, documentation, rules, workflow.\nOmit topic to get the full guide.",inputSchema:{type:"object",properties:{topic:{type:"string",description:"Optional topic filter: navigation, analysis, testing, documentation, rules, workflow"}}}},get_agent_instructions:{name:"get_agent_instructions",description:"Get coding guidelines, architectural standards, and JSDoc rules for this project.",inputSchema:{type:"object",properties:{}}},get_custom_rules:{name:"get_custom_rules",description:"List all custom code analysis rules. Rules are stored in JSON files in rules/ directory.",inputSchema:{type:"object",properties:{}}},set_custom_rule:{name:"set_custom_rule",description:"Add or update a custom code analysis rule. Creates ruleset if it does not exist.",inputSchema:{type:"object",properties:{ruleSet:{type:"string",description:'Name of ruleset (e.g., "symbiote", "react", "custom")'},rule:{type:"object",description:"Rule definition with id, name, description, pattern, patternType, replacement, severity, filePattern"}},required:["ruleSet","rule"]}},check_custom_rules:{name:"check_custom_rules",description:"Run custom rules analysis on a directory. Returns violations found.",inputSchema:{type:"object",properties:{path:{type:"string",description:"Path to scan"},ruleSet:{type:"string",description:"Optional: specific ruleset to use"},severity:{type:"string",description:"Optional: filter by severity (error/warning/info)"}},required:["path"]}},get_framework_reference:{name:"get_framework_reference",description:"Get framework-specific AI reference documentation. Auto-detects framework from project or accepts explicit name. Returns full API reference, patterns, and common mistakes as agent context.",inputSchema:{type:"object",properties:{framework:{type:"string",description:'Framework reference name (e.g., "symbiote-3x"). If omitted, auto-detects from path.'},path:{type:"string",description:'Project path for auto-detection (e.g., "src/")'}}}}};
|
|
3
|
-
export const TOOLS=[e.get_skeleton,e.get_focus_zone,e.get_ai_context,e.invalidate_cache,e.get_usage_guide,e.get_agent_instructions,e.get_custom_rules,e.set_custom_rule,e.check_custom_rules,e.get_framework_reference,{name:"navigate",description:"Navigate the project graph. Actions: expand|deps|usages|call_chain|sub_projects",inputSchema:{type:"object",properties:{action:{type:"string",enum:["expand","deps","usages","call_chain","sub_projects"],description:"Navigation action to perform"},symbol:{type:"string",description:"Symbol name (for expand, deps, usages)"},from:{type:"string",description:"Starting symbol (for call_chain)"},to:{type:"string",description:"Target symbol (for call_chain)"},path:{type:"string",description:"Path to scan (for call_chain, sub_projects)"}},required:["action"]}},{name:"analyze",description:"Code quality analysis. Actions: dead_code|similar_functions|complexity|large_files|outdated_patterns|full_analysis|analysis_summary|undocumented",inputSchema:{type:"object",properties:{action:{type:"string",enum:["dead_code","similar_functions","complexity","large_files","outdated_patterns","full_analysis","analysis_summary","undocumented"],description:"Analysis type to run"},path:{type:"string",description:"Path to scan"},minComplexity:{type:"number",description:"For complexity: minimum threshold (default: 1)"},onlyProblematic:{type:"boolean",description:"For complexity/large_files: only show issues"},threshold:{type:"number",description:"For similar_functions: min similarity % (default: 60)"},includeItems:{type:"boolean",description:"For full_analysis: include individual items"},level:{type:"string",enum:["tests","params","all"],description:"For undocumented: strictness level"},codeOnly:{type:"boolean",description:"For outdated_patterns: only check code"},depsOnly:{type:"boolean",description:"For outdated_patterns: only check deps"}},required:["action","path"]}},{name:"testing",description:"Test checklist management. Actions: pending|pass|fail|summary|reset",inputSchema:{type:"object",properties:{action:{type:"string",enum:["pending","pass","fail","summary","reset"],description:"Test action to perform"},path:{type:"string",description:"Path to scan (for pending, summary)"},testId:{type:"string",description:"Test ID (for pass, fail)"},reason:{type:"string",description:"Failure reason (for fail)"}},required:["action"]}},{name:"filters",description:"Filter configuration. Actions: get|set|add_excludes|remove_excludes|reset",inputSchema:{type:"object",properties:{action:{type:"string",enum:["get","set","add_excludes","remove_excludes","reset"],description:"Filter action to perform"},excludeDirs:{type:"array",items:{type:"string"},description:"For set: directories to exclude"},excludePatterns:{type:"array",items:{type:"string"},description:"For set: file patterns to exclude"},useGitignore:{type:"boolean",description:"For set: use .gitignore patterns"},includeHidden:{type:"boolean",description:"For set: include hidden directories"},dirs:{type:"array",items:{type:"string"},description:"For add_excludes/remove_excludes"}},required:["action"]}},{name:"jsdoc",description:"JSDoc operations. Actions: check_consistency|check_types|generate",inputSchema:{type:"object",properties:{action:{type:"string",enum:["check_consistency","check_types","generate"],description:"JSDoc action to perform"},path:{type:"string",description:"Path to scan"},name:{type:"string",description:"For generate: specific function name"},files:{type:"array",items:{type:"string"},description:"For check_types: specific files"},maxDiagnostics:{type:"number",description:"For check_types: max diagnostics (default: 50)"}},required:["action","path"]}},{name:"docs",description:"Documentation (.ctx) management. Actions: get|generate|check_stale|validate_contracts",inputSchema:{type:"object",properties:{action:{type:"string",enum:["get","generate","check_stale","validate_contracts"],description:"Documentation action to perform"},path:{type:"string",description:"Project root path"},file:{type:"string",description:"For get: specific file docs"},overwrite:{type:"boolean",description:"For generate: overwrite existing (merge preserves descriptions)"},scope:{description:'For generate: "all", "focus" (git diff), or array of file paths'},strict:{type:"boolean",description:"For validate_contracts: report functions missing from .ctx"}},required:["action","path"]}},{name:"compact",description:"Compact code operations. Actions: compact_file|edit|compact_all|beautify|expand_file|expand_project|validate_pipeline|get_mode|set_mode",inputSchema:{type:"object",properties:{action:{type:"string",enum:["compact_file","edit","compact_all","beautify","expand_file","expand_project","validate_pipeline","get_mode","set_mode"],description:"Compact action to perform"},path:{type:"string",description:"Path to file or directory"},symbol:{type:"string",description:"For edit: function/class name to replace"},code:{type:"string",description:"For edit: new code for the symbol"},beautify:{type:"boolean",description:"Beautify output (default: true)"},legend:{type:"boolean",description:"For compact_file: include export legend"},dryRun:{type:"boolean",description:"Preview without modifying"},mode:{type:"number",description:"For set_mode:
|
|
3
|
+
export const TOOLS=[e.get_skeleton,e.get_focus_zone,e.get_ai_context,e.invalidate_cache,e.get_usage_guide,e.get_agent_instructions,e.get_custom_rules,e.set_custom_rule,e.check_custom_rules,e.get_framework_reference,{name:"navigate",description:"Navigate the project graph. Actions: expand|deps|usages|call_chain|sub_projects",inputSchema:{type:"object",properties:{action:{type:"string",enum:["expand","deps","usages","call_chain","sub_projects"],description:"Navigation action to perform"},symbol:{type:"string",description:"Symbol name (for expand, deps, usages)"},from:{type:"string",description:"Starting symbol (for call_chain)"},to:{type:"string",description:"Target symbol (for call_chain)"},path:{type:"string",description:"Path to scan (for call_chain, sub_projects)"}},required:["action"]}},{name:"analyze",description:"Code quality analysis. Actions: dead_code|similar_functions|complexity|large_files|outdated_patterns|full_analysis|analysis_summary|undocumented",inputSchema:{type:"object",properties:{action:{type:"string",enum:["dead_code","similar_functions","complexity","large_files","outdated_patterns","full_analysis","analysis_summary","undocumented"],description:"Analysis type to run"},path:{type:"string",description:"Path to scan"},minComplexity:{type:"number",description:"For complexity: minimum threshold (default: 1)"},onlyProblematic:{type:"boolean",description:"For complexity/large_files: only show issues"},threshold:{type:"number",description:"For similar_functions: min similarity % (default: 60)"},includeItems:{type:"boolean",description:"For full_analysis: include individual items"},level:{type:"string",enum:["tests","params","all"],description:"For undocumented: strictness level"},codeOnly:{type:"boolean",description:"For outdated_patterns: only check code"},depsOnly:{type:"boolean",description:"For outdated_patterns: only check deps"}},required:["action","path"]}},{name:"testing",description:"Test checklist management. Actions: pending|pass|fail|summary|reset",inputSchema:{type:"object",properties:{action:{type:"string",enum:["pending","pass","fail","summary","reset"],description:"Test action to perform"},path:{type:"string",description:"Path to scan (for pending, summary)"},testId:{type:"string",description:"Test ID (for pass, fail)"},reason:{type:"string",description:"Failure reason (for fail)"}},required:["action"]}},{name:"filters",description:"Filter configuration. Actions: get|set|add_excludes|remove_excludes|reset",inputSchema:{type:"object",properties:{action:{type:"string",enum:["get","set","add_excludes","remove_excludes","reset"],description:"Filter action to perform"},excludeDirs:{type:"array",items:{type:"string"},description:"For set: directories to exclude"},excludePatterns:{type:"array",items:{type:"string"},description:"For set: file patterns to exclude"},useGitignore:{type:"boolean",description:"For set: use .gitignore patterns"},includeHidden:{type:"boolean",description:"For set: include hidden directories"},dirs:{type:"array",items:{type:"string"},description:"For add_excludes/remove_excludes"}},required:["action"]}},{name:"jsdoc",description:"JSDoc operations. Actions: check_consistency|check_types|generate",inputSchema:{type:"object",properties:{action:{type:"string",enum:["check_consistency","check_types","generate"],description:"JSDoc action to perform"},path:{type:"string",description:"Path to scan"},name:{type:"string",description:"For generate: specific function name"},files:{type:"array",items:{type:"string"},description:"For check_types: specific files"},maxDiagnostics:{type:"number",description:"For check_types: max diagnostics (default: 50)"}},required:["action","path"]}},{name:"docs",description:"Documentation (.ctx) management. Actions: get|generate|check_stale|validate_contracts",inputSchema:{type:"object",properties:{action:{type:"string",enum:["get","generate","check_stale","validate_contracts"],description:"Documentation action to perform"},path:{type:"string",description:"Project root path"},file:{type:"string",description:"For get: specific file docs"},overwrite:{type:"boolean",description:"For generate: overwrite existing (merge preserves descriptions)"},scope:{description:'For generate: "all", "focus" (git diff), or array of file paths'},strict:{type:"boolean",description:"For validate_contracts: report functions missing from .ctx"}},required:["action","path"]}},{name:"compact",description:"Compact code operations. Actions: compact_file|edit|compact_all|beautify|expand_file|expand_project|validate_pipeline|get_mode|set_mode",inputSchema:{type:"object",properties:{action:{type:"string",enum:["compact_file","edit","compact_all","beautify","expand_file","expand_project","validate_pipeline","get_mode","set_mode"],description:"Compact action to perform"},path:{type:"string",description:"Path to file or directory"},symbol:{type:"string",description:"For edit: function/class name to replace"},code:{type:"string",description:"For edit: new code for the symbol"},beautify:{type:"boolean",description:"Beautify output (default: true)"},legend:{type:"boolean",description:"For compact_file: include export legend"},dryRun:{type:"boolean",description:"Preview without modifying"},mode:{type:"number",description:"For set_mode: 1 (compact, recommended) or 2 (full)"},autoValidate:{type:"boolean",description:"For set_mode: auto-validate after edits"},stripJSDoc:{type:"boolean",description:"For set_mode: strip JSDoc when compacting"},strict:{type:"boolean",description:"For validate_pipeline: report fns missing from .ctx"}},required:["action"]}},{name:"db",description:"Database analysis. Actions: schema|table_usage|dead_tables",inputSchema:{type:"object",properties:{action:{type:"string",enum:["schema","table_usage","dead_tables"],description:"Database analysis action"},path:{type:"string",description:"Path to scan"},table:{type:"string",description:"For table_usage: filter to specific table"}},required:["action","path"]}}];
|
package/web/app.js
CHANGED
|
@@ -13,4 +13,5 @@ async function f(){g(),l(),i("project",t=>{t&&(document.title=`${t.name} — Pro
|
|
|
13
13
|
const n=new Set;for(const o of Object.values(t.n||{}))o.f&&n.add(o.f);for(const o of Object.keys(t.X||{}))n.add(o);for(const[o,a]of Object.entries(t.f||{}))for(const t of a)n.add("./"===o?t:`${o}${t}`);for(const[o,a]of Object.entries(t.a||{}))for(const t of a)n.add("./"===o?t:`${o}${t}`);
|
|
14
14
|
const o=document.getElementById("project-files");o&&(o.textContent=`${n.size} files`),emit("skeleton-loaded",t),fetch(m+"api/compression-stats").then(t=>t.json()).then(t=>{const n=document.getElementById("compression-stats");if(n&&t.codeTok){const o=t.ctxTok?`${(t.codeTok/1e3).toFixed(1)}K + ${(t.ctxTok/1e3).toFixed(1)}K ctx = ${(t.totalTok/1e3).toFixed(1)}K tok`:`${(t.codeTok/1e3).toFixed(1)}K tok`;n.textContent=o,n.style.display=""}})}),i("connected",t=>{const n=document.getElementById("status-indicator");n&&(n.className=t?"status connected":"status disconnected")}),r(t=>{if("agent_connect"===t.type||"agent_disconnect"===t.type)return h(t.agents),void emit("agent-event",t);state.monitorEvents.push(t),state.monitorEvents.length>500&&state.monitorEvents.shift(),emit("tool-event",t)})}
|
|
15
15
|
function h(t){let n=document.getElementById("agent-badge");if(!n){const t=document.querySelector(".app-topbar");if(!t)return;n=document.createElement("span"),n.id="agent-badge",n.className="agent-badge",t.appendChild(n)}n.textContent=t>0?`● ${t} agent${1!==t?"s":""}`:"",n.style.display=t>0?"":"none"}
|
|
16
|
-
function y(){document.querySelector("pg-quick-open")||document.body.appendChild(document.createElement("pg-quick-open"))}
|
|
16
|
+
function y(){document.querySelector("pg-quick-open")||document.body.appendChild(document.createElement("pg-quick-open"))}
|
|
17
|
+
"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{f(),y()}):setTimeout(()=>{f(),y()},100);
|