project-graph-mcp 1.3.0 โ†’ 1.5.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/AGENT_ROLE.md CHANGED
@@ -5,27 +5,37 @@ You have access to **Project Graph MCP** โ€” a suite of code analysis and projec
5
5
  ## ๐Ÿงญ Navigation & Understanding
6
6
  | Tool | Purpose |
7
7
  |------|---------|
8
- | `get_structure` | Get file/folder tree |
9
- | `get_skeleton` | Get code structure (classes, functions, exports) |
8
+ | `get_skeleton` | Get compact code structure (classes, functions, exports) |
10
9
  | `expand` | Deep dive into a class or function |
10
+ | `get_focus_zone` | Get enriched context for recently modified files |
11
+ | `get_call_chain` | Find shortest path between two symbols |
12
+ | `usages` | Find all usages of a symbol across the project |
13
+ | `deps` | Get dependency tree for a symbol |
11
14
  | `get_agent_instructions` | Get project coding guidelines |
12
15
  | `get_framework_reference` | Get framework AI reference (auto-detects or explicit) |
16
+ | `get_usage_guide` | Get full usage guide with examples |
17
+ | `invalidate_cache` | Refresh graph after code changes (MANDATORY after edits) |
13
18
 
14
19
  ## ๐Ÿงช Testing System
15
20
 
16
21
  | Tool | Purpose |
17
22
  |------|---------|
18
- | `get_pending_tests` | List @test/@expect annotations needing verification |
19
- | `mark_test_passed` / `mark_test_failed` | Track test results |
23
+ | `get_pending_tests` | List `[ ]` checklists from `.ctx.md` files |
24
+ | `mark_test_passed` / `mark_test_failed` | Write `[x]` or `[!]` directly to `.ctx.md` |
20
25
  | `get_test_summary` | Progress report |
26
+ | `reset_test_state` | Reset all checklists to `[ ]` |
21
27
 
22
- ### When to Write @test/@expect
23
- Add annotations to JSDoc when creating or modifying **interactive methods**:
24
- - `onclick` / `onchange` / `oninput` event handlers
25
- - Methods that change DOM state (show/hide, toggle classes/attributes)
26
- - Navigation and routing methods
27
- - Form submission and validation handlers
28
- - Any method with user-visible side effects
28
+ ### How Test Checklists Work
29
+ Tests live in `.ctx.md` files (the "agent zone" of the two-tier documentation), not in source code:
30
+
31
+ ```markdown
32
+ # parser.js
33
+
34
+ ## Tests
35
+ - [ ] Parse valid JS file with classes and functions
36
+ - [ ] Handle syntax errors gracefully
37
+ - [x] Parse empty file without crash
38
+ ```
29
39
 
30
40
  ### Browser Testing Workflow (VERIFICATION mode)
31
41
  After code changes, you MUST verify UI with this flow:
@@ -37,20 +47,9 @@ After code changes, you MUST verify UI with this flow:
37
47
  4. get_test_summary(path) โ†’ final report before completing task
