@laitszkin/apollo-toolkit 4.1.4 → 5.0.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/CHANGELOG.md +37 -0
- package/bin/apollo-toolkit.ts +4 -0
- package/dist/bin/apollo-toolkit.js +4 -0
- package/package.json +4 -2
- package/packages/cli/dist/help-text-builder.d.ts +23 -0
- package/packages/cli/dist/help-text-builder.js +166 -0
- package/packages/cli/dist/index.d.ts +6 -17
- package/packages/cli/dist/index.js +52 -246
- package/packages/cli/dist/installer.d.ts +1 -0
- package/packages/cli/dist/installer.js +20 -7
- package/packages/cli/dist/parsers/install-parser.d.ts +15 -0
- package/packages/cli/dist/parsers/install-parser.js +87 -0
- package/packages/cli/dist/parsers/parser-utils.d.ts +9 -0
- package/packages/cli/dist/parsers/parser-utils.js +16 -0
- package/packages/cli/dist/parsers/tool-parser.d.ts +16 -0
- package/packages/cli/dist/parsers/tool-parser.js +58 -0
- package/packages/cli/dist/parsers/types.d.ts +50 -0
- package/packages/cli/dist/parsers/types.js +1 -0
- package/packages/cli/dist/parsers/uninstall-parser.d.ts +15 -0
- package/packages/cli/dist/parsers/uninstall-parser.js +67 -0
- package/packages/cli/dist/tool-registration.d.ts +2 -0
- package/packages/cli/dist/tool-registration.js +2 -0
- package/packages/cli/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/cli/dist/types.d.ts +3 -1
- package/packages/cli/dist/updater.js +11 -5
- package/packages/cli/help-text-builder.ts +180 -0
- package/packages/cli/index.ts +59 -251
- package/packages/cli/installer.ts +19 -7
- package/packages/cli/package.json +6 -3
- package/packages/cli/parsers/install-parser.ts +94 -0
- package/packages/cli/parsers/parser-utils.ts +17 -0
- package/packages/cli/parsers/tool-parser.ts +65 -0
- package/packages/cli/parsers/types.ts +56 -0
- package/packages/cli/parsers/uninstall-parser.ts +75 -0
- package/packages/cli/tool-registration.ts +3 -0
- package/packages/cli/types.ts +6 -1
- package/packages/cli/updater.ts +11 -5
- package/packages/tool-registry/dist/registry.js +3 -4
- package/packages/tool-registry/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tool-registry/dist/types.d.ts +2 -9
- package/packages/tool-registry/package.json +3 -3
- package/packages/tool-registry/registry.ts +3 -4
- package/packages/tool-registry/tsconfig.json +6 -2
- package/packages/tool-registry/types.ts +3 -9
- package/packages/tool-utils/app-error.ts +97 -0
- package/packages/tool-utils/dist/app-error.d.ts +49 -0
- package/packages/tool-utils/dist/app-error.js +80 -0
- package/packages/tool-utils/dist/index.d.ts +5 -0
- package/packages/tool-utils/dist/index.js +3 -0
- package/packages/tool-utils/dist/platform-adapter.d.ts +48 -0
- package/packages/tool-utils/dist/platform-adapter.js +73 -0
- package/packages/tool-utils/dist/schema.d.ts +68 -0
- package/packages/tool-utils/dist/schema.js +67 -0
- package/packages/tool-utils/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tool-utils/index.ts +12 -0
- package/packages/tool-utils/package.json +3 -3
- package/packages/tool-utils/platform-adapter.ts +112 -0
- package/packages/tool-utils/schema.ts +122 -0
- package/packages/tools/architecture/dist/index.d.ts +13 -0
- package/packages/tools/architecture/dist/index.js +55 -57
- package/packages/tools/architecture/dist/index.test.js +17 -4
- package/packages/tools/architecture/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/architecture/index.test.ts +27 -14
- package/packages/tools/architecture/index.ts +85 -88
- package/packages/tools/architecture/package.json +3 -3
- package/packages/tools/codegraph/dist/index.js +12 -22
- package/packages/tools/codegraph/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/codegraph/index.ts +13 -22
- package/packages/tools/codegraph/package.json +3 -3
- package/packages/tools/create-review-report/dist/index.d.ts +1 -2
- package/packages/tools/create-review-report/dist/index.js +46 -77
- package/packages/tools/create-review-report/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/create-review-report/index.ts +52 -81
- package/packages/tools/create-review-report/package.json +3 -3
- package/packages/tools/create-specs/dist/index.d.ts +1 -2
- package/packages/tools/create-specs/dist/index.js +70 -123
- package/packages/tools/create-specs/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/create-specs/index.ts +82 -128
- package/packages/tools/create-specs/package.json +3 -3
- package/packages/tools/docs-to-voice/dist/index.d.ts +1 -2
- package/packages/tools/docs-to-voice/dist/index.js +116 -219
- package/packages/tools/docs-to-voice/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/docs-to-voice/index.ts +265 -385
- package/packages/tools/docs-to-voice/package.json +3 -3
- package/packages/tools/enforce-video-aspect-ratio/dist/index.d.ts +1 -2
- package/packages/tools/enforce-video-aspect-ratio/dist/index.js +77 -154
- package/packages/tools/enforce-video-aspect-ratio/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/enforce-video-aspect-ratio/index.ts +87 -172
- package/packages/tools/enforce-video-aspect-ratio/package.json +3 -3
- package/packages/tools/eval/dist/index.js +7 -0
- package/packages/tools/eval/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/eval/index.ts +8 -0
- package/packages/tools/eval/package.json +3 -3
- package/packages/tools/extract-conversations/dist/index.d.ts +1 -2
- package/packages/tools/extract-conversations/dist/index.js +31 -29
- package/packages/tools/extract-conversations/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/extract-conversations/index.ts +37 -30
- package/packages/tools/extract-conversations/package.json +3 -3
- package/packages/tools/extract-pdf-text/dist/index.d.ts +1 -2
- package/packages/tools/extract-pdf-text/dist/index.js +44 -65
- package/packages/tools/extract-pdf-text/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/extract-pdf-text/index.ts +55 -74
- package/packages/tools/extract-pdf-text/package.json +3 -3
- package/packages/tools/filter-logs/dist/index.js +60 -84
- package/packages/tools/filter-logs/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/filter-logs/index.ts +67 -97
- package/packages/tools/filter-logs/package.json +3 -3
- package/packages/tools/find-github-issues/dist/index.d.ts +10 -0
- package/packages/tools/find-github-issues/dist/index.js +34 -5
- package/packages/tools/find-github-issues/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/find-github-issues/index.ts +37 -5
- package/packages/tools/find-github-issues/package.json +3 -3
- package/packages/tools/generate-storyboard-images/dist/index.d.ts +1 -2
- package/packages/tools/generate-storyboard-images/dist/index.js +98 -173
- package/packages/tools/generate-storyboard-images/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/generate-storyboard-images/index.ts +100 -188
- package/packages/tools/generate-storyboard-images/package.json +3 -3
- package/packages/tools/open-github-issue/dist/index.d.ts +13 -0
- package/packages/tools/open-github-issue/dist/index.js +67 -68
- package/packages/tools/open-github-issue/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/open-github-issue/index.ts +71 -72
- package/packages/tools/open-github-issue/package.json +3 -3
- package/packages/tools/read-github-issue/dist/index.d.ts +16 -1
- package/packages/tools/read-github-issue/dist/index.js +32 -40
- package/packages/tools/read-github-issue/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/read-github-issue/index.ts +32 -45
- package/packages/tools/read-github-issue/package.json +3 -3
- package/packages/tools/render-error-book/dist/index.d.ts +1 -2
- package/packages/tools/render-error-book/dist/index.js +74 -95
- package/packages/tools/render-error-book/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/render-error-book/index.ts +88 -103
- package/packages/tools/render-error-book/package.json +3 -3
- package/packages/tools/render-katex/dist/index.d.ts +1 -2
- package/packages/tools/render-katex/dist/index.js +70 -157
- package/packages/tools/render-katex/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/render-katex/index.ts +138 -222
- package/packages/tools/render-katex/package.json +3 -3
- package/packages/tools/review-threads/dist/index.d.ts +12 -0
- package/packages/tools/review-threads/dist/index.js +83 -86
- package/packages/tools/review-threads/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/review-threads/index.ts +90 -84
- package/packages/tools/review-threads/package.json +3 -3
- package/packages/tools/search-logs/dist/index.js +100 -136
- package/packages/tools/search-logs/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/search-logs/index.ts +113 -145
- package/packages/tools/search-logs/package.json +3 -3
- package/packages/tools/sync-memory-index/dist/index.js +34 -28
- package/packages/tools/sync-memory-index/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/sync-memory-index/index.ts +37 -28
- package/packages/tools/sync-memory-index/package.json +3 -3
- package/packages/tools/validate-openai-agent-config/dist/index.js +13 -7
- package/packages/tools/validate-openai-agent-config/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/validate-openai-agent-config/index.ts +13 -7
- package/packages/tools/validate-openai-agent-config/package.json +3 -3
- package/packages/tools/validate-skill-frontmatter/dist/index.js +12 -6
- package/packages/tools/validate-skill-frontmatter/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/validate-skill-frontmatter/index.ts +12 -6
- package/packages/tools/validate-skill-frontmatter/package.json +3 -3
- package/packages/tui/dist/index.d.ts +2 -1
- package/packages/tui/dist/index.js +1 -0
- package/packages/tui/dist/stdio-adapter.d.ts +36 -0
- package/packages/tui/dist/stdio-adapter.js +69 -0
- package/packages/tui/dist/terminal.js +3 -1
- package/packages/tui/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tui/dist/types.d.ts +17 -0
- package/packages/tui/index.ts +2 -1
- package/packages/tui/package.json +6 -5
- package/packages/tui/stdio-adapter.ts +85 -0
- package/packages/tui/terminal.ts +3 -1
- package/packages/tui/tsconfig.json +5 -2
- package/packages/tui/types.ts +19 -0
- package/resources/project-architecture/assets/architecture.css +2 -1
- package/resources/project-architecture/atlas/atlas.history.log +1 -0
- package/resources/project-architecture/atlas/atlas.history.undo.json +13 -2
- package/resources/project-architecture/atlas/atlas.history.undo.stack.json +610 -0
- package/resources/project-architecture/atlas/atlas.index.yaml +81 -5
- package/resources/project-architecture/atlas/features/cli-dispatch.yaml +43 -0
- package/resources/project-architecture/atlas/features/terminal-ui.yaml +29 -0
- package/resources/project-architecture/atlas/features/tool-registry.yaml +22 -0
- package/resources/project-architecture/atlas/features/tool-utils.yaml +22 -0
- package/resources/project-architecture/features/cli-dispatch/arg-parser.html +40 -0
- package/resources/project-architecture/features/cli-dispatch/help-builder.html +40 -0
- package/resources/project-architecture/features/cli-dispatch/index.html +64 -0
- package/resources/project-architecture/features/cli-dispatch/installer-core.html +40 -0
- package/resources/project-architecture/features/cli-dispatch/tool-discovery.html +40 -0
- package/resources/project-architecture/features/cli-dispatch/update-checker.html +40 -0
- package/resources/project-architecture/features/terminal-ui/banner-display.html +40 -0
- package/resources/project-architecture/features/terminal-ui/index.html +50 -0
- package/resources/project-architecture/features/terminal-ui/interactive-prompts.html +40 -0
- package/resources/project-architecture/features/terminal-ui/terminal-detection.html +40 -0
- package/resources/project-architecture/features/tool-registry/formatter.html +40 -0
- package/resources/project-architecture/features/tool-registry/index.html +43 -0
- package/resources/project-architecture/features/tool-registry/registry-core.html +40 -0
- package/resources/project-architecture/features/tool-utils/index.html +43 -0
- package/resources/project-architecture/features/tool-utils/log-utils.html +40 -0
- package/resources/project-architecture/features/tool-utils/skill-discovery.html +40 -0
- package/resources/project-architecture/index.html +365 -121
- package/scripts/rewrite-imports.mjs +2 -2
- package/scripts/test.sh +144 -8
- package/skills/design/SKILL.md +57 -64
- package/skills/design/assets/templates/DESIGN.md +12 -0
- package/skills/design/references/code-smells.md +94 -0
- package/skills/design/references/module-boundary-adjustment.md +126 -0
- package/skills/design/references/module-internal-restructuring.md +132 -0
- package/skills/design/references/module-internal-simplification.md +164 -0
|
@@ -4,6 +4,7 @@ import { createRequire } from 'node:module';
|
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
5
5
|
import type { ToolDefinition, ToolContext } from '@laitszkin/tool-registry';
|
|
6
6
|
import yaml from 'js-yaml';
|
|
7
|
+
import { UserInputError, SystemError, createPlatformAdapter } from '@laitszkin/tool-utils';
|
|
7
8
|
|
|
8
9
|
// ── Apply & Template helpers (mirrors cli.js internals for the new verbs) ─────
|
|
9
10
|
|
|
@@ -77,7 +78,7 @@ function removeSubmodule(feature: any, slug: string, merged?: any): boolean {
|
|
|
77
78
|
|
|
78
79
|
function parseEndpoint(value: string): { feature: string; submodule?: string } {
|
|
79
80
|
const parts = value.split('/').filter(Boolean);
|
|
80
|
-
if (parts.length === 0) throw new
|
|
81
|
+
if (parts.length === 0) throw new UserInputError(`Invalid endpoint: "${value}"`);
|
|
81
82
|
return parts.length > 1
|
|
82
83
|
? { feature: parts[0], submodule: parts[1] }
|
|
83
84
|
: { feature: parts[0] };
|
|
@@ -145,17 +146,13 @@ function yamlStr(value: string): string {
|
|
|
145
146
|
|
|
146
147
|
async function handleApply(applyArgs: string[], context: ToolContext): Promise<number> {
|
|
147
148
|
const stdout = context.stdout || process.stdout;
|
|
148
|
-
const stderr = context.stderr || process.stderr;
|
|
149
149
|
const sourceRoot =
|
|
150
150
|
context.sourceRoot ||
|
|
151
151
|
path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..', '..', '..');
|
|
152
152
|
|
|
153
153
|
const yamlArg = applyArgs[0];
|
|
154
154
|
if (!yamlArg || yamlArg.startsWith('--')) {
|
|
155
|
-
|
|
156
|
-
'Usage: apltk architecture apply <yaml-file> [--spec <dir>] [--project <root>] [--no-render]\n',
|
|
157
|
-
);
|
|
158
|
-
return 1;
|
|
155
|
+
throw new UserInputError('Missing architecture specification YAML file path. Usage: apltk architecture apply <yaml-file>');
|
|
159
156
|
}
|
|
160
157
|
|
|
161
158
|
// Simple flag parser for trailing flags (--spec, --project, --no-render)
|
|
@@ -176,13 +173,11 @@ async function handleApply(applyArgs: string[], context: ToolContext): Promise<n
|
|
|
176
173
|
batch = yaml.load(raw);
|
|
177
174
|
} catch (e: any) {
|
|
178
175
|
const location = e.mark ? ` at line ${e.mark.line + 1}` : '';
|
|
179
|
-
|
|
180
|
-
return 1;
|
|
176
|
+
throw new UserInputError(`Error parsing apply YAML (${yamlArg})${location}: ${e.message}`);
|
|
181
177
|
}
|
|
182
178
|
|
|
183
179
|
if (!batch || typeof batch !== 'object') {
|
|
184
|
-
|
|
185
|
-
return 1;
|
|
180
|
+
throw new UserInputError('Invalid apply YAML: expected an object with "features" / "edges" keys.');
|
|
186
181
|
}
|
|
187
182
|
|
|
188
183
|
// Import atlas modules (shared with the existing JS CLI)
|
|
@@ -215,8 +210,7 @@ async function handleApply(applyArgs: string[], context: ToolContext): Promise<n
|
|
|
215
210
|
try {
|
|
216
211
|
projectRoot = cli.resolveProjectRoot(flags);
|
|
217
212
|
} catch (e: any) {
|
|
218
|
-
|
|
219
|
-
return 1;
|
|
213
|
+
throw new UserInputError(e.message);
|
|
220
214
|
}
|
|
221
215
|
|
|
222
216
|
const isSpec = Boolean(flags.spec);
|
|
@@ -244,7 +238,7 @@ async function handleApply(applyArgs: string[], context: ToolContext): Promise<n
|
|
|
244
238
|
// 1) Features (add / modify / remove)
|
|
245
239
|
for (const feat of batch.features || []) {
|
|
246
240
|
const slug: string = feat.slug;
|
|
247
|
-
if (!slug) throw new
|
|
241
|
+
if (!slug) throw new UserInputError('"features" entry missing required "slug" field');
|
|
248
242
|
|
|
249
243
|
switch (feat.action) {
|
|
250
244
|
case 'add': {
|
|
@@ -259,7 +253,7 @@ async function handleApply(applyArgs: string[], context: ToolContext): Promise<n
|
|
|
259
253
|
}
|
|
260
254
|
case 'modify': {
|
|
261
255
|
const existing = findFeature(merged, slug);
|
|
262
|
-
if (!existing) throw new
|
|
256
|
+
if (!existing) throw new UserInputError(`feature "${slug}" not found for action "modify"`);
|
|
263
257
|
if (feat.title !== undefined) existing.title = String(feat.title);
|
|
264
258
|
if (feat.story !== undefined) existing.story = String(feat.story);
|
|
265
259
|
if (feat.dependsOn !== undefined)
|
|
@@ -271,7 +265,7 @@ async function handleApply(applyArgs: string[], context: ToolContext): Promise<n
|
|
|
271
265
|
removeFeature(merged, slug);
|
|
272
266
|
break;
|
|
273
267
|
default:
|
|
274
|
-
throw new
|
|
268
|
+
throw new UserInputError(`feature "${slug}": unknown action "${feat.action}"`);
|
|
275
269
|
}
|
|
276
270
|
}
|
|
277
271
|
|
|
@@ -279,7 +273,7 @@ async function handleApply(applyArgs: string[], context: ToolContext): Promise<n
|
|
|
279
273
|
for (const feat of batch.features || []) {
|
|
280
274
|
if (feat.action === 'remove') continue;
|
|
281
275
|
const parent = findFeature(merged, feat.slug);
|
|
282
|
-
if (!parent) throw new
|
|
276
|
+
if (!parent) throw new UserInputError(`feature "${feat.slug}" not found for submodule operations`);
|
|
283
277
|
for (const sub of feat.submodules || []) {
|
|
284
278
|
switch (sub.action) {
|
|
285
279
|
case 'add': {
|
|
@@ -294,7 +288,7 @@ async function handleApply(applyArgs: string[], context: ToolContext): Promise<n
|
|
|
294
288
|
removeSubmodule(parent, sub.slug, merged);
|
|
295
289
|
break;
|
|
296
290
|
default:
|
|
297
|
-
throw new
|
|
291
|
+
throw new UserInputError(
|
|
298
292
|
`submodule "${feat.slug}/${sub.slug}": unknown action "${sub.action}"`,
|
|
299
293
|
);
|
|
300
294
|
}
|
|
@@ -310,7 +304,7 @@ async function handleApply(applyArgs: string[], context: ToolContext): Promise<n
|
|
|
310
304
|
if (sub.action === 'remove') continue;
|
|
311
305
|
const subMod = findSubmodule(parent, sub.slug);
|
|
312
306
|
if (!subMod)
|
|
313
|
-
throw new
|
|
307
|
+
throw new UserInputError(`submodule "${feat.slug}/${sub.slug}" not found for function operations`);
|
|
314
308
|
for (const fn of sub.functions || []) {
|
|
315
309
|
switch (fn.action) {
|
|
316
310
|
case 'add': {
|
|
@@ -332,7 +326,7 @@ async function handleApply(applyArgs: string[], context: ToolContext): Promise<n
|
|
|
332
326
|
);
|
|
333
327
|
break;
|
|
334
328
|
default:
|
|
335
|
-
throw new
|
|
329
|
+
throw new UserInputError(
|
|
336
330
|
`function "${feat.slug}/${sub.slug}/${fn.name}": unknown action "${fn.action}"`,
|
|
337
331
|
);
|
|
338
332
|
}
|
|
@@ -348,7 +342,7 @@ async function handleApply(applyArgs: string[], context: ToolContext): Promise<n
|
|
|
348
342
|
from = parseEndpoint(edge.from);
|
|
349
343
|
to = parseEndpoint(edge.to);
|
|
350
344
|
} catch (er: any) {
|
|
351
|
-
throw new
|
|
345
|
+
throw new UserInputError(`edge: ${er.message}`, undefined, { cause: er });
|
|
352
346
|
}
|
|
353
347
|
|
|
354
348
|
switch (edge.action) {
|
|
@@ -356,28 +350,28 @@ async function handleApply(applyArgs: string[], context: ToolContext): Promise<n
|
|
|
356
350
|
// Referential integrity validation
|
|
357
351
|
const fromFeature = findFeature(merged, from.feature);
|
|
358
352
|
if (!fromFeature) {
|
|
359
|
-
throw new
|
|
353
|
+
throw new UserInputError(
|
|
360
354
|
`edge "${edge.from} → ${edge.to}": source feature "${from.feature}" not found`,
|
|
361
355
|
);
|
|
362
356
|
}
|
|
363
357
|
if (from.submodule) {
|
|
364
358
|
const fromSub = findSubmodule(fromFeature, from.submodule);
|
|
365
359
|
if (!fromSub) {
|
|
366
|
-
throw new
|
|
360
|
+
throw new UserInputError(
|
|
367
361
|
`edge "${edge.from} → ${edge.to}": source submodule "${from.submodule}" not found in feature "${from.feature}"`,
|
|
368
362
|
);
|
|
369
363
|
}
|
|
370
364
|
}
|
|
371
365
|
const toFeature = findFeature(merged, to.feature);
|
|
372
366
|
if (!toFeature) {
|
|
373
|
-
throw new
|
|
367
|
+
throw new UserInputError(
|
|
374
368
|
`edge "${edge.from} → ${edge.to}": target feature "${to.feature}" not found`,
|
|
375
369
|
);
|
|
376
370
|
}
|
|
377
371
|
if (to.submodule) {
|
|
378
372
|
const toSub = findSubmodule(toFeature, to.submodule);
|
|
379
373
|
if (!toSub) {
|
|
380
|
-
throw new
|
|
374
|
+
throw new UserInputError(
|
|
381
375
|
`edge "${edge.from} → ${edge.to}": target submodule "${to.submodule}" not found in feature "${to.feature}"`,
|
|
382
376
|
);
|
|
383
377
|
}
|
|
@@ -426,12 +420,14 @@ async function handleApply(applyArgs: string[], context: ToolContext): Promise<n
|
|
|
426
420
|
break;
|
|
427
421
|
}
|
|
428
422
|
default:
|
|
429
|
-
throw new
|
|
423
|
+
throw new UserInputError(`edge "${edge.from} → ${edge.to}": unknown action "${edge.action}"`);
|
|
430
424
|
}
|
|
431
425
|
}
|
|
432
426
|
} catch (e: any) {
|
|
433
|
-
|
|
434
|
-
|
|
427
|
+
if (e instanceof UserInputError || e instanceof SystemError) {
|
|
428
|
+
throw e;
|
|
429
|
+
}
|
|
430
|
+
throw new UserInputError(e.message);
|
|
435
431
|
}
|
|
436
432
|
|
|
437
433
|
// ── All mutations succeeded — persist ──
|
|
@@ -481,54 +477,50 @@ async function handleApply(applyArgs: string[], context: ToolContext): Promise<n
|
|
|
481
477
|
// ── template ─────────────────────────────────────────────────────────────────
|
|
482
478
|
|
|
483
479
|
async function handleTemplate(templateArgs: string[], context: ToolContext): Promise<number> {
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
480
|
+
const stdout = context.stdout || process.stdout;
|
|
481
|
+
const adapter = createPlatformAdapter();
|
|
482
|
+
|
|
483
|
+
// Parse --spec <dir> --output <dir>
|
|
484
|
+
let specDir: string | undefined;
|
|
485
|
+
let outputDir: string | undefined;
|
|
486
|
+
for (let i = 0; i < templateArgs.length; i++) {
|
|
487
|
+
const a = templateArgs[i];
|
|
488
|
+
if (a === '--spec' && i + 1 < templateArgs.length) specDir = templateArgs[++i];
|
|
489
|
+
else if (a === '--output' && i + 1 < templateArgs.length) outputDir = templateArgs[++i];
|
|
490
|
+
}
|
|
495
491
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
}
|
|
492
|
+
if (!specDir || !outputDir) {
|
|
493
|
+
throw new UserInputError('Missing --spec and/or --output arguments. Usage: apltk architecture template --spec <spec-dir> --output <output-dir>');
|
|
494
|
+
}
|
|
500
495
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
496
|
+
const specPath = path.resolve(specDir, 'SPEC.md');
|
|
497
|
+
const outputDirPath = path.resolve(outputDir);
|
|
498
|
+
const outputPath = path.join(outputDirPath, 'proposal.yaml');
|
|
504
499
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
500
|
+
// Extract spec metadata (title, goal) from SPEC.md
|
|
501
|
+
let featureSlug = 'feature';
|
|
502
|
+
let featureTitle = 'Feature';
|
|
503
|
+
let goal = '';
|
|
509
504
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
505
|
+
if (fs.existsSync(specPath)) {
|
|
506
|
+
const meta = parseSpecMetadata(specPath);
|
|
507
|
+
if (meta.title) {
|
|
508
|
+
featureTitle = meta.title;
|
|
509
|
+
featureSlug = toSlug(featureTitle);
|
|
510
|
+
}
|
|
511
|
+
if (meta.goal) {
|
|
512
|
+
goal = meta.goal;
|
|
513
|
+
}
|
|
514
|
+
} else {
|
|
520
515
|
const resolvedSpecDir = path.resolve(specDir);
|
|
521
516
|
if (!fs.existsSync(resolvedSpecDir)) {
|
|
522
|
-
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
} else {
|
|
528
|
-
stderr.write(`Spec directory found but no SPEC.md. No .md files found.\n`);
|
|
529
|
-
}
|
|
517
|
+
throw new UserInputError(`Spec directory not found: ${resolvedSpecDir}`);
|
|
518
|
+
}
|
|
519
|
+
const mdFiles = fs.readdirSync(resolvedSpecDir).filter((f: string) => f.endsWith('.md'));
|
|
520
|
+
if (mdFiles.length > 0) {
|
|
521
|
+
throw new UserInputError(`Spec directory found but no SPEC.md. Found: ${mdFiles.join(', ')}`);
|
|
530
522
|
}
|
|
531
|
-
|
|
523
|
+
throw new UserInputError('Spec directory found but no SPEC.md. No .md files found.');
|
|
532
524
|
}
|
|
533
525
|
|
|
534
526
|
// Build proposal.yaml content
|
|
@@ -554,11 +546,10 @@ async function handleTemplate(templateArgs: string[], context: ToolContext): Pro
|
|
|
554
546
|
|
|
555
547
|
try {
|
|
556
548
|
fs.mkdirSync(outputDirPath, { recursive: true });
|
|
557
|
-
fs.writeFileSync(outputPath, lines.join(
|
|
549
|
+
fs.writeFileSync(outputPath, lines.join(adapter.EOL), 'utf8');
|
|
558
550
|
stdout.write(`${outputPath}\n`);
|
|
559
551
|
} catch (e: any) {
|
|
560
|
-
|
|
561
|
-
return 1;
|
|
552
|
+
throw new SystemError(`Error writing proposal.yaml: ${e.message}`);
|
|
562
553
|
}
|
|
563
554
|
|
|
564
555
|
// Try to enrich with CodeGraph API listing
|
|
@@ -581,7 +572,7 @@ async function handleTemplate(templateArgs: string[], context: ToolContext): Pro
|
|
|
581
572
|
}
|
|
582
573
|
apiLines.push('#');
|
|
583
574
|
const existing = fs.readFileSync(outputPath, 'utf8');
|
|
584
|
-
fs.writeFileSync(outputPath, apiLines.join(
|
|
575
|
+
fs.writeFileSync(outputPath, apiLines.join(adapter.EOL) + adapter.EOL + existing);
|
|
585
576
|
cg.close();
|
|
586
577
|
}
|
|
587
578
|
} catch {
|
|
@@ -593,14 +584,27 @@ async function handleTemplate(templateArgs: string[], context: ToolContext): Pro
|
|
|
593
584
|
|
|
594
585
|
// ── Handler entrypoint ───────────────────────────────────────────────────────
|
|
595
586
|
|
|
587
|
+
/**
|
|
588
|
+
* architectureHandler — Known carryover from the createToolRunner migration.
|
|
589
|
+
*
|
|
590
|
+
* Reason for not using createToolRunner:
|
|
591
|
+
* - Mixed TS/JS dispatch: "apply" and "template" subcommands use TypeScript
|
|
592
|
+
* with AppError throws. Other subcommands delegate to the JS atlas CLI
|
|
593
|
+
* (cli.js) which has its own error handling.
|
|
594
|
+
* - Subcommand-level flag parsing: Each subcommand has unique flags; a single
|
|
595
|
+
* ToolSchema can't express this. See DESIGN.md §2.3 for the full picture.
|
|
596
|
+
*
|
|
597
|
+
* Error handling: All TS paths throw UserInputError/SystemError. JS paths are
|
|
598
|
+
* handled by cli.dispatch()'s internal catch.
|
|
599
|
+
*/
|
|
596
600
|
export async function architectureHandler(
|
|
597
601
|
args: string[],
|
|
598
602
|
context: ToolContext,
|
|
599
603
|
): Promise<number> {
|
|
600
604
|
// Intercept apply / template before passing through to the JS CLI
|
|
601
605
|
const first = args[0] || '';
|
|
602
|
-
if (first === 'apply') return handleApply(args.slice(1), context);
|
|
603
|
-
if (first === 'template') return handleTemplate(args.slice(1), context);
|
|
606
|
+
if (first === 'apply') return await handleApply(args.slice(1), context);
|
|
607
|
+
if (first === 'template') return await handleTemplate(args.slice(1), context);
|
|
604
608
|
|
|
605
609
|
// Delegate to the existing atlas CLI (still in JS)
|
|
606
610
|
const sourceRoot =
|
|
@@ -615,20 +619,13 @@ export async function architectureHandler(
|
|
|
615
619
|
'cli.js',
|
|
616
620
|
);
|
|
617
621
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
});
|
|
626
|
-
} catch (error: any) {
|
|
627
|
-
(context.stderr || process.stderr).write(
|
|
628
|
-
`Error loading atlas CLI: ${error.message}\n`,
|
|
629
|
-
);
|
|
630
|
-
return 1;
|
|
631
|
-
}
|
|
622
|
+
// Use file URL for ESM import compatibility on Windows — import() requires forward slashes.
|
|
623
|
+
const cliModule = await import(pathToFileURL(cliPath).href);
|
|
624
|
+
const cli = cliModule.default;
|
|
625
|
+
return cli.dispatch(args, {
|
|
626
|
+
stdout: context.stdout || process.stdout,
|
|
627
|
+
stderr: context.stderr || process.stderr,
|
|
628
|
+
});
|
|
632
629
|
}
|
|
633
630
|
|
|
634
631
|
export const tool: ToolDefinition = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@laitszkin/tool-architecture",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Apollo Toolkit
|
|
3
|
+
"version": "5.0.0",
|
|
4
|
+
"description": "Apollo Toolkit \u2014 CLI tool",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -19,4 +19,4 @@
|
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@laitszkin/tool-registry": "*"
|
|
21
21
|
}
|
|
22
|
-
}
|
|
22
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SystemError, UserInputError } from '../../../tool-utils/dist/index.js';
|
|
1
2
|
import { findProjectRoot } from './lib/cg-instance.js';
|
|
2
3
|
import { handleInit } from './lib/cmd-init.js';
|
|
3
4
|
import { handleSync } from './lib/cmd-sync.js';
|
|
@@ -35,13 +36,11 @@ export async function codegraphHandler(args, context) {
|
|
|
35
36
|
projectRoot = findProjectRoot(context.cwd || process.cwd());
|
|
36
37
|
}
|
|
37
38
|
catch (error) {
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
const message = error instanceof Error ? error.message : 'Unknown error finding project root';
|
|
40
|
+
if (error?.code === 'MODULE_NOT_FOUND' || message.includes('Cannot find module')) {
|
|
41
|
+
throw new UserInputError('`@colbymchenry/codegraph` is not installed. Run `npm install @colbymchenry/codegraph` in your project directory.');
|
|
40
42
|
}
|
|
41
|
-
|
|
42
|
-
stderr.write(`Error finding project root: ${error.message}\n`);
|
|
43
|
-
}
|
|
44
|
-
return 1;
|
|
43
|
+
throw new SystemError(`Error finding project root: ${message}`);
|
|
45
44
|
}
|
|
46
45
|
// Parse --spec <dir> for verify
|
|
47
46
|
const specIndex = rest.indexOf('--spec');
|
|
@@ -85,16 +84,14 @@ export async function codegraphHandler(args, context) {
|
|
|
85
84
|
case 'search': {
|
|
86
85
|
const query = rest.join(' ');
|
|
87
86
|
if (!query) {
|
|
88
|
-
|
|
89
|
-
return 1;
|
|
87
|
+
throw new UserInputError('Usage: apltk codegraph search <query> [--limit N] [--json]');
|
|
90
88
|
}
|
|
91
89
|
return await handleSearch(projectRoot, query, { limit, json: isJson });
|
|
92
90
|
}
|
|
93
91
|
case 'explore': {
|
|
94
92
|
const query = rest.join(' ');
|
|
95
93
|
if (!query) {
|
|
96
|
-
|
|
97
|
-
return 1;
|
|
94
|
+
throw new UserInputError('Usage: apltk codegraph explore <query> [--json]');
|
|
98
95
|
}
|
|
99
96
|
return await handleExplore(projectRoot, query, { json: isJson, feature: featureName });
|
|
100
97
|
}
|
|
@@ -111,25 +108,18 @@ export async function codegraphHandler(args, context) {
|
|
|
111
108
|
}
|
|
112
109
|
case 'verify': {
|
|
113
110
|
if (!specDir) {
|
|
114
|
-
|
|
115
|
-
return 1;
|
|
111
|
+
throw new UserInputError('Usage: apltk codegraph verify --spec <spec-dir> [--json]');
|
|
116
112
|
}
|
|
117
113
|
return await handleVerify(projectRoot, specDir, { json: isJson });
|
|
118
114
|
}
|
|
119
115
|
default:
|
|
120
|
-
|
|
121
|
-
printHelp(stderr);
|
|
122
|
-
return 1;
|
|
116
|
+
throw new SystemError(`Unknown codegraph subcommand: ${subcommand}`);
|
|
123
117
|
}
|
|
124
118
|
}
|
|
125
119
|
catch (error) {
|
|
126
|
-
if (error
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
stderr.write(`Error running codegraph ${subcommand}: ${error.message}\n`);
|
|
131
|
-
}
|
|
132
|
-
return 1;
|
|
120
|
+
if (error instanceof SystemError || error instanceof UserInputError)
|
|
121
|
+
throw error;
|
|
122
|
+
throw new SystemError(error instanceof Error ? error.message : 'Unknown error in codegraph', { cause: error instanceof Error ? error : undefined });
|
|
133
123
|
}
|
|
134
124
|
}
|
|
135
125
|
function printHelp(stream) {
|