@laitszkin/apollo-toolkit 4.0.11 → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/AGENTS.md +37 -27
  2. package/CHANGELOG.md +47 -0
  3. package/CLAUDE.md +37 -27
  4. package/README.md +15 -2
  5. package/assets/spec/rg13-1780435029246/test-questions.json +1 -0
  6. package/assets/spec/rg13-1780468345132/test-questions.json +1 -0
  7. package/package.json +3 -3
  8. package/packages/cli/dist/tool-registration.js +1 -0
  9. package/packages/cli/dist/tsconfig.tsbuildinfo +1 -1
  10. package/packages/cli/tool-registration.ts +1 -0
  11. package/packages/tools/architecture/dist/index.js +549 -2
  12. package/packages/tools/architecture/dist/index.test.d.ts +1 -0
  13. package/packages/tools/architecture/dist/index.test.js +229 -0
  14. package/packages/tools/architecture/dist/tsconfig.tsbuildinfo +1 -1
  15. package/packages/tools/architecture/index.test.ts +329 -0
  16. package/packages/tools/architecture/index.ts +613 -5
  17. package/packages/tools/codegraph/dist/index.d.ts +3 -0
  18. package/packages/tools/codegraph/dist/index.js +343 -0
  19. package/packages/tools/codegraph/dist/lib/cg-instance.d.ts +29 -0
  20. package/packages/tools/codegraph/dist/lib/cg-instance.js +59 -0
  21. package/packages/tools/codegraph/dist/lib/cg-instance.test.d.ts +1 -0
  22. package/packages/tools/codegraph/dist/lib/cg-instance.test.js +27 -0
  23. package/packages/tools/codegraph/dist/lib/cmd-explore.d.ts +5 -0
  24. package/packages/tools/codegraph/dist/lib/cmd-explore.js +95 -0
  25. package/packages/tools/codegraph/dist/lib/cmd-explore.test.d.ts +1 -0
  26. package/packages/tools/codegraph/dist/lib/cmd-explore.test.js +133 -0
  27. package/packages/tools/codegraph/dist/lib/cmd-flag-splice.test.d.ts +1 -0
  28. package/packages/tools/codegraph/dist/lib/cmd-flag-splice.test.js +83 -0
  29. package/packages/tools/codegraph/dist/lib/cmd-init.d.ts +5 -0
  30. package/packages/tools/codegraph/dist/lib/cmd-init.js +50 -0
  31. package/packages/tools/codegraph/dist/lib/cmd-init.test.d.ts +1 -0
  32. package/packages/tools/codegraph/dist/lib/cmd-init.test.js +51 -0
  33. package/packages/tools/codegraph/dist/lib/cmd-list-apis.d.ts +5 -0
  34. package/packages/tools/codegraph/dist/lib/cmd-list-apis.js +64 -0
  35. package/packages/tools/codegraph/dist/lib/cmd-list-apis.test.d.ts +1 -0
  36. package/packages/tools/codegraph/dist/lib/cmd-list-apis.test.js +69 -0
  37. package/packages/tools/codegraph/dist/lib/cmd-search.d.ts +5 -0
  38. package/packages/tools/codegraph/dist/lib/cmd-search.js +21 -0
  39. package/packages/tools/codegraph/dist/lib/cmd-search.test.d.ts +1 -0
  40. package/packages/tools/codegraph/dist/lib/cmd-search.test.js +30 -0
  41. package/packages/tools/codegraph/dist/lib/cmd-status.d.ts +4 -0
  42. package/packages/tools/codegraph/dist/lib/cmd-status.js +44 -0
  43. package/packages/tools/codegraph/dist/lib/cmd-status.test.d.ts +1 -0
  44. package/packages/tools/codegraph/dist/lib/cmd-status.test.js +72 -0
  45. package/packages/tools/codegraph/dist/lib/cmd-survey.d.ts +36 -0
  46. package/packages/tools/codegraph/dist/lib/cmd-survey.js +142 -0
  47. package/packages/tools/codegraph/dist/lib/cmd-survey.test.d.ts +1 -0
  48. package/packages/tools/codegraph/dist/lib/cmd-survey.test.js +136 -0
  49. package/packages/tools/codegraph/dist/lib/cmd-sync.d.ts +4 -0
  50. package/packages/tools/codegraph/dist/lib/cmd-sync.js +51 -0
  51. package/packages/tools/codegraph/dist/lib/cmd-sync.test.d.ts +1 -0
  52. package/packages/tools/codegraph/dist/lib/cmd-sync.test.js +30 -0
  53. package/packages/tools/codegraph/dist/lib/cmd-verify.d.ts +4 -0
  54. package/packages/tools/codegraph/dist/lib/cmd-verify.js +134 -0
  55. package/packages/tools/codegraph/dist/lib/cmd-verify.test.d.ts +1 -0
  56. package/packages/tools/codegraph/dist/lib/cmd-verify.test.js +139 -0
  57. package/packages/tools/codegraph/dist/lib/formatter.d.ts +67 -0
  58. package/packages/tools/codegraph/dist/lib/formatter.js +107 -0
  59. package/packages/tools/codegraph/dist/lib/formatter.test.d.ts +1 -0
  60. package/packages/tools/codegraph/dist/lib/formatter.test.js +41 -0
  61. package/packages/tools/codegraph/dist/lib/survey/grouper.d.ts +19 -0
  62. package/packages/tools/codegraph/dist/lib/survey/grouper.js +194 -0
  63. package/packages/tools/codegraph/dist/lib/survey/grouper.test.d.ts +1 -0
  64. package/packages/tools/codegraph/dist/lib/survey/grouper.test.js +62 -0
  65. package/packages/tools/codegraph/dist/lib/survey/scanner.d.ts +31 -0
  66. package/packages/tools/codegraph/dist/lib/survey/scanner.js +50 -0
  67. package/packages/tools/codegraph/dist/lib/verify/checker.d.ts +32 -0
  68. package/packages/tools/codegraph/dist/lib/verify/checker.js +146 -0
  69. package/packages/tools/codegraph/dist/lib/verify/checker.test.d.ts +1 -0
  70. package/packages/tools/codegraph/dist/lib/verify/checker.test.js +128 -0
  71. package/packages/tools/codegraph/dist/tsconfig.tsbuildinfo +1 -0
  72. package/packages/tools/codegraph/env.d.ts +56 -0
  73. package/packages/tools/codegraph/index.ts +362 -0
  74. package/packages/tools/codegraph/lib/cg-instance.test.ts +36 -0
  75. package/packages/tools/codegraph/lib/cg-instance.ts +66 -0
  76. package/packages/tools/codegraph/lib/cmd-explore.test.ts +195 -0
  77. package/packages/tools/codegraph/lib/cmd-explore.ts +129 -0
  78. package/packages/tools/codegraph/lib/cmd-flag-splice.test.ts +94 -0
  79. package/packages/tools/codegraph/lib/cmd-init.test.ts +68 -0
  80. package/packages/tools/codegraph/lib/cmd-init.ts +60 -0
  81. package/packages/tools/codegraph/lib/cmd-list-apis.test.ts +80 -0
  82. package/packages/tools/codegraph/lib/cmd-list-apis.ts +90 -0
  83. package/packages/tools/codegraph/lib/cmd-search.test.ts +37 -0
  84. package/packages/tools/codegraph/lib/cmd-search.ts +32 -0
  85. package/packages/tools/codegraph/lib/cmd-status.test.ts +86 -0
  86. package/packages/tools/codegraph/lib/cmd-status.ts +53 -0
  87. package/packages/tools/codegraph/lib/cmd-survey.test.ts +161 -0
  88. package/packages/tools/codegraph/lib/cmd-survey.ts +199 -0
  89. package/packages/tools/codegraph/lib/cmd-sync.test.ts +41 -0
  90. package/packages/tools/codegraph/lib/cmd-sync.ts +62 -0
  91. package/packages/tools/codegraph/lib/cmd-verify.test.ts +162 -0
  92. package/packages/tools/codegraph/lib/cmd-verify.ts +145 -0
  93. package/packages/tools/codegraph/lib/formatter.test.ts +47 -0
  94. package/packages/tools/codegraph/lib/formatter.ts +130 -0
  95. package/packages/tools/codegraph/lib/survey/grouper.test.ts +72 -0
  96. package/packages/tools/codegraph/lib/survey/grouper.ts +226 -0
  97. package/packages/tools/codegraph/lib/survey/scanner.ts +89 -0
  98. package/packages/tools/codegraph/lib/verify/checker.test.ts +140 -0
  99. package/packages/tools/codegraph/lib/verify/checker.ts +172 -0
  100. package/packages/tools/codegraph/package.json +23 -0
  101. package/packages/tools/codegraph/tsconfig.json +22 -0
  102. package/resources/project-architecture/atlas/atlas.history.log +32 -0
  103. package/resources/project-architecture/atlas/atlas.history.undo.json +356 -28
  104. package/resources/project-architecture/atlas/atlas.history.undo.stack.json +14350 -0
  105. package/resources/project-architecture/atlas/atlas.index.yaml +76 -12
  106. package/resources/project-architecture/atlas/features/codegraph.yaml +95 -0
  107. package/resources/project-architecture/atlas/features/eval-ci-gate.yaml +6 -1
  108. package/resources/project-architecture/atlas/features/eval-cli.yaml +16 -1
  109. package/resources/project-architecture/atlas/features/eval-executor.yaml +12 -2
  110. package/resources/project-architecture/atlas/features/eval-isolation.yaml +6 -1
  111. package/resources/project-architecture/atlas/features/eval-optimizer.yaml +17 -2
  112. package/resources/project-architecture/atlas/features/eval-question.yaml +12 -2
  113. package/resources/project-architecture/atlas/features/eval-reporter.yaml +6 -1
  114. package/resources/project-architecture/atlas/features/eval-scorer.yaml +12 -2
  115. package/resources/project-architecture/features/codegraph/cg-discovery.html +47 -0
  116. package/resources/project-architecture/features/codegraph/cg-lifecycle.html +48 -0
  117. package/resources/project-architecture/features/codegraph/cg-validation.html +47 -0
  118. package/resources/project-architecture/features/codegraph/index.html +58 -0
  119. package/resources/project-architecture/features/eval-ci-gate/workflow-trigger.html +6 -1
  120. package/resources/project-architecture/features/eval-cli/cli-handler.html +8 -1
  121. package/resources/project-architecture/features/eval-executor/exec-api-client.html +6 -1
  122. package/resources/project-architecture/features/eval-executor/trace-recorder.html +6 -1
  123. package/resources/project-architecture/features/eval-isolation/tool-dispatcher.html +6 -1
  124. package/resources/project-architecture/features/eval-optimizer/dedup-engine.html +6 -1
  125. package/resources/project-architecture/features/eval-optimizer/issue-extractor.html +7 -1
  126. package/resources/project-architecture/features/eval-question/question-loader.html +6 -1
  127. package/resources/project-architecture/features/eval-question/variant-generator.html +6 -1
  128. package/resources/project-architecture/features/eval-reporter/report-composer.html +6 -1
  129. package/resources/project-architecture/features/eval-scorer/judge-api-client.html +6 -1
  130. package/resources/project-architecture/features/eval-scorer/judge-prompt-builder.html +6 -1
  131. package/resources/project-architecture/index.html +200 -94
  132. package/scripts/test.sh +39 -0
  133. package/skills/design/SKILL.md +33 -0
  134. package/skills/init-project-html/SKILL.md +66 -56
  135. package/skills/init-project-html/lib/atlas/assets/architecture.css +2 -1
  136. package/skills/init-project-html/lib/atlas/render.js +11 -1
  137. package/skills/init-project-html/lib/atlas/schema.js +44 -7
  138. package/skills/init-project-html/references/TEMPLATE_SPEC.md +20 -0
  139. package/skills/init-project-html/references/architecture.md +35 -35
  140. package/skills/init-project-html/references/definition.md +12 -17
  141. package/skills/update-project-html/README.md +16 -27
  142. package/skills/update-project-html/SKILL.md +54 -41
  143. package/skills/update-project-html/references/architecture.md +35 -35
  144. package/skills/update-project-html/references/definition.md +12 -17
  145. package/tsconfig.json +1 -0