38
48
  ```
39
49
 
40
- **Rule**: If `get_pending_tests()` returns items, they MUST be executed in the browser before the task is marked complete. Never skip browser verification when @test annotations exist.
41
-
42
- ### Example
43
- ```javascript
44
- /**
45
- * Delete selected persona
46
- *
47
- * @test click: Click delete button on persona card
48
- * @test click: Confirm in dialog
49
- * @expect element: Persona removed from list
50
- * @expect visual: Toast notification appears
51
- */
52
- async onDeletePersona() { ... }
53
- ```
50
+ **Rule**: If `get_pending_tests()` returns items, they MUST be executed before the task is marked complete.
51
+
52
+ > **Note**: Test state is persistent (written to files) and survives agent session restarts.
54
53
 
55
54
  ## ๐Ÿ—„๏ธ Database Analysis
56
55
  | Tool | Purpose |
@@ -71,16 +70,72 @@ The graph automatically detects SQL queries in your code:
71
70
  - Column-level dead code detection is best-effort.
72
71
  - ORM-specific patterns (Prisma, Sequelize, Knex query builder) are not yet supported.
73
72
 
73
+ ## ๐Ÿง  AI Context Layer
74
+ | Tool | Purpose |
75
+ |------|---------|
76
+ | `get_ai_context` | **Boot**: skeleton + docs + compressed files in one call |
77
+ | `get_compressed_file` | Terser-minified source with export legend |
78
+ | `get_project_docs` | Doc Dialect documentation (auto + manual .context/) |
79
+ | `generate_context_docs` | Generate .context/ templates from AST (batch concurrent) |
80
+ | `check_stale_docs` | Detect outdated .ctx files by @sig hash |
81
+ | `discover_sub_projects` | Find sub-projects in monorepo (packages/apps/services/...) |
82
+ | `get_analysis_summary` | Quick health score โ€” cached metrics only, skips cross-file |
83
+ | `compact_project` | Compact all JS files โ€” strips comments/whitespace (mangle:false) |
84
+ | `beautify_project` | Beautify/expand all JS files โ€” inverse of compact |
85
+
86
+ ### AI-First Workflow
87
+ 1. **Boot**: `get_ai_context(path)` โ€” loads skeleton + docs (~1700 tokens vs ~60K original)
88
+ 2. **Drill**: `expand(symbol)` or `get_compressed_file(file)` โ€” go deeper when needed
89
+ 3. **Enrich**: `generate_context_docs(path)` creates `.context/*.ctx` with `{DESCRIBE}` markers. Fill them with compact descriptions.
90
+
91
+ ### Doc Dialect Storage (Two-Tier)
92
+ `.context/` mirrors your source tree with two files per source:
93
+ ```
94
+ .context/ โ† auto-generated (mirror)
95
+ โ”œโ”€โ”€ project.ctx
96
+ โ”œโ”€โ”€ parser.ctx โ† Machine zone: AST signatures, @sig
97
+ โ”œโ”€โ”€ parser.ctx.md โ† Agent zone: notes, TODO, decisions
98
+ โ””โ”€โ”€ utils/
99
+ โ””โ”€โ”€ helpers.ctx
100
+
101
+ src/
102
+ โ”œโ”€โ”€ parser.js
103
+ โ”œโ”€โ”€ parser.ctx โ† colocated override (wins!)
104
+ โ””โ”€โ”€ utils/
105
+ โ””โ”€โ”€ helpers.js
106
+ ```
107
+
108
+ ### Doc Dialect Format
109
+ `.context/` files use a compact pipe-separated format:
110
+ ```
111
+ --- parser.js ---
112
+ export parseProject()โ†’resolve,findJSFiles,readFileSync|scans dir, parses all files
113
+ parseFileByExtension()โ†’parseSQL,parsePython,parseGo|routes by extension
114
+ PATTERNS: lang-*.js for non-JS|regex fallback for Python
115
+ EDGE_CASES: Python uses regex, not AST|Go interfaces โ‰  classes
116
+ ```
117
+
118
+ ### Enrichment Workflow
119
+ | Step | How |
120
+ |------|-----|
121
+ | 1. Generate | `generate_context_docs` creates templates with `{DESCRIBE}` markers + `@sig` hash |
122
+ | 2. Enrich | Delegate to agent-pool: `delegate_task({ skill: "doc-enricher" })` |
123
+ | 3. Monitor | `check_stale_docs` detects when source changes invalidate docs |
124
+ | 4. Update | Regenerate with `overwrite: true` โ€” existing descriptions are preserved |
125
+
74
126
  ## ๐Ÿ” Code Quality Analysis
75
127
  | Tool | Purpose |
76
128
  |------|---------|
77
129
  | `get_full_analysis` | Run ALL checks + Health Score (0-100) |
130
+ | `get_analysis_summary` | Quick health score (cached only, fast) |
78
131
  | `get_dead_code` | Find unused functions/classes |
79
132
  | `get_undocumented` | Find missing JSDoc |
80
133
  | `get_similar_functions` | Detect code duplicates |
81
134
  | `get_complexity` | Cyclomatic complexity metrics |
82
135
  | `get_large_files` | Files needing split |
83
136
  | `get_outdated_patterns` | Legacy patterns + redundant npm deps |
137
+ | `check_jsdoc_consistency` | Validate JSDoc โ†” AST signatures |
138
+ | `check_types` | Optional tsc type checking (requires TypeScript) |
84
139
  | `generate_jsdoc` | Auto-generate JSDoc templates |
85
140
 
86
141
  ## ๐Ÿ”ง Custom Rules (Configurable)
@@ -96,11 +151,11 @@ Rules are applied automatically based on:
96
151
  - Import patterns in source code
97
152
  - Code patterns (e.g., `extends Symbiote`)
98
153
 
99
- ### Pre-built Rulesets (85 rules)
154
+ ### Pre-built Rulesets (86 rules)
100
155
  | Ruleset | Rules | Framework |
101
156
  |---------|-------|-----------|
102
157
  | `symbiote-2x` | 12 | Symbiote.js 2.x |
103
- | `symbiote-3x` | 17 | Symbiote.js 3.x |
158
+ | `symbiote-3x` | 18 | Symbiote.js 3.x |
104
159
  | `react-18` | 6 | React 18 |
105
160
  | `react-19` | 5 | React 19 (Server Components) |
106
161
  | `vue-3` | 5 | Vue 3 Composition API |
@@ -109,7 +164,7 @@ Rules are applied automatically based on:
109
164
  | `fastify-5` | 5 | Fastify 5.x |
110
165
  | `nestjs-10` | 6 | NestJS 10.x |
111
166
  | `typescript-5` | 5 | TypeScript 5.x |
112
- | `node-22` | 7 | Node.js 22+ |
167
+ | `node-22` | 13 | Node.js 22+ |
113
168
 
114
169
  ### Creating New Rules
115
170
  Read project workflow docs (e.g., `.agent/workflows/symbiote-audit.md`) and use `set_custom_rule`:
@@ -134,12 +189,14 @@ Read project workflow docs (e.g., `.agent/workflows/symbiote-audit.md`) and use
134
189
  |------|---------|
135
190
  | `get_filters` / `set_filters` | Configure excluded directories |
136
191
  | `add_excludes` / `remove_excludes` | Modify exclude list |
192
+ | `reset_filters` | Reset to defaults |
137
193
 
138
194
  ## ๐Ÿš€ Recommended Workflow
139
195
 
140
- 1. **Start**: `get_structure` โ†’ understand project layout
141
- 2. **Dive**: `get_skeleton` โ†’ map code architecture
196
+ 1. **Boot**: `get_ai_context` โ†’ understand entire project in ~1700 tokens
197
+ 2. **Dive**: `expand` / `get_compressed_file` โ†’ drill into specific files
142
198
  3. **Analyze**: `get_full_analysis` โ†’ find issues (Health Score)
143
199
  4. **Check Rules**: `check_custom_rules` โ†’ framework-specific violations
144
200
  5. **Fix**: Address issues by severity (error โ†’ warning โ†’ info)
145
201
  6. **Verify**: `get_pending_tests` โ†’ execute in browser โ†’ `mark_test_passed/failed` โ†’ `get_test_summary`
202
+ 7. **Document**: `generate_context_docs` โ†’ enrich .ctx files with PATTERNS and EDGE_CASES
@@ -1,6 +1,6 @@
1
1
  # Project Graph MCP
2
2
 
3
- You have **Project Graph MCP** tools available โ€” code analysis, project navigation, and framework-specific linting.
3
+ You have **Project Graph MCP** tools available โ€” 45 tools for code analysis, project navigation, monorepo scanning, and framework-specific linting.
4
4
 
5
5
  ## Quick Start
6
6
 
@@ -15,9 +15,11 @@ You have **Project Graph MCP** tools available โ€” code analysis, project naviga
15
15
  - `expand(symbol)` โ€” Deep dive into class/function (use symbols from skeleton's `L` field)
16
16
  - `deps(symbol)` โ€” Dependency tree (imports, usedBy, calls)
17
17
  - `usages(symbol)` โ€” Find all usages across project
18
+ - `invalidate_cache` โ€” Refresh graph after code changes
18
19
 
19
20
  ### Code Quality
20
21
  - `get_full_analysis` โ€” Run ALL checks + Health Score
22
+ - `get_analysis_summary` โ€” Quick health score (cached only, fast)
21
23
  - `get_dead_code` โ€” Unused functions/classes
22
24
  - `get_undocumented` โ€” Missing JSDoc
23
25
  - `get_similar_functions` โ€” Code duplicates
@@ -25,10 +27,21 @@ You have **Project Graph MCP** tools available โ€” code analysis, project naviga
25
27
  - `get_large_files` โ€” Files needing split
26
28
  - `get_outdated_patterns` โ€” Legacy patterns
27
29
 
30
+ ### AI Context
31
+ - `get_ai_context` โ€” **Boot**: skeleton + docs + compressed files (~97% savings)
32
+ - `get_compressed_file` โ€” Terser-minified source with export legend
33
+ - `get_project_docs` โ€” Doc Dialect documentation (.context/)
34
+ - `generate_context_docs` โ€” Generate .context/ templates with `@sig` staleness hashes
35
+ - `check_stale_docs` โ€” Check which .ctx files need updating
36
+ - `discover_sub_projects` โ€” Find sub-projects in monorepo
37
+ - `compact_project` โ€” Compact all JS files (strips comments/whitespace, preserves names)
38
+ - `beautify_project` โ€” Beautify/expand all JS files (inverse of compact)
39
+
28
40
  ### Testing
29
- - `get_pending_tests` โ€” List @test/@expect annotations
30
- - `mark_test_passed(testId)` / `mark_test_failed(testId, reason)`
41
+ - `get_pending_tests` โ€” List `[ ]` checklists from `.ctx.md` files
42
+ - `mark_test_passed(testId)` / `mark_test_failed(testId, reason)` โ€” writes to `.ctx.md`
31
43
  - `get_test_summary` โ€” Progress report
44
+ - `reset_test_state` โ€” Reset all checklists to `[ ]`
32
45
 
33
46
  ### Custom Rules
34
47
  - `check_custom_rules(path)` โ€” Run framework-specific analysis (auto-detected)
@@ -40,11 +53,13 @@ You have **Project Graph MCP** tools available โ€” code analysis, project naviga
40
53
  ## Workflow
41
54
 
42
55
  ```
43
- 1. get_skeleton("src/") โ†’ Understand structure
44
- 2. get_full_analysis("src/") โ†’ Find issues (Health Score)
45
- 3. check_custom_rules("src/") โ†’ Framework violations
46
- 4. Fix by severity: error โ†’ warning โ†’ info
47
- 5. get_pending_tests("src/") โ†’ Verification checklist
56
+ 1. get_ai_context("src/") โ†’ Boot: ~1700 tokens for entire project
57
+ 2. expand(symbol) โ†’ Drill into specific class/function
58
+ 3. get_full_analysis("src/") โ†’ Find issues (Health Score)
59
+ 4. check_custom_rules("src/") โ†’ Framework violations
60
+ 5. Fix by severity: error โ†’ warning โ†’ info
61
+ 6. get_pending_tests("src/") โ†’ Verification checklist
62
+ 7. generate_context_docs("src/")โ†’ Enrich .ctx files
48
63
  ```
49
64
 
50
65
  ## Tips
package/README.md CHANGED
@@ -5,10 +5,10 @@
5
5
 
6
6
  # project-graph-mcp
7
7
 
8
- An MCP server that parses your source code into a **10-50x compressed skeleton** โ€” classes, functions, imports, and dependencies in a minified JSON. Agents navigate the graph using `expand`, `deps`, and `usages` without reading irrelevant files.
8
+ An MCP server that parses your source code into a **10-50x compressed skeleton** โ€” classes, functions, imports, and dependencies in a minified JSON. Agents navigate the graph using `expand`, `deps`, and `usages` without reading irrelevant files. The **AI Context Layer** compresses an entire codebase into ~1700 tokens (97% savings) with a single `get_ai_context` call. Supports **monorepo scanning** and **streaming analysis** for large codebases.
9
9
 
10
10
  > [!TIP]
11
- > **132 kB, 47 files, zero external dependencies.** Add one line to your MCP config and the server downloads itself on the next IDE restart.
11
+ > **132 kB, 47 files, zero external dependencies.** 49 MCP tools. Add one line to your MCP config and the server downloads itself on the next IDE restart.
12
12
 
13
13
  ### Project Skeleton (10-50x compression)
14
14
 
@@ -44,27 +44,107 @@ stripStringsAndComments(code, { backtick: true, templateInterpolation: false })
44
44
  - **Duplicate detection** โ€” finds functionally similar functions by signature + structure similarity
45
45
  - **Large file analysis** โ€” candidates for splitting by lines, functions, and exports count
46
46
  - **Legacy pattern finder** โ€” outdated code patterns and redundant npm deps (built into Node.js 18+)
47
- - **Health Score (0-100)** โ€” aggregated result from all checks in one call
47
+ - **JSDoc consistency** โ€” validates `@param` count/names and `@returns` against AST signatures
48
+ - **Type checking** โ€” optional `tsc --checkJs` wrapper with graceful fallback
49
+ - **Health Score (0-100)** โ€” aggregated result from all checks in one call (`get_full_analysis` or quick `get_analysis_summary`)
50
+ - **Incremental cache** โ€” per-file analysis results cached in `.context/.cache/` with content hashing
48
51
 
49
- ### Test Checklists
52
+ ### AI Context Layer
53
+
54
+ One call loads everything an agent needs to understand a project:
55
+
56
+ ```javascript
57
+ get_ai_context({ path: "src/" })
58
+ // โ†’ { skeleton, docs, totalTokens: 1742, savings: "97%" }
59
+ ```
60
+
61
+ - **Code compression** โ€” Terser-minified source with export legend headers (20-55% per file)
62
+ - **Compact Code Mode** โ€” project-wide `compact`/`beautify` (preserves all names, strips comments/whitespace)
63
+ - **Doc Dialect** โ€” compact `.context/` documentation format, auto-generated from AST with `{DESCRIBE}` markers
64
+ - **Two-tier `.ctx`** โ€” `.ctx` (machine-generated, AST signatures) + `.ctx.md` (agent notes, TODO, decisions)
65
+ - **Self-enriching** โ€” `@enrich` instructions embedded in `.ctx` files guide any AI agent to fill descriptions
66
+ - **Staleness detection** โ€” `@sig` hashes track structural changes; `check_stale_docs` identifies outdated docs
67
+ - **Merge strategy** โ€” regenerating `.ctx` files preserves existing descriptions
68
+ - **Boot aggregator** โ€” `get_ai_context` combines skeleton + docs + compressed files in one response
69
+
70
+ ```
71
+ # Generate .context/ documentation templates
72
+ npx project-graph-mcp generate-ctx src/
50
73
 
51
- JSDoc annotations (`@test` and `@expect`) define test checklists directly in the code:
74
+ # View project docs in compact format
75
+ npx project-graph-mcp docs src/
76
+
77
+ # Compress a single file for AI
78
+ npx project-graph-mcp compress src/parser.js
79
+ ```
80
+
81
+ ### Compact Code Architecture
82
+
83
+ Three modes for AI-native codebase editing โ€” configure per project via `.context/config.json`:
84
+
85
+ | Mode | Storage | Agent reads | Agent edits |
86
+ |------|---------|-------------|-------------|
87
+ | **1 โ€” Native Compact** | Minified JS | Files directly | Files directly |
88
+ | **2 โ€” Full Storage** (default) | Formatted JS | `get_compressed_file` | `edit_compressed` |
89
+ | **3 โ€” IDE Virtual** | Minified JS | IDE renders full view | IDE handles mapping |
90
+
91
+ **Mode 2 workflow** (recommended):
52
92
 
53
93
  ```javascript
54
- /**
55
- * Create new user via API
56
- *
57
- * @test request: POST /api/users with valid data
58
- * @expect status: 201 Created
59
- */
60
- async createUser(data) { ... }
94
+ // 1. Read compressed view (saves 20-55% tokens)
95
+ get_compressed_file({ path: "src/parser.js" })
96
+
97
+ // 2. Edit by symbol name โ€” server finds it via AST
98
+ edit_compressed({
99
+ path: "src/parser.js",
100
+ symbol: "parseFile",
101
+ code: "export async function parseFile(code, filename) { /* new body */ }"
102
+ })
103
+
104
+ // 3. Validate .ctx contracts after editing
105
+ validate_ctx_contracts({ path: "." })
61
106
  ```
62
107
 
63
- The agent calls `get_pending_tests`, runs the test, then `mark_test_passed`. Supports browser, API, CLI, and integration test types.
108
+ **`.ctx` typed signatures** โ€” JSDoc types extracted into compact format:
109
+
110
+ ```
111
+ parseFile(code:string,filename:string)โ†’Promise<ParseResult>โ†’parse,walk|parse JS file into AST
112
+ ```
113
+
114
+ ```bash
115
+ # Set project mode
116
+ npx project-graph-mcp set-mode . 2
117
+
118
+ # Validate .ctx documentation matches source
119
+ npx project-graph-mcp validate-ctx . --strict
120
+ ```
121
+
122
+ ### Test Checklists
123
+
124
+ Test checklists live in `.ctx.md` files (alongside documentation), not in source code:
125
+
126
+ ```markdown
127
+ ## Tests
128
+ - [ ] POST /api/users with valid data โ†’ 201 Created
129
+ - [ ] GET /api/users/:id returns user object
130
+ - [x] DELETE /api/users/:id โ†’ 204 No Content
131
+ ```
132
+
133
+ The agent calls `get_pending_tests`, runs the test, then `mark_test_passed` (which writes `[x]` directly to the `.ctx.md` file). Test state is persistent and survives session restarts.
134
+
135
+ ### Monorepo Support
136
+
137
+ `discover_sub_projects` scans standard monorepo directories (`packages/`, `apps/`, `services/`, `modules/`, `libs/`, `plugins/`) for sub-projects with `package.json`. Combined with `parseProject({ recursive: true })`, agents can analyze entire monorepos.
138
+
139
+ ### Performance
140
+
141
+ - **Batch concurrency** โ€” `generate_context_docs` processes 5 files in parallel
142
+ - **Quick health check** โ€” `get_analysis_summary` runs only cached per-file metrics (skips expensive cross-file analysis)
143
+ - **Streaming analysis** โ€” `getFullAnalysisStreaming` yields results incrementally as each sub-analysis completes
64
144
 
65
145
  ### Custom Rules & Framework References
66
146
 
67
- 10 pre-built rulesets (62 rules) for React 18/19, Vue 3, Next.js 15, Express 5, Fastify 5, NestJS 10, TypeScript 5, Node.js 22, and [Symbiote.js](https://github.com/symbiotejs/symbiote.js). The server auto-detects your project type and returns adapted documentation via `get_framework_reference`.
147
+ 11 pre-built rulesets (86 rules) for React 18/19, Vue 3, Next.js 15, Express 5, Fastify 5, NestJS 10, TypeScript 5, Node.js 22, and [Symbiote.js](https://github.com/symbiotejs/symbiote.js). The server auto-detects your project type and returns adapted documentation via `get_framework_reference`.
68
148
 
69
149
  Custom project conventions can be added in the `rules/` directory or configured by the agent via `set_custom_rule`.
70
150
 
@@ -130,6 +210,12 @@ npx project-graph-mcp deadcode src/ # Find unused code
130
210
  npx project-graph-mcp complexity src/ # Cyclomatic complexity
131
211
  npx project-graph-mcp similar src/ # Find duplicates
132
212
  npx project-graph-mcp pending src/ # List pending tests
213
+ npx project-graph-mcp compress src/f.js # Compress file for AI
214
+ npx project-graph-mcp docs src/ # Project docs (doc-dialect)
215
+ npx project-graph-mcp generate-ctx src/ # Generate .context/ docs
216
+ npx project-graph-mcp validate-ctx . # Validate .ctx โ†” source
217
+ npx project-graph-mcp mode . # Show current editing mode
218
+ npx project-graph-mcp set-mode . 2 # Set mode (1/2/3)
133
219
  npx project-graph-mcp help # All commands
134
220
  ```
