@laitszkin/apollo-toolkit 4.1.4 → 5.0.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.
- package/CHANGELOG.md +45 -0
- package/bin/apollo-toolkit.ts +4 -0
- package/dist/bin/apollo-toolkit.js +4 -0
- package/package.json +3 -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 +14 -4
- 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 +11 -4
- 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 +11 -4
- 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 +11 -4
- 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 +11 -4
- 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 +11 -4
- 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 +11 -4
- 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 +11 -4
- 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 +11 -4
- 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 +11 -4
- 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 +11 -4
- 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 +11 -4
- 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 +11 -4
- 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 +11 -4
- 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 +11 -4
- 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 +11 -4
- 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 +11 -4
- 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 +11 -4
- 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 +11 -4
- 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 +11 -4
- 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 +11 -4
- 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 +11 -4
- 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 +11 -4
- 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 +11 -4
- 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 +14 -6
- 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
|
@@ -1,257 +1,50 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
|
-
import { color, supportsColor, buildBanner, buildWelcomeScreen,
|
|
5
|
-
import {
|
|
6
|
-
import { formatExamples } from '../../tool-registry/dist/index.js';
|
|
4
|
+
import { color, supportsColor, buildBanner, buildWelcomeScreen, animateWelcomeScreen, promptYesNo, promptForModes, isInteractive, createStdioWriter } from '../../tui/dist/index.js';
|
|
5
|
+
import { runTool } from '../../tool-registry/dist/index.js';
|
|
7
6
|
import { TARGET_DEFINITIONS, VALID_MODES, installLinks, listAllKnownSkillNames, listCodexSkillNames, normalizeModes, resolveToolkitHome, syncToolkitHome, uninstallSkills, getTargetRoots, getUninstallTargetRoots, expandUserPath, readManifest, writeManifest, resolveHomeDirectory, listSkillNames, } from './installer.js';
|
|
8
7
|
import { checkForPackageUpdate, compareVersions, execCommand } from './updater.js';
|
|
9
8
|
import { registerAllTools, isKnownToolName } from './tool-registration.js';
|
|
10
9
|
// Re-export installer functions for external consumers (tests, bin)
|
|
11
10
|
export { TARGET_DEFINITIONS, VALID_MODES, installLinks, listAllKnownSkillNames, listCodexSkillNames, normalizeModes, resolveToolkitHome, syncToolkitHome, uninstallSkills, getTargetRoots, getUninstallTargetRoots, expandUserPath, readManifest, writeManifest, resolveHomeDirectory, listSkillNames, checkForPackageUpdate, compareVersions, execCommand, };
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return `${quotedModes.slice(0, -1).join(', ')}, or ${quotedModes.at(-1)}`;
|
|
18
|
-
}
|
|
19
|
-
function buildHelpText({ version, colorEnabled }) {
|
|
20
|
-
const examples = [
|
|
21
|
-
{ command: 'apltk --help', result: 'Shows the top-level Apollo Toolkit guide, including install modes and bundled task-tool discovery.' },
|
|
22
|
-
{ command: 'apltk tools --help', result: 'Lists bundled tools by task so you can decide which CLI helper to inspect next.' },
|
|
23
|
-
{ command: 'apltk architecture --help', result: 'Shows the architecture atlas command tree, task guidance, and action-specific follow-up help paths.' },
|
|
24
|
-
{ command: 'apltk tools architecture --help', result: 'Shows what the architecture atlas tool is for, then prints its native command tree and examples.' },
|
|
25
|
-
{ command: 'apltk filter-logs app.log --start 2026-03-24T10:00:00Z', result: 'Prints only the log lines whose timestamps fall within the requested time window.' },
|
|
26
|
-
];
|
|
27
|
-
return [
|
|
28
|
-
buildBanner({ version, colorEnabled }),
|
|
29
|
-
'',
|
|
30
|
-
'Usage:',
|
|
31
|
-
` apltk [install] [${buildModeUsagePattern()}]...`,
|
|
32
|
-
` apollo-toolkit [install] [${buildModeUsagePattern()}]...`,
|
|
33
|
-
` apltk uninstall [${buildModeUsagePattern()}]... [--yes]`,
|
|
34
|
-
' apltk tools',
|
|
35
|
-
' apltk <tool> [...args]',
|
|
36
|
-
' apltk tools <tool> [...args]',
|
|
37
|
-
' apltk --help',
|
|
38
|
-
' apollo-toolkit --help',
|
|
39
|
-
'',
|
|
40
|
-
'Common goals:',
|
|
41
|
-
' - Install or refresh skills in one or more agent targets: `apltk install --help`',
|
|
42
|
-
' - Remove manifest-tracked installs from selected targets: `apltk uninstall --help`',
|
|
43
|
-
' - Discover which bundled helper tool matches a task: `apltk tools --help`',
|
|
44
|
-
' - Inspect one tool deeply before running it: `apltk tools <tool> --help`',
|
|
45
|
-
'',
|
|
46
|
-
'Bundled tools:',
|
|
47
|
-
formatToolList(),
|
|
48
|
-
'',
|
|
49
|
-
buildToolDiscoveryHelp(),
|
|
50
|
-
'',
|
|
51
|
-
'Options:',
|
|
52
|
-
' --home <path> Override Apollo Toolkit home directory',
|
|
53
|
-
' --symlink Install skills as symlinks instead of copied directories',
|
|
54
|
-
' --copy Install skills as copied directories instead of symlinks',
|
|
55
|
-
' --yes, -y Skip uninstall confirmation',
|
|
56
|
-
' --help Show this help text',
|
|
57
|
-
'',
|
|
58
|
-
'Examples:',
|
|
59
|
-
formatExamples(examples),
|
|
60
|
-
].join('\n');
|
|
61
|
-
}
|
|
62
|
-
function buildToolsHelp({ version, colorEnabled }) {
|
|
63
|
-
const examples = [
|
|
64
|
-
{ command: 'apltk tools', result: 'Lists all bundled tools plus the task-oriented discovery guide.' },
|
|
65
|
-
{ command: 'apltk tools open-github-issue --help', result: 'Shows when to use the GitHub issue publisher, then prints its exact script flags and examples.' },
|
|
66
|
-
{ command: 'apltk tools architecture --help', result: 'Shows when to use the architecture atlas CLI, then prints its native command tree.' },
|
|
67
|
-
];
|
|
68
|
-
return [
|
|
69
|
-
buildBanner({ version, colorEnabled }),
|
|
70
|
-
'',
|
|
71
|
-
'Usage:',
|
|
72
|
-
' apltk tools',
|
|
73
|
-
' apltk <tool> [...args]',
|
|
74
|
-
' apltk tools <tool> [...args]',
|
|
75
|
-
'',
|
|
76
|
-
buildToolDiscoveryHelp(),
|
|
77
|
-
'',
|
|
78
|
-
'Bundled tools:',
|
|
79
|
-
formatToolList(),
|
|
80
|
-
'',
|
|
81
|
-
'Tip:',
|
|
82
|
-
' Pass `--help` after a tool name to view task guidance, native script flags, and concrete examples.',
|
|
83
|
-
'',
|
|
84
|
-
'Examples:',
|
|
85
|
-
formatExamples(examples),
|
|
86
|
-
].join('\n');
|
|
87
|
-
}
|
|
88
|
-
function buildInstallHelpText({ version, colorEnabled }) {
|
|
89
|
-
const examples = [
|
|
90
|
-
{ command: 'apltk', result: 'Launches the interactive installer, opens the target selector, and then walks through link-mode confirmation.' },
|
|
91
|
-
{ command: 'apltk codex openclaw --symlink', result: 'Performs a non-interactive install into `codex` and `openclaw` targets using symlinks.' },
|
|
92
|
-
{ command: 'npx @laitszkin/apollo-toolkit all --copy', result: 'Installs a copied snapshot into every supported target instead of symlinking.' },
|
|
93
|
-
];
|
|
94
|
-
return [
|
|
95
|
-
buildBanner({ version, colorEnabled }),
|
|
96
|
-
'',
|
|
97
|
-
'Usage:',
|
|
98
|
-
` apltk [install] [${buildModeUsagePattern()}]...`,
|
|
99
|
-
` apollo-toolkit [install] [${buildModeUsagePattern()}]...`,
|
|
100
|
-
'',
|
|
101
|
-
'Use this when:',
|
|
102
|
-
' - You want to install or refresh Apollo Toolkit skills in one or more agent targets.',
|
|
103
|
-
' - You need to choose between symlink mode (auto-updating) and copy mode (stable snapshot).',
|
|
104
|
-
'',
|
|
105
|
-
'Supported targets:',
|
|
106
|
-
buildSupportedTargetLines({ targets: [...TARGET_DEFINITIONS], colorEnabled }),
|
|
107
|
-
'',
|
|
108
|
-
'Behavior notes:',
|
|
109
|
-
' - Running `apltk` with no targets opens the interactive installer and target selector.',
|
|
110
|
-
' - `--symlink` keeps installed skills connected to the managed toolkit checkout in `~/.apollo-toolkit`.',
|
|
111
|
-
' - `--copy` installs a snapshot that only changes when you run the installer again.',
|
|
112
|
-
' - The installer can optionally include codex-exclusive skills in non-codex targets after prompting.',
|
|
113
|
-
'',
|
|
114
|
-
'Options:',
|
|
115
|
-
' --home <path> Override Apollo Toolkit home directory',
|
|
116
|
-
' --symlink Install skills as symlinks (recommended)',
|
|
117
|
-
' --copy Install skills as copied directories',
|
|
118
|
-
' --help Show this install help',
|
|
119
|
-
'',
|
|
120
|
-
'Examples:',
|
|
121
|
-
formatExamples(examples),
|
|
122
|
-
].join('\n');
|
|
123
|
-
}
|
|
124
|
-
function buildUninstallHelpText({ version, colorEnabled }) {
|
|
125
|
-
const examples = [
|
|
126
|
-
{ command: 'apltk uninstall', result: 'Opens the interactive uninstall selector when running in a TTY and then asks for confirmation before removal.' },
|
|
127
|
-
{ command: 'apltk uninstall codex agents --yes', result: 'Removes Apollo Toolkit-managed installs from `codex` and `agents` without another confirmation prompt.' },
|
|
128
|
-
{ command: 'apltk uninstall codex --home /tmp/custom-home', result: 'Uses the custom managed toolkit home while removing manifest-tracked installs from the selected target.' },
|
|
129
|
-
];
|
|
130
|
-
return [
|
|
131
|
-
buildBanner({ version, colorEnabled }),
|
|
132
|
-
'',
|
|
133
|
-
'Usage:',
|
|
134
|
-
` apltk uninstall [${buildModeUsagePattern()}]... [--yes]`,
|
|
135
|
-
'',
|
|
136
|
-
'Use this when:',
|
|
137
|
-
' - You want to remove Apollo Toolkit-managed skills from one or more agent targets.',
|
|
138
|
-
' - You need to clean up manifest-tracked historical installs as well as the current installed skills.',
|
|
139
|
-
'',
|
|
140
|
-
'Supported targets:',
|
|
141
|
-
buildSupportedTargetLines({ targets: [...TARGET_DEFINITIONS], colorEnabled }),
|
|
142
|
-
'',
|
|
143
|
-
'Behavior notes:',
|
|
144
|
-
' - With no explicit targets, uninstall opens the interactive selector in a TTY and otherwise falls back to all targets.',
|
|
145
|
-
' - Uninstall removes manifest-tracked current and historical Apollo Toolkit skill directories.',
|
|
146
|
-
' - `--yes` skips the confirmation prompt after the target list is resolved.',
|
|
147
|
-
'',
|
|
148
|
-
'Options:',
|
|
149
|
-
' --home <path> Override Apollo Toolkit home directory',
|
|
150
|
-
' --yes, -y Skip uninstall confirmation',
|
|
151
|
-
' --help Show this uninstall help',
|
|
152
|
-
'',
|
|
153
|
-
'Examples:',
|
|
154
|
-
formatExamples(examples),
|
|
155
|
-
].join('\n');
|
|
156
|
-
}
|
|
11
|
+
import { formatAppError } from '../../tool-utils/dist/index.js';
|
|
12
|
+
import { InstallArgsParser } from './parsers/install-parser.js';
|
|
13
|
+
import { UninstallArgsParser } from './parsers/uninstall-parser.js';
|
|
14
|
+
import { ToolArgsParser } from './parsers/tool-parser.js';
|
|
15
|
+
import { HelpTextBuilder } from './help-text-builder.js';
|
|
157
16
|
function readPackageJson(sourceRoot) {
|
|
158
17
|
return JSON.parse(fs.readFileSync(path.join(sourceRoot, 'package.json'), 'utf8'));
|
|
159
18
|
}
|
|
160
19
|
function parseArguments(argv) {
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
result.showHelp = true;
|
|
182
|
-
}
|
|
183
|
-
else if (arg === '--yes' || arg === '-y') {
|
|
184
|
-
result.assumeYes = true;
|
|
185
|
-
}
|
|
186
|
-
else if (arg === '--home') {
|
|
187
|
-
const toolkitHome = args.shift();
|
|
188
|
-
if (!toolkitHome)
|
|
189
|
-
throw new Error('Missing value for --home');
|
|
190
|
-
result.toolkitHome = path.resolve(toolkitHome);
|
|
191
|
-
}
|
|
192
|
-
else {
|
|
193
|
-
result.modes.push(arg);
|
|
194
|
-
}
|
|
20
|
+
const firstArg = argv[0];
|
|
21
|
+
// Shared parser instances (eliminates double instantiation)
|
|
22
|
+
const installParser = new InstallArgsParser();
|
|
23
|
+
const toolParser = new ToolArgsParser();
|
|
24
|
+
// Dispatch table for all known command types
|
|
25
|
+
// ==== Collision zone (FIX-09) ====
|
|
26
|
+
// L55-190 and L349-360 are high-collision regions touched by dispatch,
|
|
27
|
+
// parser, and error-boundary changes. Modify with care.
|
|
28
|
+
// =================================
|
|
29
|
+
const commandParsers = new Map([
|
|
30
|
+
['install', installParser],
|
|
31
|
+
['uninstall', new UninstallArgsParser()],
|
|
32
|
+
['tools', toolParser],
|
|
33
|
+
['tool', toolParser],
|
|
34
|
+
]);
|
|
35
|
+
// Command dispatch: iterate parsers, first match wins
|
|
36
|
+
for (const [name, parser] of commandParsers) {
|
|
37
|
+
if (firstArg === name) {
|
|
38
|
+
const result = parser.parse(argv);
|
|
39
|
+
return parser.toParsedArguments(result);
|
|
195
40
|
}
|
|
196
|
-
if (result.showHelp)
|
|
197
|
-
result.helpTopic = 'uninstall';
|
|
198
|
-
return result;
|
|
199
41
|
}
|
|
200
|
-
|
|
201
|
-
args.shift();
|
|
202
|
-
const nextArg = args[0];
|
|
203
|
-
if (args.length === 0 || nextArg === '--help' || nextArg === '-h') {
|
|
204
|
-
result.command = 'tools-help';
|
|
205
|
-
result.showToolsHelp = true;
|
|
206
|
-
return result;
|
|
207
|
-
}
|
|
208
|
-
result.command = 'tool';
|
|
209
|
-
result.toolName = args.shift() || null;
|
|
210
|
-
result.toolArgs = args;
|
|
211
|
-
return result;
|
|
212
|
-
}
|
|
213
|
-
const firstArg = args[0];
|
|
42
|
+
// Direct tool name (no "tools" prefix) — route through the 'tool' dispatch table entry
|
|
214
43
|
if (firstArg && isKnownToolName(firstArg)) {
|
|
215
|
-
|
|
216
|
-
result.toolName = args.shift() || null;
|
|
217
|
-
result.toolArgs = args;
|
|
218
|
-
return result;
|
|
219
|
-
}
|
|
220
|
-
while (args.length > 0) {
|
|
221
|
-
const arg = args.shift();
|
|
222
|
-
if (arg === '--help' || arg === '-h') {
|
|
223
|
-
result.showHelp = true;
|
|
224
|
-
continue;
|
|
225
|
-
}
|
|
226
|
-
if (arg === '--home') {
|
|
227
|
-
const toolkitHome = args.shift();
|
|
228
|
-
if (!toolkitHome)
|
|
229
|
-
throw new Error('Missing value for --home');
|
|
230
|
-
result.toolkitHome = path.resolve(toolkitHome);
|
|
231
|
-
continue;
|
|
232
|
-
}
|
|
233
|
-
if (arg === '--symlink') {
|
|
234
|
-
result.linkMode = 'symlink';
|
|
235
|
-
continue;
|
|
236
|
-
}
|
|
237
|
-
if (arg === '--copy') {
|
|
238
|
-
result.linkMode = 'copy';
|
|
239
|
-
continue;
|
|
240
|
-
}
|
|
241
|
-
if (arg === 'install') {
|
|
242
|
-
result.explicitInstallCommand = true;
|
|
243
|
-
continue;
|
|
244
|
-
}
|
|
245
|
-
result.modes.push(arg);
|
|
246
|
-
}
|
|
247
|
-
if (result.showHelp) {
|
|
248
|
-
const installContextRequested = result.explicitInstallCommand
|
|
249
|
-
|| result.modes.length > 0
|
|
250
|
-
|| result.linkMode !== null
|
|
251
|
-
|| result.toolkitHome !== null;
|
|
252
|
-
result.helpTopic = installContextRequested ? 'install' : 'overview';
|
|
44
|
+
return toolParser.toParsedArguments(toolParser.parse(argv));
|
|
253
45
|
}
|
|
254
|
-
|
|
46
|
+
// Default: install (handles bare arguments like "codex", "--help", or empty argv)
|
|
47
|
+
return installParser.toParsedArguments(installParser.parse(argv));
|
|
255
48
|
}
|
|
256
49
|
function buildSymlinkInfo({ colorEnabled }) {
|
|
257
50
|
return [
|
|
@@ -326,7 +119,12 @@ function printUninstallSummary({ stdout, uninstallResult, env }) {
|
|
|
326
119
|
stdout.write(` Removed: ${result.removedSkills.length > 0 ? result.removedSkills.join(', ') : '(manifest only)'}\n`);
|
|
327
120
|
}
|
|
328
121
|
}
|
|
329
|
-
export {
|
|
122
|
+
export { InstallArgsParser } from './parsers/install-parser.js';
|
|
123
|
+
export { UninstallArgsParser } from './parsers/uninstall-parser.js';
|
|
124
|
+
export { ToolArgsParser } from './parsers/tool-parser.js';
|
|
125
|
+
export { HelpTextBuilder } from './help-text-builder.js';
|
|
126
|
+
export { normalizeParseError } from './parsers/parser-utils.js';
|
|
127
|
+
export { parseArguments, buildBanner, buildWelcomeScreen, registerAllTools };
|
|
330
128
|
export async function run(argv, context = {}) {
|
|
331
129
|
const __filename = fileURLToPath(import.meta.url);
|
|
332
130
|
const __dir = path.dirname(__filename);
|
|
@@ -335,6 +133,7 @@ export async function run(argv, context = {}) {
|
|
|
335
133
|
const stderr = context.stderr || process.stderr;
|
|
336
134
|
const stdin = context.stdin || process.stdin;
|
|
337
135
|
const env = context.env || process.env;
|
|
136
|
+
const stdioWriter = createStdioWriter({ stdout, stderr, env });
|
|
338
137
|
let packageJson = readPackageJson(sourceRoot);
|
|
339
138
|
try {
|
|
340
139
|
const parsed = parseArguments(argv);
|
|
@@ -342,23 +141,30 @@ export async function run(argv, context = {}) {
|
|
|
342
141
|
const colorEnabled = supportsColor(stdout, env);
|
|
343
142
|
if (parsed.helpTopic === 'overview')
|
|
344
143
|
await registerAllTools();
|
|
144
|
+
const builder = new HelpTextBuilder({ version: packageJson.version, colorEnabled });
|
|
345
145
|
const helpText = parsed.helpTopic === 'install'
|
|
346
|
-
?
|
|
146
|
+
? builder.install()
|
|
347
147
|
: parsed.helpTopic === 'uninstall'
|
|
348
|
-
?
|
|
349
|
-
:
|
|
148
|
+
? builder.uninstall()
|
|
149
|
+
: builder.overview();
|
|
350
150
|
stdout.write(`${helpText}\n`);
|
|
351
151
|
return 0;
|
|
352
152
|
}
|
|
353
153
|
if (parsed.showToolsHelp) {
|
|
354
154
|
await registerAllTools();
|
|
355
|
-
stdout.write(`${
|
|
155
|
+
stdout.write(`${new HelpTextBuilder({ version: packageJson.version, colorEnabled: supportsColor(stdout, env) }).toolsHelp()}\n`);
|
|
356
156
|
return 0;
|
|
357
157
|
}
|
|
158
|
+
// Tool dispatch error patterns (FIX-10):
|
|
159
|
+
// Pattern A (createToolRunner tools): handler throws -> caught internally ->
|
|
160
|
+
// formatAppError + return 1
|
|
161
|
+
// Pattern B (carryover tools): handler throws -> propagates through runTool ->
|
|
162
|
+
// CLI boundary catch -> formatAppError + return 1
|
|
163
|
+
// Both patterns converge on the same formatting at the boundary.
|
|
358
164
|
if (parsed.command === 'tool') {
|
|
359
165
|
await registerAllTools();
|
|
360
|
-
return (context.runTool || runTool)(parsed.toolName, parsed.toolArgs, {
|
|
361
|
-
sourceRoot, stdout, stderr, env, spawnCommand: context.spawnCommand,
|
|
166
|
+
return await (context.runTool || runTool)(parsed.toolName, parsed.toolArgs, {
|
|
167
|
+
sourceRoot, stdout, stderr, env, spawnCommand: context.spawnCommand, stdioWriter,
|
|
362
168
|
});
|
|
363
169
|
}
|
|
364
170
|
// Uninstall flow
|
|
@@ -465,7 +271,7 @@ export async function run(argv, context = {}) {
|
|
|
465
271
|
return 0;
|
|
466
272
|
}
|
|
467
273
|
catch (error) {
|
|
468
|
-
stderr
|
|
274
|
+
formatAppError(stderr, error);
|
|
469
275
|
return 1;
|
|
470
276
|
}
|
|
471
277
|
}
|
|
@@ -14,6 +14,7 @@ export declare function normalizeModes(inputModes: string[]): InstallMode[];
|
|
|
14
14
|
export declare function listSkillNames(rootDir: string, modes?: InstallMode[]): Promise<string[]>;
|
|
15
15
|
export declare function listCodexSkillNames(rootDir: string): Promise<string[]>;
|
|
16
16
|
export declare function readManifest(targetRoot: string): Promise<ManifestData | null>;
|
|
17
|
+
export declare function isSafeSkillName(skillName: string): boolean;
|
|
17
18
|
export declare function writeManifest(targetRoot: string, { version, linkMode, skills, previousSkills }: {
|
|
18
19
|
version: string;
|
|
19
20
|
linkMode: string;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import fsp from 'node:fs/promises';
|
|
3
|
-
import os from 'node:os';
|
|
4
3
|
import path from 'node:path';
|
|
4
|
+
import { createPlatformAdapter } from '../../tool-utils/dist/index.js';
|
|
5
|
+
const platformAdapter = createPlatformAdapter();
|
|
5
6
|
export const TARGET_DEFINITIONS = Object.freeze([
|
|
6
7
|
{ id: 'codex', label: 'Codex', description: '~/.codex/skills' },
|
|
7
8
|
{ id: 'openclaw', label: 'OpenClaw', description: '~/.openclaw/workspace*/skills' },
|
|
@@ -14,7 +15,7 @@ const COPY_FILES = new Set(['AGENTS.md', 'CHANGELOG.md', 'LICENSE', 'README.md',
|
|
|
14
15
|
const SKILLS_DIRNAME = 'skills';
|
|
15
16
|
export const MANIFEST_FILENAME = '.apollo-toolkit-manifest.json';
|
|
16
17
|
export function resolveHomeDirectory(env = process.env) {
|
|
17
|
-
return
|
|
18
|
+
return createPlatformAdapter().homeDir(env);
|
|
18
19
|
}
|
|
19
20
|
export function expandUserPath(inputPath, env = process.env) {
|
|
20
21
|
if (!inputPath)
|
|
@@ -99,12 +100,12 @@ export async function readManifest(targetRoot) {
|
|
|
99
100
|
return null;
|
|
100
101
|
}
|
|
101
102
|
}
|
|
102
|
-
function isSafeSkillName(skillName) {
|
|
103
|
+
export function isSafeSkillName(skillName) {
|
|
103
104
|
return typeof skillName === 'string'
|
|
104
105
|
&& skillName.length > 0
|
|
105
106
|
&& !skillName.includes('\0')
|
|
106
107
|
&& !skillName.includes('/')
|
|
107
|
-
&& !skillName.includes('\\')
|
|
108
|
+
&& !(skillName.includes('\\') && createPlatformAdapter().isWindows())
|
|
108
109
|
&& !path.isAbsolute(skillName)
|
|
109
110
|
&& skillName !== '.'
|
|
110
111
|
&& skillName !== '..';
|
|
@@ -125,7 +126,7 @@ export async function writeManifest(targetRoot, { version, linkMode, skills, pre
|
|
|
125
126
|
historicalSkills,
|
|
126
127
|
};
|
|
127
128
|
await fsp.mkdir(targetRoot, { recursive: true });
|
|
128
|
-
await fsp.writeFile(path.join(targetRoot, MANIFEST_FILENAME), `${JSON.stringify(manifest, null, 2)}
|
|
129
|
+
await fsp.writeFile(path.join(targetRoot, MANIFEST_FILENAME), `${JSON.stringify(manifest, null, 2)}${platformAdapter.EOL}`, 'utf8');
|
|
129
130
|
}
|
|
130
131
|
export async function listAllKnownSkillNames({ toolkitHome, modes = [], env = process.env }) {
|
|
131
132
|
const allNames = new Set();
|
|
@@ -186,7 +187,7 @@ async function stageToolkitContents({ sourceRoot, destinationRoot, version, mode
|
|
|
186
187
|
copiedEntries.push(entry.name);
|
|
187
188
|
}
|
|
188
189
|
const metadata = { version, installedAt: new Date().toISOString(), source: 'npm-package' };
|
|
189
|
-
await fsp.writeFile(path.join(destinationRoot, '.apollo-toolkit-install.json'), `${JSON.stringify(metadata, null, 2)}
|
|
190
|
+
await fsp.writeFile(path.join(destinationRoot, '.apollo-toolkit-install.json'), `${JSON.stringify(metadata, null, 2)}${platformAdapter.EOL}`, 'utf8');
|
|
190
191
|
return copiedEntries.sort();
|
|
191
192
|
}
|
|
192
193
|
export async function syncToolkitHome({ sourceRoot, toolkitHome, version, modes = [] }) {
|
|
@@ -297,9 +298,21 @@ async function replaceWithCopy(sourcePath, targetPath) {
|
|
|
297
298
|
await fsp.cp(sourcePath, targetPath, { recursive: true, force: true });
|
|
298
299
|
}
|
|
299
300
|
async function replaceWithSymlink(sourcePath, targetPath) {
|
|
301
|
+
const adapter = createPlatformAdapter();
|
|
300
302
|
await fsp.rm(targetPath, { recursive: true, force: true });
|
|
301
303
|
await ensureDirectory(path.dirname(targetPath));
|
|
302
|
-
|
|
304
|
+
try {
|
|
305
|
+
await fsp.symlink(sourcePath, targetPath, adapter.symlinkType());
|
|
306
|
+
}
|
|
307
|
+
catch (err) {
|
|
308
|
+
if (err.code === 'EPERM') {
|
|
309
|
+
process.stderr.write(`Warning: Symlink not supported (EPERM). Falling back to copy mode.${adapter.EOL}`);
|
|
310
|
+
await replaceWithCopy(sourcePath, targetPath);
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
throw err;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
303
316
|
}
|
|
304
317
|
export async function installLinks({ toolkitHome, modes, env = process.env, previousSkillNames = [], linkMode = 'copy', includeExclusiveSkills = false }) {
|
|
305
318
|
const normalizedModes = normalizeModes(modes);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ParsedArguments } from '../types.js';
|
|
2
|
+
import type { CommandParser, InstallCommand } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Parser for the install (default) command mode.
|
|
5
|
+
*
|
|
6
|
+
* Recognises:
|
|
7
|
+
* - Positional args: install keyword, mode names (codex, openclaw, ...)
|
|
8
|
+
* - --help / -h
|
|
9
|
+
* - --home <path>
|
|
10
|
+
* - --symlink, --copy
|
|
11
|
+
*/
|
|
12
|
+
export declare class InstallArgsParser implements CommandParser<InstallCommand> {
|
|
13
|
+
parse(argv: string[]): InstallCommand;
|
|
14
|
+
toParsedArguments(result: InstallCommand): ParsedArguments;
|
|
15
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { parseArgs } from 'node:util';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { UserInputError } from '../../../tool-utils/dist/index.js';
|
|
4
|
+
import { normalizeParseError } from './parser-utils.js';
|
|
5
|
+
/**
|
|
6
|
+
* Parser for the install (default) command mode.
|
|
7
|
+
*
|
|
8
|
+
* Recognises:
|
|
9
|
+
* - Positional args: install keyword, mode names (codex, openclaw, ...)
|
|
10
|
+
* - --help / -h
|
|
11
|
+
* - --home <path>
|
|
12
|
+
* - --symlink, --copy
|
|
13
|
+
*/
|
|
14
|
+
export class InstallArgsParser {
|
|
15
|
+
parse(argv) {
|
|
16
|
+
let showHelp = false;
|
|
17
|
+
let toolkitHome = null;
|
|
18
|
+
let linkMode = null;
|
|
19
|
+
let explicitInstallCommand = false;
|
|
20
|
+
const modes = [];
|
|
21
|
+
try {
|
|
22
|
+
const { values, positionals } = parseArgs({
|
|
23
|
+
args: argv,
|
|
24
|
+
allowPositionals: true,
|
|
25
|
+
options: {
|
|
26
|
+
help: { type: 'boolean', short: 'h' },
|
|
27
|
+
home: { type: 'string' },
|
|
28
|
+
symlink: { type: 'boolean' },
|
|
29
|
+
copy: { type: 'boolean' },
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
showHelp = values.help ?? false;
|
|
33
|
+
if (values.home) {
|
|
34
|
+
toolkitHome = path.resolve(values.home);
|
|
35
|
+
}
|
|
36
|
+
if (values.symlink) {
|
|
37
|
+
linkMode = 'symlink';
|
|
38
|
+
}
|
|
39
|
+
if (values.copy) {
|
|
40
|
+
linkMode = 'copy';
|
|
41
|
+
}
|
|
42
|
+
if (values.symlink && values.copy) {
|
|
43
|
+
throw new UserInputError('Cannot use both --symlink and --copy');
|
|
44
|
+
}
|
|
45
|
+
for (const pos of positionals) {
|
|
46
|
+
if (pos === 'install') {
|
|
47
|
+
explicitInstallCommand = true;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
modes.push(pos);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
normalizeParseError(err);
|
|
56
|
+
}
|
|
57
|
+
const helpTopic = showHelp
|
|
58
|
+
? (explicitInstallCommand || modes.length > 0 || linkMode !== null || toolkitHome !== null)
|
|
59
|
+
? 'install'
|
|
60
|
+
: 'overview'
|
|
61
|
+
: 'overview';
|
|
62
|
+
return {
|
|
63
|
+
command: 'install',
|
|
64
|
+
modes: modes,
|
|
65
|
+
showHelp,
|
|
66
|
+
toolkitHome,
|
|
67
|
+
linkMode,
|
|
68
|
+
explicitInstallCommand,
|
|
69
|
+
helpTopic,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
toParsedArguments(result) {
|
|
73
|
+
return {
|
|
74
|
+
command: 'install',
|
|
75
|
+
modes: result.modes,
|
|
76
|
+
showHelp: result.showHelp,
|
|
77
|
+
showToolsHelp: false,
|
|
78
|
+
toolkitHome: result.toolkitHome,
|
|
79
|
+
toolName: null,
|
|
80
|
+
toolArgs: [],
|
|
81
|
+
linkMode: result.linkMode,
|
|
82
|
+
assumeYes: false,
|
|
83
|
+
explicitInstallCommand: result.explicitInstallCommand,
|
|
84
|
+
helpTopic: result.helpTopic,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalises common parseArgs errors into user-facing UserInputErrors.
|
|
3
|
+
*
|
|
4
|
+
* Currently handles:
|
|
5
|
+
* - --home without a value
|
|
6
|
+
*
|
|
7
|
+
* Call this inside a catch block to normalise the error before propagating it.
|
|
8
|
+
*/
|
|
9
|
+
export declare function normalizeParseError(err: unknown): never;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { UserInputError } from '../../../tool-utils/dist/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Normalises common parseArgs errors into user-facing UserInputErrors.
|
|
4
|
+
*
|
|
5
|
+
* Currently handles:
|
|
6
|
+
* - --home without a value
|
|
7
|
+
*
|
|
8
|
+
* Call this inside a catch block to normalise the error before propagating it.
|
|
9
|
+
*/
|
|
10
|
+
export function normalizeParseError(err) {
|
|
11
|
+
const message = err.message;
|
|
12
|
+
if (message.includes('--home') && (message.includes('argument missing') || message.includes('value') || message.includes('ambiguous'))) {
|
|
13
|
+
throw new UserInputError('Missing value for --home');
|
|
14
|
+
}
|
|
15
|
+
throw err;
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ParsedArguments } from '../types.js';
|
|
2
|
+
import type { CommandParser, ToolCommand, ToolsHelpCommand } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Parser for tool-invocation modes.
|
|
5
|
+
*
|
|
6
|
+
* Two entry paths:
|
|
7
|
+
* 1. `tools` / `tool` prefix – argv[0] is 'tools' or 'tool'
|
|
8
|
+
* 2. Direct tool name – argv[0] is a known tool name (detected by caller)
|
|
9
|
+
*
|
|
10
|
+
* Returns a ToolsHelpCommand when no tool is named or --help is passed,
|
|
11
|
+
* otherwise returns a ToolCommand with the tool name and remaining args.
|
|
12
|
+
*/
|
|
13
|
+
export declare class ToolArgsParser implements CommandParser<ToolCommand | ToolsHelpCommand> {
|
|
14
|
+
parse(argv: string[]): ToolCommand | ToolsHelpCommand;
|
|
15
|
+
toParsedArguments(result: ToolCommand | ToolsHelpCommand): ParsedArguments;
|
|
16
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parser for tool-invocation modes.
|
|
3
|
+
*
|
|
4
|
+
* Two entry paths:
|
|
5
|
+
* 1. `tools` / `tool` prefix – argv[0] is 'tools' or 'tool'
|
|
6
|
+
* 2. Direct tool name – argv[0] is a known tool name (detected by caller)
|
|
7
|
+
*
|
|
8
|
+
* Returns a ToolsHelpCommand when no tool is named or --help is passed,
|
|
9
|
+
* otherwise returns a ToolCommand with the tool name and remaining args.
|
|
10
|
+
*/
|
|
11
|
+
export class ToolArgsParser {
|
|
12
|
+
parse(argv) {
|
|
13
|
+
const args = [...argv];
|
|
14
|
+
// Strip leading 'tools'/'tool' prefix if present
|
|
15
|
+
const hasToolsPrefix = args[0] === 'tools' || args[0] === 'tool';
|
|
16
|
+
if (hasToolsPrefix) {
|
|
17
|
+
args.shift();
|
|
18
|
+
}
|
|
19
|
+
if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
|
|
20
|
+
return { command: 'tools-help', showToolsHelp: true };
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
command: 'tool',
|
|
24
|
+
toolName: args.shift() ?? null,
|
|
25
|
+
toolArgs: args,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
toParsedArguments(result) {
|
|
29
|
+
if (result.command === 'tools-help') {
|
|
30
|
+
return {
|
|
31
|
+
command: 'tools-help',
|
|
32
|
+
modes: [],
|
|
33
|
+
showHelp: false,
|
|
34
|
+
showToolsHelp: true,
|
|
35
|
+
toolkitHome: null,
|
|
36
|
+
toolName: null,
|
|
37
|
+
toolArgs: [],
|
|
38
|
+
linkMode: null,
|
|
39
|
+
assumeYes: false,
|
|
40
|
+
explicitInstallCommand: false,
|
|
41
|
+
helpTopic: 'tools-help',
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
command: 'tool',
|
|
46
|
+
modes: [],
|
|
47
|
+
showHelp: false,
|
|
48
|
+
showToolsHelp: false,
|
|
49
|
+
toolkitHome: null,
|
|
50
|
+
toolName: result.toolName,
|
|
51
|
+
toolArgs: result.toolArgs,
|
|
52
|
+
linkMode: null,
|
|
53
|
+
assumeYes: false,
|
|
54
|
+
explicitInstallCommand: false,
|
|
55
|
+
helpTopic: 'overview',
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|