@@ -0,0 +1,343 @@
1
+ import { findProjectRoot } from './lib/cg-instance.js';
2
+ import { handleInit } from './lib/cmd-init.js';
3
+ import { handleSync } from './lib/cmd-sync.js';
4
+ import { handleStatus } from './lib/cmd-status.js';
5
+ import { handleSearch } from './lib/cmd-search.js';
6
+ import { handleExplore } from './lib/cmd-explore.js';
7
+ import { handleSurvey } from './lib/cmd-survey.js';
8
+ import { handleListApis } from './lib/cmd-list-apis.js';
9
+ import { handleVerify } from './lib/cmd-verify.js';
10
+ export async function codegraphHandler(args, context) {
11
+ const stdout = context.stdout || process.stdout;
12
+ const stderr = context.stderr || process.stderr;
13
+ const projectRoot = findProjectRoot(context.cwd || process.cwd());
14
+ // Parse --json flag early (can appear anywhere)
15
+ const jsonIndex = args.indexOf('--json');
16
+ const isJson = jsonIndex >= 0;
17
+ if (jsonIndex >= 0)
18
+ args.splice(jsonIndex, 1);
19
+ // Main help: no args, --help, -h, or "help" subcommand
20
+ if (args.length === 0 || args[0] === '--help' || args[0] === '-h' || args[0] === 'help') {
21
+ printHelp(stdout);
22
+ return 0;
23
+ }
24
+ const subcommand = args[0];
25
+ // Per-subcommand help: e.g., "apltk codegraph search --help"
26
+ // Check for --help/-h at position 1 (after the subcommand name)
27
+ const rest = args.slice(1);
28
+ if (rest.includes('--help') || rest.includes('-h')) {
29
+ printSubcommandHelp(subcommand, stdout, stderr);
30
+ return 0;
31
+ }
32
+ // Parse --spec <dir> for verify
33
+ const specIndex = rest.indexOf('--spec');
34
+ let specDir;
35
+ if (specIndex >= 0 && specIndex + 1 < rest.length) {
36
+ specDir = rest[specIndex + 1];
37
+ rest.splice(specIndex, 2);
38
+ }
39
+ // Parse --all flag for list-apis
40
+ const allIndex = rest.indexOf('--all');
41
+ const isAll = allIndex >= 0;
42
+ if (allIndex >= 0)
43
+ rest.splice(allIndex, 1);
44
+ // Parse --index flag for init
45
+ const shouldIndex = rest.includes('--index');
46
+ const indexIdx = rest.indexOf('--index');
47
+ if (indexIdx >= 0)
48
+ rest.splice(indexIdx, 1);
49
+ // Parse --feature <name> for survey
50
+ const featureIndex = rest.indexOf('--feature');
51
+ let featureName;
52
+ if (featureIndex >= 0 && featureIndex + 1 < rest.length) {
53
+ featureName = rest[featureIndex + 1];
54
+ rest.splice(featureIndex, 2);
55
+ }
56
+ // Parse limit for search
57
+ const limitIndex = rest.indexOf('--limit');
58
+ let limit;
59
+ if (limitIndex >= 0 && limitIndex + 1 < rest.length) {
60
+ limit = parseInt(rest[limitIndex + 1], 10);
61
+ rest.splice(limitIndex, 2);
62
+ }
63
+ try {
64
+ switch (subcommand) {
65
+ case 'init':
66
+ return await handleInit(projectRoot, { index: shouldIndex, json: isJson });
67
+ case 'sync':
68
+ return await handleSync(projectRoot, { json: isJson });
69
+ case 'status':
70
+ return await handleStatus(projectRoot, { json: isJson });
71
+ case 'search': {
72
+ const query = rest.join(' ');
73
+ if (!query) {
74
+ stderr.write('Usage: apltk codegraph search <query> [--limit N] [--json]\n');
75
+ return 1;
76
+ }
77
+ return await handleSearch(projectRoot, query, { limit, json: isJson });
78
+ }
79
+ case 'explore': {
80
+ const query = rest.join(' ');
81
+ if (!query) {
82
+ stderr.write('Usage: apltk codegraph explore <query> [--json]\n');
83
+ return 1;
84
+ }
85
+ return await handleExplore(projectRoot, query, { json: isJson, feature: featureName });
86
+ }
87
+ case 'survey': {
88
+ const dirPath = rest[0] || '.';
89
+ return await handleSurvey(projectRoot, dirPath, { feature: featureName, json: isJson });
90
+ }
91
+ case 'list-apis': {
92
+ const pathArg = rest[0];
93
+ const combinedPath = featureName
94
+ ? (pathArg ? `${featureName}/${pathArg.replace(/^\//, '')}` : featureName)
95
+ : pathArg;
96
+ return await handleListApis(projectRoot, combinedPath, { all: isAll, json: isJson });
97
+ }
98
+ case 'verify': {
99
+ if (!specDir) {
100
+ stderr.write('Usage: apltk codegraph verify --spec <spec-dir> [--json]\n');
101
+ return 1;
102
+ }
103
+ return await handleVerify(projectRoot, specDir, { json: isJson });
104
+ }
105
+ default:
106
+ stderr.write(`Unknown subcommand: ${subcommand}\n\n`);
107
+ printHelp(stderr);
108
+ return 1;
109
+ }
110
+ }
111
+ catch (error) {
112
+ if (error.code === 'MODULE_NOT_FOUND' || (error.message && error.message.includes('Cannot find module'))) {
113
+ stderr.write('`@colbymchenry/codegraph` is not installed. Run `npm install @colbymchenry/codegraph` in your project directory.\n');
114
+ }
115
+ else {
116
+ stderr.write(`Error running codegraph ${subcommand}: ${error.message}\n`);
117
+ }
118
+ return 1;
119
+ }
120
+ }
121
+ function printHelp(stream) {
122
+ stream.write(`Usage: apltk codegraph <subcommand> [options]
123
+
124
+ CodeGraph code intelligence — parse source code into a knowledge graph
125
+ of symbols (functions, classes) and relationships (call edges), backed by
126
+ a local SQLite database with FTS5 full-text search.
127
+
128
+ Powered by @colbymchenry/codegraph (tree-sitter-backed code knowledge graph).
129
+
130
+ Subcommands:
131
+
132
+ lifecycle:
133
+ init Initialize CodeGraph for the project
134
+ --index Run initial indexing immediately after init
135
+ --json JSON output
136
+
137
+ sync Sync the index with current file state
138
+ --json JSON output
139
+
140
+ status Show index statistics (files, nodes, edges, languages)
141
+ --json JSON output
142
+
143
+ discovery:
144
+ search <query> Search the code graph for symbols via FTS5
145
+ --limit N Max results (default: 20, max: 100)
146
+ --json JSON output
147
+
148
+ explore <query> Deep-dive on a symbol — show callers, callees, and source
149
+ --feature <name> Only show results within this feature
150
+ --json JSON output
151
+
152
+ survey [dir] Scan a directory, suggest submodule groupings and
153
+ cross-boundary edges for atlas modelling
154
+ --feature <name> Feature context for grouping
155
+ --json JSON output
156
+
157
+ list-apis [path] List public APIs in the project or within a sub-path
158
+ --all Include non-exported (internal) symbols
159
+ --json JSON output
160
+
161
+ validation:
162
+ verify --spec <dir>
163
+ Verify a spec overlay against actual code —
164
+ checks that every declared feature, submodule,
165
+ function, and edge exists in the code graph
166
+ --json JSON output
167
+
168
+ Global options:
169
+ --json Output as JSON instead of human-readable format
170
+ --help, -h Show this help message
171
+
172
+ Use "apltk codegraph <subcommand> --help" for per-subcommand details.
173
+
174
+ Examples:
175
+ apltk codegraph init
176
+ apltk codegraph init --index
177
+ apltk codegraph status --json
178
+ apltk codegraph search getUser
179
+ apltk codegraph search getUser --limit 5 --json
180
+ apltk codegraph explore handleLogin
181
+ apltk codegraph survey src/
182
+ apltk codegraph survey src/ --feature auth --json
183
+ apltk codegraph list-apis --all
184
+ apltk codegraph verify --spec docs/plans/2026-05-11/add-2fa
185
+ `);
186
+ }
187
+ function printSubcommandHelp(subcommand, stream, errStream) {
188
+ const PAD = ' ';
189
+ const helps = {
190
+ init: `Usage: apltk codegraph init [--index] [--json]
191
+
192
+ Initialize the CodeGraph knowledge graph for the project.
193
+ Creates the .codegraph/ directory and SQLite database.
194
+
195
+ Flags:
196
+ --index Run initial indexing immediately after init, so the
197
+ knowledge graph is ready for queries right away.
198
+ Without this flag, you need to run "apltk codegraph sync"
199
+ separately before searching or exploring.
200
+ --json Output confirmation as JSON.
201
+
202
+ Examples:
203
+ apltk codegraph init
204
+ apltk codegraph init --index
205
+ `,
206
+ sync: `Usage: apltk codegraph sync [--json]
207
+
208
+ Sync the code graph index with the current state of files on disk.
209
+ Parses changed files and updates the SQLite database.
210
+
211
+ This is needed after you modify source files if you want queries
212
+ to reflect the latest code. Runs incrementally — only reprocesses
213
+ files whose mtime has changed.
214
+
215
+ Flags:
216
+ --json Output sync results (files added/removed/updated) as JSON.
217
+
218
+ Examples:
219
+ apltk codegraph sync
220
+ apltk codegraph sync --json
221
+ `,
222
+ status: `Usage: apltk codegraph status [--json]
223
+
224
+ Show index statistics: file count, symbol (node) count, edge count,
225
+ languages detected, and last-sync timestamp.
226
+
227
+ Flags:
228
+ --json Output full statistics as a JSON object.
229
+
230
+ Examples:
231
+ apltk codegraph status
232
+ apltk codegraph status --json
233
+ `,
234
+ search: `Usage: apltk codegraph search <query> [--limit N] [--json]
235
+
236
+ Full-text search the code graph for symbols (functions, classes, variables).
237
+ Uses FTS5 (SQLite full-text search) under the hood.
238
+
239
+ Arguments:
240
+ query Search term (required). Matches against symbol names and
241
+ source code content.
242
+
243
+ Flags:
244
+ --limit N Max results to return (default: 20, max: 100).
245
+ --json Output results as a JSON array.
246
+
247
+ Examples:
248
+ apltk codegraph search getUser
249
+ apltk codegraph search handleLogin --limit 5
250
+ apltk codegraph search "class.*Handler" --limit 10 --json
251
+ `,
252
+ explore: `Usage: apltk codegraph explore <query> [--feature <name>] [--json]
253
+
254
+ Deep-dive on a symbol — shows who calls it, what it calls, and its
255
+ full source code. Useful for understanding how a function or class
256
+ fits into the broader codebase.
257
+
258
+ Arguments:
259
+ query Symbol name to explore (required).
260
+
261
+ Flags:
262
+ --feature <name>
263
+ Scope results to only show callers/callees within a
264
+ specific feature directory (e.g. "auth", "billing").
265
+ --json Output full exploration data as JSON (callers, callees,
266
+ source code, file path, line numbers).
267
+
268
+ Examples:
269
+ apltk codegraph explore handleLogin
270
+ apltk codegraph explore authenticate --feature auth
271
+ apltk codegraph explore sendEmail --json
272
+ `,
273
+ survey: `Usage: apltk codegraph survey [dir] [--feature <name>] [--json]
274
+
275
+ Scan a directory and produce a structured survey report with suggested
276
+ submodule groupings, cross-boundary edges, and entry points.
277
+
278
+ This is the primary input for the "init-project-html" skill's Step 1 —
279
+ it tells the LLM how to model features and submodules for the atlas.
280
+
281
+ Arguments:
282
+ dir Directory to scan (default: current directory ".").
283
+
284
+ Flags:
285
+ --feature <name>
286
+ Feature context: scope the survey to only one feature's
287
+ boundary. Helps the grouper cluster symbols more accurately.
288
+ --json Output survey results as JSON — best for LLM consumption.
289
+
290
+ Examples:
291
+ apltk codegraph survey
292
+ apltk codegraph survey src/
293
+ apltk codegraph survey src/auth --feature auth --json
294
+ `,
295
+ 'list-apis': `Usage: apltk codegraph list-apis [path] [--all] [--json]
296
+
297
+ List public (exported) symbols in the project or a specific sub-path.
298
+ Useful for understanding the public surface area of a module.
299
+
300
+ Arguments:
301
+ path Sub-path to scan (e.g. "src/auth"). When omitted, scans
302
+ the entire project.
303
+
304
+ Flags:
305
+ --all Include non-exported (internal) symbols in the listing.
306
+ --json Output API list as JSON.
307
+
308
+ Examples:
309
+ apltk codegraph list-apis
310
+ apltk codegraph list-apis src/auth
311
+ apltk codegraph list-apis --all --json
312
+ `,
313
+ verify: `Usage: apltk codegraph verify --spec <spec-dir> [--json]
314
+
315
+ Verify a spec overlay's architecture proposals against actual code.
316
+ Checks that every feature, submodule, function, and edge referenced
317
+ in the overlay's atlas state actually exists in the code graph.
318
+
319
+ Flags:
320
+ --spec <spec-dir>
321
+ Path to the spec directory containing an architecture_diff/
322
+ overlay (required). For example, "docs/plans/2026-05-11/add-2fa".
323
+ --json Output verification results as JSON (passed/failed checks).
324
+
325
+ Examples:
326
+ apltk codegraph verify --spec docs/plans/2026-05-11/add-2fa
327
+ apltk codegraph verify --spec docs/plans/2026-05-11/add-2fa --json
328
+ `,
329
+ };
330
+ const text = helps[subcommand];
331
+ if (text) {
332
+ stream.write(text);
333
+ }
334
+ else {
335
+ errStream.write(`Unknown subcommand: "${subcommand}". Use "apltk codegraph --help" for the list of available subcommands.\n`);
336
+ }
337
+ }
338
+ export const tool = {
339
+ name: 'codegraph',
340
+ category: 'Code analysis',
341
+ description: 'CodeGraph code intelligence — init, sync, status, search, explore, survey, list-apis, verify',
342
+ handler: codegraphHandler,
343
+ };
@@ -0,0 +1,29 @@
1
+ export declare function getCodeGraphModule(): {
2
+ CodeGraph: any;
3
+ findNearestCodeGraphRoot: any;
4
+ };
5
+ /**
6
+ * Locate the project root by walking up from the given directory.
7
+ * Returns the nearest parent containing `.codegraph/`, or falls back
8
+ * to the nearest parent containing `package.json`.
9
+ */
10
+ export declare function findProjectRoot(startPath?: string): string;
11
+ /**
12
+ * Initialize a CodeGraph index for the given project root.
13
+ *
14
+ * If the project is already initialized, throws an error suggesting
15
+ * `apltk codegraph sync` instead. Otherwise, initializes a new CodeGraph
16
+ * project. When `options.index` is true, runs initial indexing after init.
17
+ *
18
+ * Note: `CodeGraph.init()` supports an `{ index: true }` shorthand that
19
+ * runs initial indexing inline -- this deviates from a two-step init-then-index
20
+ * pattern but is the supported API through the npm package.
21
+ */
22
+ export declare function createOrOpenIndex(projectRoot: string, options?: {
23
+ index?: boolean;
24
+ onProgress?: (progress: any) => void;
25
+ }): Promise<any>;
26
+ /**
27
+ * Close a CodeGraph instance and release resources.
28
+ */
29
+ export declare function closeIndex(cg: any): void;
@@ -0,0 +1,59 @@
1
+ import path from 'node:path';
2
+ import fs from 'node:fs';
3
+ import { createRequire } from 'node:module';
4
+ const require = createRequire(import.meta.url);
5
+ let _codeGraphModule = null;
6
+ export function getCodeGraphModule() {
7
+ if (!_codeGraphModule) {
8
+ _codeGraphModule = require('@colbymchenry/codegraph');
9
+ }
10
+ return _codeGraphModule;
11
+ }
12
+ /**
13
+ * Locate the project root by walking up from the given directory.
14
+ * Returns the nearest parent containing `.codegraph/`, or falls back
15
+ * to the nearest parent containing `package.json`.
16
+ */
17
+ export function findProjectRoot(startPath) {
18
+ const cwd = startPath || process.cwd();
19
+ const codegraphRoot = getCodeGraphModule().findNearestCodeGraphRoot(cwd);
20
+ if (codegraphRoot)
21
+ return codegraphRoot;
22
+ // Fallback: walk up looking for package.json
23
+ let dir = path.resolve(cwd);
24
+ while (true) {
25
+ if (fs.existsSync(path.join(dir, 'package.json')))
26
+ return dir;
27
+ const parent = path.dirname(dir);
28
+ if (parent === dir)
29
+ return cwd; // hit filesystem root
30
+ dir = parent;
31
+ }
32
+ }
33
+ /**
34
+ * Initialize a CodeGraph index for the given project root.
35
+ *
36
+ * If the project is already initialized, throws an error suggesting
37
+ * `apltk codegraph sync` instead. Otherwise, initializes a new CodeGraph
38
+ * project. When `options.index` is true, runs initial indexing after init.
39
+ *
40
+ * Note: `CodeGraph.init()` supports an `{ index: true }` shorthand that
41
+ * runs initial indexing inline -- this deviates from a two-step init-then-index
42
+ * pattern but is the supported API through the npm package.
43
+ */
44
+ export async function createOrOpenIndex(projectRoot, options) {
45
+ const isInit = getCodeGraphModule().CodeGraph.isInitialized(projectRoot);
46
+ if (isInit) {
47
+ throw new Error(`Project is already initialized at ${projectRoot}. Use \`apltk codegraph sync\` to update the index.`);
48
+ }
49
+ return getCodeGraphModule().CodeGraph.init(projectRoot, {
50
+ index: options?.index ?? false,
51
+ onProgress: options?.onProgress,
52
+ });
53
+ }
54
+ /**
55
+ * Close a CodeGraph instance and release resources.
56
+ */
57
+ export function closeIndex(cg) {
58
+ cg.close();
59
+ }
@@ -0,0 +1,27 @@
1
+ import { describe, it, before, after } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import os from 'node:os';
6
+ import { createOrOpenIndex } from './cg-instance.js';
7
+ describe('createOrOpenIndex', () => {
8
+ let tmpDir;
9
+ before(() => {
10
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'cg-test-'));
11
+ });
12
+ after(() => {
13
+ fs.rmSync(tmpDir, { recursive: true, force: true });
14
+ });
15
+ it('should throw when project is already initialized', async () => {
16
+ // Arrange: create .codegraph/ and codegraph.db to simulate an initialized project
17
+ const codegraphDir = path.join(tmpDir, '.codegraph');
18
+ fs.mkdirSync(codegraphDir, { recursive: true });
19
+ fs.writeFileSync(path.join(codegraphDir, 'codegraph.db'), '');
20
+ // Act & Assert
21
+ await assert.rejects(() => createOrOpenIndex(tmpDir), (err) => {
22
+ assert.ok(err instanceof Error);
23
+ assert.match(err.message, /sync/);
24
+ return true;
25
+ });
26
+ });
27
+ });
@@ -0,0 +1,5 @@
1
+ export interface ExploreOptions {
2
+ json?: boolean;
3
+ feature?: string;
4
+ }
5
+ export declare function handleExplore(projectRoot: string, query: string, options?: ExploreOptions): Promise<number>;
@@ -0,0 +1,95 @@
1
+ import { createRequire } from 'node:module';
2
+ const require = createRequire(import.meta.url);
3
+ import { closeIndex } from './cg-instance.js';
4
+ import { formatOutput } from './formatter.js';
5
+ export async function handleExplore(projectRoot, query, options = {}) {
6
+ const { CodeGraph } = require('@colbymchenry/codegraph');
7
+ const cg = await CodeGraph.open(projectRoot, { sync: false, readOnly: true });
8
+ // Step 1: Search for the query
9
+ const searchResults = cg.searchNodes(query, { limit: 10 });
10
+ if (searchResults.length === 0) {
11
+ process.stdout.write('No symbols found matching the query.\n');
12
+ closeIndex(cg);
13
+ return 0;
14
+ }
15
+ const details = [];
16
+ for (const result of searchResults) {
17
+ const node = result.node;
18
+ const callers = cg.getCallers(node.id).map((c) => ({
19
+ name: c.node.name,
20
+ filePath: c.node.filePath,
21
+ startLine: c.node.startLine,
22
+ }));
23
+ const callees = cg.getCallees(node.id).map((c) => ({
24
+ name: c.node.name,
25
+ filePath: c.node.filePath,
26
+ startLine: c.node.startLine,
27
+ }));
28
+ const code = await cg.getCode(node.id);
29
+ details.push({
30
+ name: node.name,
31
+ kind: node.kind,
32
+ filePath: node.filePath,
33
+ startLine: node.startLine,
34
+ endLine: node.endLine,
35
+ qualifiedName: node.qualifiedName,
36
+ signature: node.signature,
37
+ callers,
38
+ callees,
39
+ code,
40
+ });
41
+ }
42
+ closeIndex(cg);
43
+ if (options.json) {
44
+ process.stdout.write(formatOutput(details, { json: true }) + '\n');
45
+ return 0;
46
+ }
47
+ // Human-readable output — group by filePath
48
+ const grouped = new Map();
49
+ for (const d of details) {
50
+ const group = grouped.get(d.filePath) ?? [];
51
+ group.push(d);
52
+ grouped.set(d.filePath, group);
53
+ }
54
+ if (options.feature) {
55
+ process.stdout.write(`Feature: ${options.feature}\n`);
56
+ }
57
+ for (const [filePath, symbols] of grouped) {
58
+ process.stdout.write(`\n=== ${filePath} ===\n\n`);
59
+ for (const d of symbols) {
60
+ process.stdout.write(` ${d.name} [${d.kind}] line ${d.startLine}-${d.endLine}\n`);
61
+ process.stdout.write(` QName: ${d.qualifiedName}\n`);
62
+ if (d.signature)
63
+ process.stdout.write(` Signature: ${d.signature}\n`);
64
+ process.stdout.write(` Callers (${d.callers.length}):\n`);
65
+ if (d.callers.length === 0) {
66
+ process.stdout.write(' (none)\n');
67
+ }
68
+ else {
69
+ for (const c of d.callers.slice(0, 20)) {
70
+ process.stdout.write(` ${c.name} ${c.filePath}:${c.startLine}\n`);
71
+ }
72
+ }
73
+ process.stdout.write(` Callees (${d.callees.length}):\n`);
74
+ if (d.callees.length === 0) {
75
+ process.stdout.write(' (none)\n');
76
+ }
77
+ else {
78
+ for (const c of d.callees.slice(0, 20)) {
79
+ process.stdout.write(` ${c.name} ${c.filePath}:${c.startLine}\n`);
80
+ }
81
+ }
82
+ if (d.code) {
83
+ process.stdout.write(` Source (${d.filePath}):\n`);
84
+ const lines = d.code.split('\n');
85
+ for (let i = 0; i < Math.min(lines.length, 30); i++) {
86
+ process.stdout.write(` ${lines[i]}\n`);
87
+ }
88
+ if (lines.length > 30) {
89
+ process.stdout.write(` ... (${lines.length - 30} more lines)\n`);
90
+ }
91
+ }
92
+ }
93
+ }
94
+ return 0;
95
+ }