135
221
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "project-graph-mcp",
3
- "version": "1.3.0",
3
+ "version": "1.5.0",
4
4
  "type": "module",
5
5
  "description": "MCP server for AI agents โ€” multi-language project graph (JS, TS, Python, Go), code quality analysis, and framework-specific lint rules. Zero dependencies.",
6
6
  "main": "src/server.js",
@@ -0,0 +1 @@
1
+ {"version":1,"path":"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src","mtimes":{"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/ai-context.js":1775705820005.593,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/analysis-cache.js":1775705820005.9824,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/cli-handlers.js":1775742844572.4338,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/cli.js":1775742927037.4722,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compact.js":1775705820007.682,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/complexity.js":1775705820008.1265,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/compress.js":1775708193583.2522,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/ctx-to-jsdoc.js":1775742405151.9907,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/custom-rules.js":1775705820009.4775,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/db-analysis.js":1775705820010.2769,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/dead-code.js":1775705820010.873,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/doc-dialect.js":1775707208614.9092,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/filters.js":1775705820011.479,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/framework-references.js":1775705820011.642,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/full-analysis.js":1775705820012.3645,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/graph-builder.js":1775705820012.8542,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/instructions.js":1775705820013.5242,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/jsdoc-checker.js":1775705820013.9524,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/jsdoc-generator.js":1775705820014.3755,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/lang-go.js":1775705820014.5596,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/lang-python.js":1775705820014.7178,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/lang-sql.js":1775705820015.08,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/lang-typescript.js":1775705820015.259,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/lang-utils.js":1775705820015.4016,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/large-files.js":1775705820015.7256,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/mcp-server.js":1775742958113.3992,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/mode-config.js":1775708353549.937,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/outdated-patterns.js":1775705820016.414,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/parser.js":1775707186671.276,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/server.js":1775705820017.2703,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/similar-functions.js":1775705820017.9243,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/test-annotations.js":1775705820018.533,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/tool-defs.js":1775708400999.8848,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/tools.js":1775705820019.4646,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/type-checker.js":1775705820019.783,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/undocumented.js":1775705820020.2156,"/Users/v.matiyasevich/Documents/GitHub/project-graph-mcp/src/workspace.js":1775705820020.5132},"graph":{"v":1,"legend":{"estimateTokens":"eT","getAiContext":"AC","computeSig":"cS","computeContentHash":"CH","getCachePath":"CP","readCache":"rC","writeCache":"wC","isCacheValid":"CV","invalidateAllCaches":"AC1","getArg":"gA","getPath":"gP","printHelp":"pH","runCLI":"CLI","walkJSFiles":"JSF","compactFile":"cF","beautifyFile":"bF","compactProject":"cP","expandProject":"eP","findJSFiles":"JSF1","calculateComplexity":"cC","getRating":"gR","analyzeComplexityFile":"CF","analyzeFile":"aF","getComplexity":"gC","extractLegend":"eL","compressFile":"cF1","editCompressed":"eC","findSymbolRange":"SR","parseCtxFile":"CF1","buildJSDocBlock":"JSD","findCtxFile":"CF2","findExportStart":"ES","injectJSDoc":"JSD1","stripJSDoc":"JSD2","splitTopLevelParams":"TLP","validateCtxContracts":"CC","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","generateDocDialect":"DD","walkCtxFiles":"CF3","resolveCtxPath":"CP1","resolveCtxMdPath":"CMP","readContextDocs":"CD","getProjectDocs":"PD","computeSignature":"cS1","parseCtxDescriptions":"CD1","checkStaleness":"cS2","buildFileTemplate":"FT","generateContextFiles":"CF4","processFileCtx":"FC","getFilters":"gF","setFilters":"sF","addExcludes":"aE","removeExcludes":"rE","resetFilters":"rF","parseGitignore":"pG1","shouldExcludeDir":"ED","shouldExcludeFile":"EF","matchWildcard":"mW","matchGitignorePattern":"GP","fetchReference":"fR","listAvailable":"lA","getFrameworkReference":"FR","calculateHealthScore":"HS","runCacheableAnalyses":"CA","aggregateComplexity":"aC","aggregateUndocumented":"aU","aggregateJSDoc":"JSD3","getFullAnalysis":"FA","getAnalysisSummaryOnly":"ASO","getFullAnalysisStreaming":"FAS","minifyLegend":"mL","createShortName":"SN","buildGraph":"bG","createSkeleton":"cS3","getInstructions":"gI","extractJSDocComments":"JSD4","findJSDocBefore":"JSD5","extractParamName":"PN","inferTypeFromDefault":"TFD","hasReturnValue":"RV","validateFunction":"vF","checkJSDocFile":"JSD6","checkJSDocConsistency":"JSD7","generateJSDoc":"JSD8","buildJSDoc":"JSD9","inferParamType":"PT","generateJSDocFor":"JSD10","parseGo":"pG2","extractImports":"eI","getBody":"gB","extractCalls":"eC1","parsePython":"pP","isSQLString":"SQL","isValidTableName":"VTN","extractSQLFromString":"SQL1","parseSQL":"SQL2","parseColumns":"pC","splitByTopLevelComma":"BTL","extractSQLFromCode":"SQL3","parseTypeScript":"TS","extractParams":"eP1","stripStringsAndComments":"SAC","getLargeFiles":"LF","createServer":"cS4","startStdioServer":"SS","getConfig":"gC1","setConfig":"sC","getModeDescription":"MD","getModeWorkflow":"MW","analyzeFilePatterns":"FP","analyzePackageJson":"PJ","getOutdatedPatterns":"OP","parseFile":"pF","extractCallsAndSQL":"CAS","getTagName":"TN","getCallMethodName":"CMN","extractStringValue":"SV","templateToString":"TS1","discoverSubProjects":"SP","parseProject":"pP1","parseFileByExtension":"FBE","isSourceFile":"SF","buildJSDocTypeMap":"JSD11","findJSDocForNode":"JSD12","enrichParamsWithTypes":"PWT","extractSignatures":"eS","buildSignature":"bS","hashBodyStructure":"BS","calculateSimilarity":"cS5","getSimilarFunctions":"SF1","findCtxMdFiles":"CMF","parseAnnotations":"pA","groupByName":"BN","getAllFeatures":"AF","getPendingTests":"PT1","markTestPassed":"TP","markTestFailed":"TF","updateTestState":"TS2","getTestSummary":"TS3","resetTestState":"TS4","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","detectTsc":"dT","parseDiagnosticLine":"DL","buildArgs":"bA","checkTypes":"cT","extractComments":"eC2","checkMissing":"cM","checkUndocumentedFile":"UF","getUndocumented":"gU","getUndocumentedSummary":"US","setRoots":"sR","getWorkspaceRoot":"WR","resolvePath":"rP"},"reverseLegend":{"eT":"estimateTokens","AC":"getAiContext","cS":"computeSig","CH":"computeContentHash","CP":"getCachePath","rC":"readCache","wC":"writeCache","CV":"isCacheValid","AC1":"invalidateAllCaches","gA":"getArg","gP":"getPath","pH":"printHelp","CLI":"runCLI","JSF":"walkJSFiles","cF":"compactFile","bF":"beautifyFile","cP":"compactProject","eP":"expandProject","JSF1":"findJSFiles","cC":"calculateComplexity","gR":"getRating","CF":"analyzeComplexityFile","aF":"analyzeFile","gC":"getComplexity","eL":"extractLegend","cF1":"compressFile","eC":"editCompressed","SR":"findSymbolRange","CF1":"parseCtxFile","JSD":"buildJSDocBlock","CF2":"findCtxFile","ES":"findExportStart","JSD1":"injectJSDoc","JSD2":"stripJSDoc","TLP":"splitTopLevelParams","CC":"validateCtxContracts","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","DD":"generateDocDialect","CF3":"walkCtxFiles","CP1":"resolveCtxPath","CMP":"resolveCtxMdPath","CD":"readContextDocs","PD":"getProjectDocs","cS1":"computeSignature","CD1":"parseCtxDescriptions","cS2":"checkStaleness","FT":"buildFileTemplate","CF4":"generateContextFiles","FC":"processFileCtx","gF":"getFilters","sF":"setFilters","aE":"addExcludes","rE":"removeExcludes","rF":"resetFilters","pG1":"parseGitignore","ED":"shouldExcludeDir","EF":"shouldExcludeFile","mW":"matchWildcard","GP":"matchGitignorePattern","fR":"fetchReference","lA":"listAvailable","FR":"getFrameworkReference","HS":"calculateHealthScore","CA":"runCacheableAnalyses","aC":"aggregateComplexity","aU":"aggregateUndocumented","JSD3":"aggregateJSDoc","FA":"getFullAnalysis","ASO":"getAnalysisSummaryOnly","FAS":"getFullAnalysisStreaming","mL":"minifyLegend","SN":"createShortName","bG":"buildGraph","cS3":"createSkeleton","gI":"getInstructions","JSD4":"extractJSDocComments","JSD5":"findJSDocBefore","PN":"extractParamName","TFD":"inferTypeFromDefault","RV":"hasReturnValue","vF":"validateFunction","JSD6":"checkJSDocFile","JSD7":"checkJSDocConsistency","JSD8":"generateJSDoc","JSD9":"buildJSDoc","PT":"inferParamType","JSD10":"generateJSDocFor","pG2":"parseGo","eI":"extractImports","gB":"getBody","eC1":"extractCalls","pP":"parsePython","SQL":"isSQLString","VTN":"isValidTableName","SQL1":"extractSQLFromString","SQL2":"parseSQL","pC":"parseColumns","BTL":"splitByTopLevelComma","SQL3":"extractSQLFromCode","TS":"parseTypeScript","eP1":"extractParams","SAC":"stripStringsAndComments","LF":"getLargeFiles","cS4":"createServer","SS":"startStdioServer","gC1":"getConfig","sC":"setConfig","MD":"getModeDescription","MW":"getModeWorkflow","FP":"analyzeFilePatterns","PJ":"analyzePackageJson","OP":"getOutdatedPatterns","pF":"parseFile","CAS":"extractCallsAndSQL","TN":"getTagName","CMN":"getCallMethodName","SV":"extractStringValue","TS1":"templateToString","SP":"discoverSubProjects","pP1":"parseProject","FBE":"parseFileByExtension","SF":"isSourceFile","JSD11":"buildJSDocTypeMap","JSD12":"findJSDocForNode","PWT":"enrichParamsWithTypes","eS":"extractSignatures","bS":"buildSignature","BS":"hashBodyStructure","cS5":"calculateSimilarity","SF1":"getSimilarFunctions","CMF":"findCtxMdFiles","pA":"parseAnnotations","BN":"groupByName","AF":"getAllFeatures","PT1":"getPendingTests","TP":"markTestPassed","TF":"markTestFailed","TS2":"updateTestState","TS3":"getTestSummary","TS4":"resetTestState","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","dT":"detectTsc","DL":"parseDiagnosticLine","bA":"buildArgs","cT":"checkTypes","eC2":"extractComments","cM":"checkMissing","UF":"checkUndocumentedFile","gU":"getUndocumented","US":"getUndocumentedSummary","sR":"setRoots","WR":"getWorkspaceRoot","rP":"resolvePath"},"stats":{"files":37,"classes":0,"functions":200,"tables":0},"nodes":{"eT":{"t":"F","e":false,"f":"compress.js"},"AC":{"t":"F","e":true,"f":"ai-context.js"},"cS":{"t":"F","e":true,"f":"analysis-cache.js"},"CH":{"t":"F","e":true,"f":"analysis-cache.js"},"CP":{"t":"F","e":true,"f":"analysis-cache.js"},"rC":{"t":"F","e":true,"f":"analysis-cache.js"},"wC":{"t":"F","e":true,"f":"analysis-cache.js"},"CV":{"t":"F","e":true,"f":"analysis-cache.js"},"AC1":{"t":"F","e":true,"f":"analysis-cache.js"},"gA":{"t":"F","e":false,"f":"cli-handlers.js"},"gP":{"t":"F","e":false,"f":"cli-handlers.js"},"pH":{"t":"F","e":true,"f":"cli.js"},"CLI":{"t":"F","e":true,"f":"cli.js"},"JSF":{"t":"F","e":false,"f":"ctx-to-jsdoc.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":"compact.js"},"JSF1":{"t":"F","e":false,"f":"undocumented.js"},"cC":{"t":"F","e":false,"f":"complexity.js"},"gR":{"t":"F","e":false,"f":"complexity.js"},"CF":{"t":"F","e":true,"f":"complexity.js"},"aF":{"t":"F","e":false,"f":"large-files.js"},"gC":{"t":"F","e":true,"f":"complexity.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"},"CF1":{"t":"F","e":true,"f":"ctx-to-jsdoc.js"},"JSD":{"t":"F","e":false,"f":"ctx-to-jsdoc.js"},"CF2":{"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"},"pG":{"t":"F","e":false,"f":"custom-rules.js"},"iG":{"t":"F","e":false,"f":"custom-rules.js"},"RS":{"t":"F","e":false,"f":"custom-rules.js"},"RS1":{"t":"F","e":false,"f":"custom-rules.js"},"fF":{"t":"F","e":false,"f":"custom-rules.js"},"iE":{"t":"F","e":false,"f":"custom-rules.js"},"ISO":{"t":"F","e":false,"f":"custom-rules.js"},"WC":{"t":"F","e":false,"f":"custom-rules.js"},"FAR":{"t":"F","e":false,"f":"custom-rules.js"},"CR":{"t":"F","e":true,"f":"custom-rules.js"},"CR1":{"t":"F","e":true,"f":"custom-rules.js"},"CR2":{"t":"F","e":true,"f":"custom-rules.js"},"PRS":{"t":"F","e":true,"f":"custom-rules.js"},"CR3":{"t":"F","e":true,"f":"custom-rules.js"},"DBS":{"t":"F","e":true,"f":"db-analysis.js"},"TU":{"t":"F","e":true,"f":"db-analysis.js"},"DBD":{"t":"F","e":true,"f":"db-analysis.js"},"RC":{"t":"F","e":false,"f":"db-analysis.js"},"PR":{"t":"F","e":false,"f":"dead-code.js"},"FL":{"t":"F","e":false,"f":"dead-code.js"},"DC":{"t":"F","e":true,"f":"dead-code.js"},"DD":{"t":"F","e":true,"f":"doc-dialect.js"},"CF3":{"t":"F","e":false,"f":"doc-dialect.js"},"CP1":{"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"},"cS1":{"t":"F","e":false,"f":"doc-dialect.js"},"CD1":{"t":"F","e":false,"f":"doc-dialect.js"},"cS2":{"t":"F","e":true,"f":"doc-dialect.js"},"FT":{"t":"F","e":false,"f":"doc-dialect.js"},"CF4":{"t":"F","e":true,"f":"doc-dialect.js"},"FC":{"t":"F","e":false,"f":"doc-dialect.js"},"gF":{"t":"F","e":true,"f":"filters.js"},"sF":{"t":"F","e":true,"f":"filters.js"},"aE":{"t":"F","e":true,"f":"filters.js"},"rE":{"t":"F","e":true,"f":"filters.js"},"rF":{"t":"F","e":true,"f":"filters.js"},"pG1":{"t":"F","e":true,"f":"filters.js"},"ED":{"t":"F","e":true,"f":"filters.js"},"EF":{"t":"F","e":true,"f":"filters.js"},"mW":{"t":"F","e":false,"f":"filters.js"},"GP":{"t":"F","e":false,"f":"filters.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"},"HS":{"t":"F","e":false,"f":"full-analysis.js"},"CA":{"t":"F","e":false,"f":"full-analysis.js"},"aC":{"t":"F","e":false,"f":"full-analysis.js"},"aU":{"t":"F","e":false,"f":"full-analysis.js"},"JSD3":{"t":"F","e":false,"f":"full-analysis.js"},"FA":{"t":"F","e":true,"f":"full-analysis.js"},"ASO":{"t":"F","e":true,"f":"full-analysis.js"},"FAS":{"t":"F","e":true,"f":"full-analysis.js"},"mL":{"t":"F","e":true,"f":"graph-builder.js"},"SN":{"t":"F","e":false,"f":"graph-builder.js"},"bG":{"t":"F","e":true,"f":"graph-builder.js"},"cS3":{"t":"F","e":true,"f":"graph-builder.js"},"gI":{"t":"F","e":true,"f":"instructions.js"},"JSD4":{"t":"F","e":false,"f":"jsdoc-checker.js"},"JSD5":{"t":"F","e":false,"f":"undocumented.js"},"PN":{"t":"F","e":false,"f":"similar-functions.js"},"TFD":{"t":"F","e":false,"f":"jsdoc-checker.js"},"RV":{"t":"F","e":false,"f":"jsdoc-checker.js"},"vF":{"t":"F","e":false,"f":"jsdoc-checker.js"},"JSD6":{"t":"F","e":true,"f":"jsdoc-checker.js"},"JSD7":{"t":"F","e":true,"f":"jsdoc-checker.js"},"JSD8":{"t":"F","e":true,"f":"jsdoc-generator.js"},"JSD9":{"t":"F","e":false,"f":"jsdoc-generator.js"},"PT":{"t":"F","e":false,"f":"jsdoc-generator.js"},"JSD10":{"t":"F","e":true,"f":"jsdoc-generator.js"},"pG2":{"t":"F","e":true,"f":"lang-go.js"},"eI":{"t":"F","e":false,"f":"lang-go.js"},"gB":{"t":"F","e":false,"f":"lang-go.js"},"eC1":{"t":"F","e":false,"f":"lang-go.js"},"pP":{"t":"F","e":true,"f":"lang-python.js"},"SQL":{"t":"F","e":true,"f":"lang-sql.js"},"VTN":{"t":"F","e":false,"f":"lang-sql.js"},"SQL1":{"t":"F","e":true,"f":"lang-sql.js"},"SQL2":{"t":"F","e":true,"f":"lang-sql.js"},"pC":{"t":"F","e":false,"f":"lang-sql.js"},"BTL":{"t":"F","e":false,"f":"lang-sql.js"},"SQL3":{"t":"F","e":true,"f":"lang-sql.js"},"TS":{"t":"F","e":true,"f":"lang-typescript.js"},"eP1":{"t":"F","e":false,"f":"lang-typescript.js"},"SAC":{"t":"F","e":true,"f":"lang-utils.js"},"LF":{"t":"F","e":true,"f":"large-files.js"},"cS4":{"t":"F","e":true,"f":"mcp-server.js"},"SS":{"t":"F","e":true,"f":"mcp-server.js"},"gC1":{"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"},"FP":{"t":"F","e":false,"f":"outdated-patterns.js"},"PJ":{"t":"F","e":false,"f":"outdated-patterns.js"},"OP":{"t":"F","e":true,"f":"outdated-patterns.js"},"pF":{"t":"F","e":true,"f":"parser.js"},"CAS":{"t":"F","e":false,"f":"parser.js"},"TN":{"t":"F","e":false,"f":"parser.js"},"CMN":{"t":"F","e":false,"f":"parser.js"},"SV":{"t":"F","e":false,"f":"parser.js"},"TS1":{"t":"F","e":false,"f":"parser.js"},"SP":{"t":"F","e":true,"f":"parser.js"},"pP1":{"t":"F","e":true,"f":"parser.js"},"FBE":{"t":"F","e":false,"f":"parser.js"},"SF":{"t":"F","e":false,"f":"parser.js"},"JSD11":{"t":"F","e":false,"f":"parser.js"},"JSD12":{"t":"F","e":false,"f":"parser.js"},"PWT":{"t":"F","e":false,"f":"parser.js"},"eS":{"t":"F","e":false,"f":"similar-functions.js"},"bS":{"t":"F","e":false,"f":"similar-functions.js"},"BS":{"t":"F","e":false,"f":"similar-functions.js"},"cS5":{"t":"F","e":false,"f":"similar-functions.js"},"SF1":{"t":"F","e":true,"f":"similar-functions.js"},"CMF":{"t":"F","e":false,"f":"test-annotations.js"},"pA":{"t":"F","e":true,"f":"test-annotations.js"},"BN":{"t":"F","e":false,"f":"test-annotations.js"},"AF":{"t":"F","e":true,"f":"test-annotations.js"},"PT1":{"t":"F","e":true,"f":"test-annotations.js"},"TP":{"t":"F","e":true,"f":"test-annotations.js"},"TF":{"t":"F","e":true,"f":"test-annotations.js"},"TS2":{"t":"F","e":false,"f":"test-annotations.js"},"TS3":{"t":"F","e":true,"f":"test-annotations.js"},"TS4":{"t":"F","e":true,"f":"test-annotations.js"},"DC1":{"t":"F","e":false,"f":"tools.js"},"DC2":{"t":"F","e":false,"f":"tools.js"},"gG":{"t":"F","e":true,"f":"tools.js"},"dC":{"t":"F","e":false,"f":"tools.js"},"sM":{"t":"F","e":false,"f":"tools.js"},"gS":{"t":"F","e":true,"f":"tools.js"},"FZ":{"t":"F","e":true,"f":"tools.js"},"ex":{"t":"F","e":true,"f":"tools.js"},"de":{"t":"F","e":true,"f":"tools.js"},"us":{"t":"F","e":true,"f":"tools.js"},"eM":{"t":"F","e":false,"f":"tools.js"},"CC1":{"t":"F","e":true,"f":"tools.js"},"iC":{"t":"F","e":true,"f":"tools.js"},"dT":{"t":"F","e":false,"f":"type-checker.js"},"DL":{"t":"F","e":false,"f":"type-checker.js"},"bA":{"t":"F","e":false,"f":"type-checker.js"},"cT":{"t":"F","e":true,"f":"type-checker.js"},"eC2":{"t":"F","e":false,"f":"undocumented.js"},"cM":{"t":"F","e":false,"f":"undocumented.js"},"UF":{"t":"F","e":true,"f":"undocumented.js"},"gU":{"t":"F","e":true,"f":"undocumented.js"},"US":{"t":"F","e":true,"f":"undocumented.js"},"sR":{"t":"F","e":true,"f":"workspace.js"},"WR":{"t":"F","e":true,"f":"workspace.js"},"rP":{"t":"F","e":true,"f":"workspace.js"}},"edges":[],"orphans":["estimateTokens","getArg","getPath","walkJSFiles","compactFile","beautifyFile","findJSFiles","calculateComplexity","getRating","analyzeFile","extractLegend","findSymbolRange","buildJSDocBlock","findCtxFile","findExportStart","splitTopLevelParams","parseGraphignore","isGraphignored","loadRuleSets","saveRuleSet","findFiles","isExcluded","isInStringOrComment","isWithinContext","checkFileAgainstRule","collectReferencedColumns","findProjectRoot","analyzeFileLocals","walkCtxFiles","resolveCtxPath","resolveCtxMdPath","computeSignature","parseCtxDescriptions","buildFileTemplate","processFileCtx","matchWildcard","matchGitignorePattern","fetchReference","listAvailable","calculateHealthScore","runCacheableAnalyses","aggregateComplexity","aggregateUndocumented","aggregateJSDoc","createShortName","extractJSDocComments","findJSDocBefore","extractParamName","inferTypeFromDefault","hasReturnValue","validateFunction","buildJSDoc","inferParamType","extractImports","getBody","extractCalls","isValidTableName","parseColumns","splitByTopLevelComma","extractParams","analyzeFilePatterns","analyzePackageJson","extractCallsAndSQL","getTagName","getCallMethodName","extractStringValue","templateToString","parseFileByExtension","isSourceFile","buildJSDocTypeMap","findJSDocForNode","enrichParamsWithTypes","extractSignatures","buildSignature","hashBodyStructure","calculateSimilarity","findCtxMdFiles","groupByName","updateTestState","saveDiskCache","loadDiskCache","detectChanges","snapshotMtimes","extractMethod","detectTsc","parseDiagnosticLine","buildArgs","extractComments","checkMissing"],"duplicates":{},"files":["ai-context.js","analysis-cache.js","cli-handlers.js","cli.js","compact.js","complexity.js","compress.js","ctx-to-jsdoc.js","custom-rules.js","db-analysis.js","dead-code.js","doc-dialect.js","filters.js","framework-references.js","full-analysis.js","graph-builder.js","instructions.js","jsdoc-checker.js","jsdoc-generator.js","lang-go.js","lang-python.js","lang-sql.js","lang-typescript.js","lang-utils.js","large-files.js","mcp-server.js","mode-config.js","outdated-patterns.js","parser.js","server.js","similar-functions.js","test-annotations.js","tool-defs.js","tools.js","type-checker.js","undocumented.js","workspace.js"]}}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * AI Context Boot โ€” Single-call agent bootstrap
3
+ *
4
+ * Combines skeleton + doc-dialect + optional compressed files
5
+ * into one response for AI agent initialization.
6
+ */
7
+
8
+ import { resolve, extname } from 'path';
9
+ import { getSkeleton, getGraph } from './tools.js';
10
+ import { getProjectDocs } from './doc-dialect.js';
11
+ import { compressFile } from './compress.js';
12
+ import { findJSFiles } from './parser.js';
13
+
14
+ /** Supported extensions for compression */
15
+ const COMPRESSIBLE = new Set(['.js', '.mjs', '.ts', '.tsx']);
16
+
17
+ /**
18
+ * Estimate tokens for any value (string or object)
19
+ * @param {*} value
20
+ * @returns {number}
21
+ */
22
+ function estimateTokens(value) {
23
+ const str = typeof value === 'string' ? value : JSON.stringify(value);
24
+ return Math.ceil(str.length / 4);
25
+ }
26
+
27
+ /**
28
+ * Load complete AI context for agent bootstrap
29
+ * @param {string} dirPath - Project directory
30
+ * @param {Object} [options]
31
+ * @param {string[]} [options.includeFiles] - Specific files to include compressed
32
+ * @param {boolean} [options.includeDocs=true] - Include doc-dialect
33
+ * @param {boolean} [options.includeSkeleton=true] - Include skeleton
34
+ * @returns {Promise<{skeleton?: Object, docs?: string, files?: Object, totalTokens: number, vsOriginal: number, savings: string}>}
35
+ */
36
+ export async function getAiContext(dirPath, options = {}) {
37
+ const {
38
+ includeFiles = [],
39
+ includeDocs = true,
40
+ includeSkeleton = true,
41
+ } = options;
42
+
43
+ const projectPath = resolve(dirPath);
44
+ const result = {};
45
+ let totalTokens = 0;
46
+
47
+ // 1. Skeleton
48
+ if (includeSkeleton) {
49
+ result.skeleton = await getSkeleton(projectPath);
50
+ totalTokens += estimateTokens(result.skeleton);
51
+ }
52
+
53
+ // 2. Doc Dialect
54
+ if (includeDocs) {
55
+ const graph = await getGraph(projectPath);
56
+ result.docs = getProjectDocs(graph, projectPath);
57
+ totalTokens += estimateTokens(result.docs);
58
+ }
59
+
60
+ // 3. Compressed files
61
+ if (includeFiles.length > 0) {
62
+ result.files = {};
63
+ const allFiles = findJSFiles(projectPath);
64
+
65
+ for (const requestedFile of includeFiles) {
66
+ // Find matching file (by name or path)
67
+ const match = allFiles.find(f =>
68
+ f.endsWith(requestedFile) || f.endsWith('/' + requestedFile)
69
+ );
70
+
71
+ if (!match) {
72
+ result.files[requestedFile] = { error: `File not found: ${requestedFile}` };
73
+ continue;
74
+ }
75
+
76
+ const ext = extname(match).toLowerCase();
77
+ if (!COMPRESSIBLE.has(ext)) {
78
+ result.files[requestedFile] = { error: `Unsupported file type: ${ext}` };
79
+ continue;
80
+ }
81
+
82
+ try {
83
+ const compressed = await compressFile(match, { beautify: true, legend: true });
84
+ result.files[requestedFile] = compressed.code;
85
+ totalTokens += compressed.compressed;
86
+ } catch (e) {
87
+ result.files[requestedFile] = { error: e.message };
88
+ }
89
+ }
90
+ }
91
+
92
+ // Estimate original size for savings calculation
93
+ const allFiles = findJSFiles(projectPath);
94
+ let vsOriginal = 0;
95
+ for (const file of allFiles) {
96
+ try {
97
+ const { readFileSync } = await import('fs');
98
+ vsOriginal += estimateTokens(readFileSync(file, 'utf-8'));
99
+ } catch {
100
+ // skip unreadable
101
+ }
102
+ }
103
+
104
+ const savings = vsOriginal > 0
105
+ ? Math.round((1 - totalTokens / vsOriginal) * 100)
106
+ : 0;
107
+
108
+ result.totalTokens = totalTokens;
109
+ result.vsOriginal = vsOriginal;
110
+ result.savings = `${savings}%`;
111
+
112
+ return result;
113
+ }