@laitszkin/apollo-toolkit 4.1.3 → 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 +45 -0
- package/bin/apollo-toolkit.ts +4 -0
- package/dist/bin/apollo-toolkit.js +4 -0
- package/package.json +7 -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 +21 -17
- package/packages/tools/codegraph/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/codegraph/index.ts +21 -17
- 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
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { buildBanner, buildSupportedTargetLines } from '@laitszkin/tui';
|
|
2
|
+
import { formatToolList, buildToolDiscoveryHelp, formatExamples } from '@laitszkin/tool-registry';
|
|
3
|
+
import { TARGET_DEFINITIONS, VALID_MODES } from './installer.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Produces the four help text sections previously generated by standalone
|
|
7
|
+
* functions. Each method returns text identical to the original builder so
|
|
8
|
+
* that observable CLI output is unchanged.
|
|
9
|
+
*/
|
|
10
|
+
export class HelpTextBuilder {
|
|
11
|
+
private version: string;
|
|
12
|
+
private colorEnabled: boolean;
|
|
13
|
+
|
|
14
|
+
constructor({ version, colorEnabled }: { version: string; colorEnabled: boolean }) {
|
|
15
|
+
this.version = version;
|
|
16
|
+
this.colorEnabled = colorEnabled;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// ---- shared helpers -------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
private modeUsagePattern(): string {
|
|
22
|
+
return `${VALID_MODES.join('|')}|all`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
private joinLines(lines: (string | undefined | null | false)[]): string {
|
|
26
|
+
return lines.filter(Boolean).join('\n');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ---- public methods -------------------------------------------------------
|
|
30
|
+
|
|
31
|
+
/** Replaces buildHelpText – top-level overview help. */
|
|
32
|
+
overview(): string {
|
|
33
|
+
const examples = [
|
|
34
|
+
{ command: 'apltk --help', result: 'Shows the top-level Apollo Toolkit guide, including install modes and bundled task-tool discovery.' },
|
|
35
|
+
{ command: 'apltk tools --help', result: 'Lists bundled tools by task so you can decide which CLI helper to inspect next.' },
|
|
36
|
+
{ command: 'apltk architecture --help', result: 'Shows the architecture atlas command tree, task guidance, and action-specific follow-up help paths.' },
|
|
37
|
+
{ command: 'apltk tools architecture --help', result: 'Shows what the architecture atlas tool is for, then prints its native command tree and examples.' },
|
|
38
|
+
{ 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.' },
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
return this.joinLines([
|
|
42
|
+
buildBanner({ version: this.version, colorEnabled: this.colorEnabled }),
|
|
43
|
+
'',
|
|
44
|
+
'Usage:',
|
|
45
|
+
` apltk [install] [${this.modeUsagePattern()}]...`,
|
|
46
|
+
` apollo-toolkit [install] [${this.modeUsagePattern()}]...`,
|
|
47
|
+
` apltk uninstall [${this.modeUsagePattern()}]... [--yes]`,
|
|
48
|
+
' apltk tools',
|
|
49
|
+
' apltk <tool> [...args]',
|
|
50
|
+
' apltk tools <tool> [...args]',
|
|
51
|
+
' apltk --help',
|
|
52
|
+
' apollo-toolkit --help',
|
|
53
|
+
'',
|
|
54
|
+
'Common goals:',
|
|
55
|
+
' - Install or refresh skills in one or more agent targets: `apltk install --help`',
|
|
56
|
+
' - Remove manifest-tracked installs from selected targets: `apltk uninstall --help`',
|
|
57
|
+
' - Discover which bundled helper tool matches a task: `apltk tools --help`',
|
|
58
|
+
' - Inspect one tool deeply before running it: `apltk tools <tool> --help`',
|
|
59
|
+
'',
|
|
60
|
+
'Bundled tools:',
|
|
61
|
+
formatToolList(),
|
|
62
|
+
'',
|
|
63
|
+
buildToolDiscoveryHelp(),
|
|
64
|
+
'',
|
|
65
|
+
'Options:',
|
|
66
|
+
' --home <path> Override Apollo Toolkit home directory',
|
|
67
|
+
' --symlink Install skills as symlinks instead of copied directories',
|
|
68
|
+
' --copy Install skills as copied directories instead of symlinks',
|
|
69
|
+
' --yes, -y Skip uninstall confirmation',
|
|
70
|
+
' --help Show this help text',
|
|
71
|
+
'',
|
|
72
|
+
'Examples:',
|
|
73
|
+
formatExamples(examples),
|
|
74
|
+
]);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Replaces buildInstallHelpText – install-specific help. */
|
|
78
|
+
install(): string {
|
|
79
|
+
const examples = [
|
|
80
|
+
{ command: 'apltk', result: 'Launches the interactive installer, opens the target selector, and then walks through link-mode confirmation.' },
|
|
81
|
+
{ command: 'apltk codex openclaw --symlink', result: 'Performs a non-interactive install into `codex` and `openclaw` targets using symlinks.' },
|
|
82
|
+
{ command: 'npx @laitszkin/apollo-toolkit all --copy', result: 'Installs a copied snapshot into every supported target instead of symlinking.' },
|
|
83
|
+
];
|
|
84
|
+
|
|
85
|
+
return this.joinLines([
|
|
86
|
+
buildBanner({ version: this.version, colorEnabled: this.colorEnabled }),
|
|
87
|
+
'',
|
|
88
|
+
'Usage:',
|
|
89
|
+
` apltk [install] [${this.modeUsagePattern()}]...`,
|
|
90
|
+
` apollo-toolkit [install] [${this.modeUsagePattern()}]...`,
|
|
91
|
+
'',
|
|
92
|
+
'Use this when:',
|
|
93
|
+
' - You want to install or refresh Apollo Toolkit skills in one or more agent targets.',
|
|
94
|
+
' - You need to choose between symlink mode (auto-updating) and copy mode (stable snapshot).',
|
|
95
|
+
'',
|
|
96
|
+
'Supported targets:',
|
|
97
|
+
buildSupportedTargetLines({ targets: [...TARGET_DEFINITIONS], colorEnabled: this.colorEnabled }),
|
|
98
|
+
'',
|
|
99
|
+
'Behavior notes:',
|
|
100
|
+
' - Running `apltk` with no targets opens the interactive installer and target selector.',
|
|
101
|
+
' - `--symlink` keeps installed skills connected to the managed toolkit checkout in `~/.apollo-toolkit`.',
|
|
102
|
+
' - `--copy` installs a snapshot that only changes when you run the installer again.',
|
|
103
|
+
' - The installer can optionally include codex-exclusive skills in non-codex targets after prompting.',
|
|
104
|
+
'',
|
|
105
|
+
'Options:',
|
|
106
|
+
' --home <path> Override Apollo Toolkit home directory',
|
|
107
|
+
' --symlink Install skills as symlinks (recommended)',
|
|
108
|
+
' --copy Install skills as copied directories',
|
|
109
|
+
' --help Show this install help',
|
|
110
|
+
'',
|
|
111
|
+
'Examples:',
|
|
112
|
+
formatExamples(examples),
|
|
113
|
+
]);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Replaces buildUninstallHelpText – uninstall-specific help. */
|
|
117
|
+
uninstall(): string {
|
|
118
|
+
const examples = [
|
|
119
|
+
{ command: 'apltk uninstall', result: 'Opens the interactive uninstall selector when running in a TTY and then asks for confirmation before removal.' },
|
|
120
|
+
{ command: 'apltk uninstall codex agents --yes', result: 'Removes Apollo Toolkit-managed installs from `codex` and `agents` without another confirmation prompt.' },
|
|
121
|
+
{ command: 'apltk uninstall codex --home /tmp/custom-home', result: 'Uses the custom managed toolkit home while removing manifest-tracked installs from the selected target.' },
|
|
122
|
+
];
|
|
123
|
+
|
|
124
|
+
return this.joinLines([
|
|
125
|
+
buildBanner({ version: this.version, colorEnabled: this.colorEnabled }),
|
|
126
|
+
'',
|
|
127
|
+
'Usage:',
|
|
128
|
+
` apltk uninstall [${this.modeUsagePattern()}]... [--yes]`,
|
|
129
|
+
'',
|
|
130
|
+
'Use this when:',
|
|
131
|
+
' - You want to remove Apollo Toolkit-managed skills from one or more agent targets.',
|
|
132
|
+
' - You need to clean up manifest-tracked historical installs as well as the current installed skills.',
|
|
133
|
+
'',
|
|
134
|
+
'Supported targets:',
|
|
135
|
+
buildSupportedTargetLines({ targets: [...TARGET_DEFINITIONS], colorEnabled: this.colorEnabled }),
|
|
136
|
+
'',
|
|
137
|
+
'Behavior notes:',
|
|
138
|
+
' - With no explicit targets, uninstall opens the interactive selector in a TTY and otherwise falls back to all targets.',
|
|
139
|
+
' - Uninstall removes manifest-tracked current and historical Apollo Toolkit skill directories.',
|
|
140
|
+
' - `--yes` skips the confirmation prompt after the target list is resolved.',
|
|
141
|
+
'',
|
|
142
|
+
'Options:',
|
|
143
|
+
' --home <path> Override Apollo Toolkit home directory',
|
|
144
|
+
' --yes, -y Skip uninstall confirmation',
|
|
145
|
+
' --help Show this uninstall help',
|
|
146
|
+
'',
|
|
147
|
+
'Examples:',
|
|
148
|
+
formatExamples(examples),
|
|
149
|
+
]);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** Replaces buildToolsHelp – tools listing help screen. */
|
|
153
|
+
toolsHelp(): string {
|
|
154
|
+
const examples = [
|
|
155
|
+
{ command: 'apltk tools', result: 'Lists all bundled tools plus the task-oriented discovery guide.' },
|
|
156
|
+
{ command: 'apltk tools open-github-issue --help', result: 'Shows when to use the GitHub issue publisher, then prints its exact script flags and examples.' },
|
|
157
|
+
{ command: 'apltk tools architecture --help', result: 'Shows when to use the architecture atlas CLI, then prints its native command tree.' },
|
|
158
|
+
];
|
|
159
|
+
|
|
160
|
+
return this.joinLines([
|
|
161
|
+
buildBanner({ version: this.version, colorEnabled: this.colorEnabled }),
|
|
162
|
+
'',
|
|
163
|
+
'Usage:',
|
|
164
|
+
' apltk tools',
|
|
165
|
+
' apltk <tool> [...args]',
|
|
166
|
+
' apltk tools <tool> [...args]',
|
|
167
|
+
'',
|
|
168
|
+
buildToolDiscoveryHelp(),
|
|
169
|
+
'',
|
|
170
|
+
'Bundled tools:',
|
|
171
|
+
formatToolList(),
|
|
172
|
+
'',
|
|
173
|
+
'Tip:',
|
|
174
|
+
' Pass `--help` after a tool name to view task guidance, native script flags, and concrete examples.',
|
|
175
|
+
'',
|
|
176
|
+
'Examples:',
|
|
177
|
+
formatExamples(examples),
|
|
178
|
+
]);
|
|
179
|
+
}
|
|
180
|
+
}
|
package/packages/cli/index.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
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, supportsAnimation, buildBanner, buildWordmark, buildWelcomeScreen, buildSupportedTargetLines, renderSelectionScreen, animateWelcomeScreen, promptYesNo, promptForModes, isInteractive } from '@laitszkin/tui';
|
|
5
|
-
import type { TargetDefinition } from '@laitszkin/tui';
|
|
6
|
-
import {
|
|
7
|
-
import { formatExamples } from '@laitszkin/tool-registry';
|
|
4
|
+
import { color, supportsColor, supportsAnimation, buildBanner, buildWordmark, buildWelcomeScreen, buildSupportedTargetLines, renderSelectionScreen, animateWelcomeScreen, promptYesNo, promptForModes, isInteractive, createStdioWriter } from '@laitszkin/tui';
|
|
5
|
+
import type { TargetDefinition, StdioWriter } from '@laitszkin/tui';
|
|
6
|
+
import { runTool } from '@laitszkin/tool-registry';
|
|
8
7
|
import {
|
|
9
8
|
TARGET_DEFINITIONS,
|
|
10
9
|
VALID_MODES,
|
|
@@ -49,257 +48,52 @@ export {
|
|
|
49
48
|
execCommand,
|
|
50
49
|
};
|
|
51
50
|
import type { CliContext, InstallMode, ParsedArguments } from './types.js';
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const quotedModes = [...VALID_MODES, 'all'].map((mode) => `\`${mode}\``);
|
|
59
|
-
return `${quotedModes.slice(0, -1).join(', ')}, or ${quotedModes.at(-1)}`;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function buildHelpText({ version, colorEnabled }: { version: string; colorEnabled: boolean }): string {
|
|
63
|
-
const examples = [
|
|
64
|
-
{ command: 'apltk --help', result: 'Shows the top-level Apollo Toolkit guide, including install modes and bundled task-tool discovery.' },
|
|
65
|
-
{ command: 'apltk tools --help', result: 'Lists bundled tools by task so you can decide which CLI helper to inspect next.' },
|
|
66
|
-
{ command: 'apltk architecture --help', result: 'Shows the architecture atlas command tree, task guidance, and action-specific follow-up help paths.' },
|
|
67
|
-
{ command: 'apltk tools architecture --help', result: 'Shows what the architecture atlas tool is for, then prints its native command tree and examples.' },
|
|
68
|
-
{ 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.' },
|
|
69
|
-
];
|
|
70
|
-
return [
|
|
71
|
-
buildBanner({ version, colorEnabled }),
|
|
72
|
-
'',
|
|
73
|
-
'Usage:',
|
|
74
|
-
` apltk [install] [${buildModeUsagePattern()}]...`,
|
|
75
|
-
` apollo-toolkit [install] [${buildModeUsagePattern()}]...`,
|
|
76
|
-
` apltk uninstall [${buildModeUsagePattern()}]... [--yes]`,
|
|
77
|
-
' apltk tools',
|
|
78
|
-
' apltk <tool> [...args]',
|
|
79
|
-
' apltk tools <tool> [...args]',
|
|
80
|
-
' apltk --help',
|
|
81
|
-
' apollo-toolkit --help',
|
|
82
|
-
'',
|
|
83
|
-
'Common goals:',
|
|
84
|
-
' - Install or refresh skills in one or more agent targets: `apltk install --help`',
|
|
85
|
-
' - Remove manifest-tracked installs from selected targets: `apltk uninstall --help`',
|
|
86
|
-
' - Discover which bundled helper tool matches a task: `apltk tools --help`',
|
|
87
|
-
' - Inspect one tool deeply before running it: `apltk tools <tool> --help`',
|
|
88
|
-
'',
|
|
89
|
-
'Bundled tools:',
|
|
90
|
-
formatToolList(),
|
|
91
|
-
'',
|
|
92
|
-
buildToolDiscoveryHelp(),
|
|
93
|
-
'',
|
|
94
|
-
'Options:',
|
|
95
|
-
' --home <path> Override Apollo Toolkit home directory',
|
|
96
|
-
' --symlink Install skills as symlinks instead of copied directories',
|
|
97
|
-
' --copy Install skills as copied directories instead of symlinks',
|
|
98
|
-
' --yes, -y Skip uninstall confirmation',
|
|
99
|
-
' --help Show this help text',
|
|
100
|
-
'',
|
|
101
|
-
'Examples:',
|
|
102
|
-
formatExamples(examples),
|
|
103
|
-
].join('\n');
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function buildToolsHelp({ version, colorEnabled }: { version: string; colorEnabled: boolean }): string {
|
|
107
|
-
const examples = [
|
|
108
|
-
{ command: 'apltk tools', result: 'Lists all bundled tools plus the task-oriented discovery guide.' },
|
|
109
|
-
{ command: 'apltk tools open-github-issue --help', result: 'Shows when to use the GitHub issue publisher, then prints its exact script flags and examples.' },
|
|
110
|
-
{ command: 'apltk tools architecture --help', result: 'Shows when to use the architecture atlas CLI, then prints its native command tree.' },
|
|
111
|
-
];
|
|
112
|
-
return [
|
|
113
|
-
buildBanner({ version, colorEnabled }),
|
|
114
|
-
'',
|
|
115
|
-
'Usage:',
|
|
116
|
-
' apltk tools',
|
|
117
|
-
' apltk <tool> [...args]',
|
|
118
|
-
' apltk tools <tool> [...args]',
|
|
119
|
-
'',
|
|
120
|
-
buildToolDiscoveryHelp(),
|
|
121
|
-
'',
|
|
122
|
-
'Bundled tools:',
|
|
123
|
-
formatToolList(),
|
|
124
|
-
'',
|
|
125
|
-
'Tip:',
|
|
126
|
-
' Pass `--help` after a tool name to view task guidance, native script flags, and concrete examples.',
|
|
127
|
-
'',
|
|
128
|
-
'Examples:',
|
|
129
|
-
formatExamples(examples),
|
|
130
|
-
].join('\n');
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function buildInstallHelpText({ version, colorEnabled }: { version: string; colorEnabled: boolean }): string {
|
|
134
|
-
const examples = [
|
|
135
|
-
{ command: 'apltk', result: 'Launches the interactive installer, opens the target selector, and then walks through link-mode confirmation.' },
|
|
136
|
-
{ command: 'apltk codex openclaw --symlink', result: 'Performs a non-interactive install into `codex` and `openclaw` targets using symlinks.' },
|
|
137
|
-
{ command: 'npx @laitszkin/apollo-toolkit all --copy', result: 'Installs a copied snapshot into every supported target instead of symlinking.' },
|
|
138
|
-
];
|
|
139
|
-
return [
|
|
140
|
-
buildBanner({ version, colorEnabled }),
|
|
141
|
-
'',
|
|
142
|
-
'Usage:',
|
|
143
|
-
` apltk [install] [${buildModeUsagePattern()}]...`,
|
|
144
|
-
` apollo-toolkit [install] [${buildModeUsagePattern()}]...`,
|
|
145
|
-
'',
|
|
146
|
-
'Use this when:',
|
|
147
|
-
' - You want to install or refresh Apollo Toolkit skills in one or more agent targets.',
|
|
148
|
-
' - You need to choose between symlink mode (auto-updating) and copy mode (stable snapshot).',
|
|
149
|
-
'',
|
|
150
|
-
'Supported targets:',
|
|
151
|
-
buildSupportedTargetLines({ targets: [...TARGET_DEFINITIONS], colorEnabled }),
|
|
152
|
-
'',
|
|
153
|
-
'Behavior notes:',
|
|
154
|
-
' - Running `apltk` with no targets opens the interactive installer and target selector.',
|
|
155
|
-
' - `--symlink` keeps installed skills connected to the managed toolkit checkout in `~/.apollo-toolkit`.',
|
|
156
|
-
' - `--copy` installs a snapshot that only changes when you run the installer again.',
|
|
157
|
-
' - The installer can optionally include codex-exclusive skills in non-codex targets after prompting.',
|
|
158
|
-
'',
|
|
159
|
-
'Options:',
|
|
160
|
-
' --home <path> Override Apollo Toolkit home directory',
|
|
161
|
-
' --symlink Install skills as symlinks (recommended)',
|
|
162
|
-
' --copy Install skills as copied directories',
|
|
163
|
-
' --help Show this install help',
|
|
164
|
-
'',
|
|
165
|
-
'Examples:',
|
|
166
|
-
formatExamples(examples),
|
|
167
|
-
].join('\n');
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
function buildUninstallHelpText({ version, colorEnabled }: { version: string; colorEnabled: boolean }): string {
|
|
171
|
-
const examples = [
|
|
172
|
-
{ command: 'apltk uninstall', result: 'Opens the interactive uninstall selector when running in a TTY and then asks for confirmation before removal.' },
|
|
173
|
-
{ command: 'apltk uninstall codex agents --yes', result: 'Removes Apollo Toolkit-managed installs from `codex` and `agents` without another confirmation prompt.' },
|
|
174
|
-
{ command: 'apltk uninstall codex --home /tmp/custom-home', result: 'Uses the custom managed toolkit home while removing manifest-tracked installs from the selected target.' },
|
|
175
|
-
];
|
|
176
|
-
return [
|
|
177
|
-
buildBanner({ version, colorEnabled }),
|
|
178
|
-
'',
|
|
179
|
-
'Usage:',
|
|
180
|
-
` apltk uninstall [${buildModeUsagePattern()}]... [--yes]`,
|
|
181
|
-
'',
|
|
182
|
-
'Use this when:',
|
|
183
|
-
' - You want to remove Apollo Toolkit-managed skills from one or more agent targets.',
|
|
184
|
-
' - You need to clean up manifest-tracked historical installs as well as the current installed skills.',
|
|
185
|
-
'',
|
|
186
|
-
'Supported targets:',
|
|
187
|
-
buildSupportedTargetLines({ targets: [...TARGET_DEFINITIONS], colorEnabled }),
|
|
188
|
-
'',
|
|
189
|
-
'Behavior notes:',
|
|
190
|
-
' - With no explicit targets, uninstall opens the interactive selector in a TTY and otherwise falls back to all targets.',
|
|
191
|
-
' - Uninstall removes manifest-tracked current and historical Apollo Toolkit skill directories.',
|
|
192
|
-
' - `--yes` skips the confirmation prompt after the target list is resolved.',
|
|
193
|
-
'',
|
|
194
|
-
'Options:',
|
|
195
|
-
' --home <path> Override Apollo Toolkit home directory',
|
|
196
|
-
' --yes, -y Skip uninstall confirmation',
|
|
197
|
-
' --help Show this uninstall help',
|
|
198
|
-
'',
|
|
199
|
-
'Examples:',
|
|
200
|
-
formatExamples(examples),
|
|
201
|
-
].join('\n');
|
|
202
|
-
}
|
|
51
|
+
import type { CommandParser } from './parsers/types.js';
|
|
52
|
+
import { formatAppError } from '@laitszkin/tool-utils';
|
|
53
|
+
import { InstallArgsParser } from './parsers/install-parser.js';
|
|
54
|
+
import { UninstallArgsParser } from './parsers/uninstall-parser.js';
|
|
55
|
+
import { ToolArgsParser } from './parsers/tool-parser.js';
|
|
56
|
+
import { HelpTextBuilder } from './help-text-builder.js';
|
|
203
57
|
|
|
204
58
|
function readPackageJson(sourceRoot: string): { version: string; name: string } {
|
|
205
59
|
return JSON.parse(fs.readFileSync(path.join(sourceRoot, 'package.json'), 'utf8'));
|
|
206
60
|
}
|
|
207
61
|
|
|
208
62
|
function parseArguments(argv: string[]): ParsedArguments {
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
} else if (arg === '--home') {
|
|
234
|
-
const toolkitHome = args.shift();
|
|
235
|
-
if (!toolkitHome) throw new Error('Missing value for --home');
|
|
236
|
-
result.toolkitHome = path.resolve(toolkitHome);
|
|
237
|
-
} else {
|
|
238
|
-
result.modes.push(arg as InstallMode);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
if (result.showHelp) result.helpTopic = 'uninstall';
|
|
242
|
-
return result;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
if (args[0] === 'tools' || args[0] === 'tool') {
|
|
246
|
-
args.shift();
|
|
247
|
-
const nextArg: string | undefined = args[0];
|
|
248
|
-
if (args.length === 0 || nextArg === '--help' || nextArg === '-h') {
|
|
249
|
-
result.command = 'tools-help';
|
|
250
|
-
result.showToolsHelp = true;
|
|
251
|
-
return result;
|
|
63
|
+
const firstArg = argv[0];
|
|
64
|
+
|
|
65
|
+
// Shared parser instances (eliminates double instantiation)
|
|
66
|
+
const installParser = new InstallArgsParser();
|
|
67
|
+
const toolParser = new ToolArgsParser();
|
|
68
|
+
|
|
69
|
+
// Dispatch table for all known command types
|
|
70
|
+
// ==== Collision zone (FIX-09) ====
|
|
71
|
+
// L55-190 and L349-360 are high-collision regions touched by dispatch,
|
|
72
|
+
// parser, and error-boundary changes. Modify with care.
|
|
73
|
+
// =================================
|
|
74
|
+
|
|
75
|
+
const commandParsers = new Map<string, CommandParser<any>>([
|
|
76
|
+
['install', installParser],
|
|
77
|
+
['uninstall', new UninstallArgsParser()],
|
|
78
|
+
['tools', toolParser],
|
|
79
|
+
['tool', toolParser],
|
|
80
|
+
]);
|
|
81
|
+
|
|
82
|
+
// Command dispatch: iterate parsers, first match wins
|
|
83
|
+
for (const [name, parser] of commandParsers) {
|
|
84
|
+
if (firstArg === name) {
|
|
85
|
+
const result = parser.parse(argv);
|
|
86
|
+
return parser.toParsedArguments(result);
|
|
252
87
|
}
|
|
253
|
-
result.command = 'tool';
|
|
254
|
-
result.toolName = args.shift() || null;
|
|
255
|
-
result.toolArgs = args;
|
|
256
|
-
return result;
|
|
257
88
|
}
|
|
258
89
|
|
|
259
|
-
|
|
90
|
+
// Direct tool name (no "tools" prefix) — route through the 'tool' dispatch table entry
|
|
260
91
|
if (firstArg && isKnownToolName(firstArg)) {
|
|
261
|
-
|
|
262
|
-
result.toolName = args.shift() || null;
|
|
263
|
-
result.toolArgs = args;
|
|
264
|
-
return result;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
while (args.length > 0) {
|
|
268
|
-
const arg = args.shift()!;
|
|
269
|
-
if (arg === '--help' || arg === '-h') {
|
|
270
|
-
result.showHelp = true;
|
|
271
|
-
continue;
|
|
272
|
-
}
|
|
273
|
-
if (arg === '--home') {
|
|
274
|
-
const toolkitHome = args.shift();
|
|
275
|
-
if (!toolkitHome) throw new Error('Missing value for --home');
|
|
276
|
-
result.toolkitHome = path.resolve(toolkitHome);
|
|
277
|
-
continue;
|
|
278
|
-
}
|
|
279
|
-
if (arg === '--symlink') {
|
|
280
|
-
result.linkMode = 'symlink';
|
|
281
|
-
continue;
|
|
282
|
-
}
|
|
283
|
-
if (arg === '--copy') {
|
|
284
|
-
result.linkMode = 'copy';
|
|
285
|
-
continue;
|
|
286
|
-
}
|
|
287
|
-
if (arg === 'install') {
|
|
288
|
-
result.explicitInstallCommand = true;
|
|
289
|
-
continue;
|
|
290
|
-
}
|
|
291
|
-
result.modes.push(arg as InstallMode);
|
|
92
|
+
return toolParser.toParsedArguments(toolParser.parse(argv));
|
|
292
93
|
}
|
|
293
94
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|| result.modes.length > 0
|
|
297
|
-
|| result.linkMode !== null
|
|
298
|
-
|| result.toolkitHome !== null;
|
|
299
|
-
result.helpTopic = installContextRequested ? 'install' : 'overview';
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
return result;
|
|
95
|
+
// Default: install (handles bare arguments like "codex", "--help", or empty argv)
|
|
96
|
+
return installParser.toParsedArguments(installParser.parse(argv));
|
|
303
97
|
}
|
|
304
98
|
|
|
305
99
|
function buildSymlinkInfo({ colorEnabled }: { colorEnabled: boolean }): string {
|
|
@@ -418,7 +212,13 @@ function printUninstallSummary({ stdout, uninstallResult, env }: {
|
|
|
418
212
|
}
|
|
419
213
|
}
|
|
420
214
|
|
|
421
|
-
export {
|
|
215
|
+
export { InstallArgsParser } from './parsers/install-parser.js';
|
|
216
|
+
export { UninstallArgsParser } from './parsers/uninstall-parser.js';
|
|
217
|
+
export { ToolArgsParser } from './parsers/tool-parser.js';
|
|
218
|
+
export { HelpTextBuilder } from './help-text-builder.js';
|
|
219
|
+
export { normalizeParseError } from './parsers/parser-utils.js';
|
|
220
|
+
|
|
221
|
+
export { parseArguments, buildBanner, buildWelcomeScreen, registerAllTools };
|
|
422
222
|
|
|
423
223
|
export async function run(argv: string[], context: CliContext = {}): Promise<number> {
|
|
424
224
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -428,6 +228,7 @@ export async function run(argv: string[], context: CliContext = {}): Promise<num
|
|
|
428
228
|
const stderr = context.stderr || process.stderr;
|
|
429
229
|
const stdin = context.stdin || process.stdin;
|
|
430
230
|
const env = context.env || process.env;
|
|
231
|
+
const stdioWriter: StdioWriter = createStdioWriter({ stdout, stderr, env });
|
|
431
232
|
let packageJson = readPackageJson(sourceRoot);
|
|
432
233
|
|
|
433
234
|
try {
|
|
@@ -436,25 +237,32 @@ export async function run(argv: string[], context: CliContext = {}): Promise<num
|
|
|
436
237
|
if (parsed.showHelp) {
|
|
437
238
|
const colorEnabled = supportsColor(stdout, env);
|
|
438
239
|
if (parsed.helpTopic === 'overview') await registerAllTools();
|
|
240
|
+
const builder = new HelpTextBuilder({ version: packageJson.version, colorEnabled });
|
|
439
241
|
const helpText = parsed.helpTopic === 'install'
|
|
440
|
-
?
|
|
242
|
+
? builder.install()
|
|
441
243
|
: parsed.helpTopic === 'uninstall'
|
|
442
|
-
?
|
|
443
|
-
:
|
|
244
|
+
? builder.uninstall()
|
|
245
|
+
: builder.overview();
|
|
444
246
|
stdout.write(`${helpText}\n`);
|
|
445
247
|
return 0;
|
|
446
248
|
}
|
|
447
249
|
|
|
448
250
|
if (parsed.showToolsHelp) {
|
|
449
251
|
await registerAllTools();
|
|
450
|
-
stdout.write(`${
|
|
252
|
+
stdout.write(`${new HelpTextBuilder({ version: packageJson.version, colorEnabled: supportsColor(stdout, env) }).toolsHelp()}\n`);
|
|
451
253
|
return 0;
|
|
452
254
|
}
|
|
453
255
|
|
|
256
|
+
// Tool dispatch error patterns (FIX-10):
|
|
257
|
+
// Pattern A (createToolRunner tools): handler throws -> caught internally ->
|
|
258
|
+
// formatAppError + return 1
|
|
259
|
+
// Pattern B (carryover tools): handler throws -> propagates through runTool ->
|
|
260
|
+
// CLI boundary catch -> formatAppError + return 1
|
|
261
|
+
// Both patterns converge on the same formatting at the boundary.
|
|
454
262
|
if (parsed.command === 'tool') {
|
|
455
263
|
await registerAllTools();
|
|
456
|
-
return (context.runTool || runTool)(parsed.toolName!, parsed.toolArgs, {
|
|
457
|
-
sourceRoot, stdout, stderr, env, spawnCommand: context.spawnCommand,
|
|
264
|
+
return await (context.runTool || runTool)(parsed.toolName!, parsed.toolArgs, {
|
|
265
|
+
sourceRoot, stdout, stderr, env, spawnCommand: context.spawnCommand, stdioWriter,
|
|
458
266
|
});
|
|
459
267
|
}
|
|
460
268
|
|
|
@@ -580,7 +388,7 @@ export async function run(argv: string[], context: CliContext = {}): Promise<num
|
|
|
580
388
|
printSummary({ stdout, version: packageJson.version, toolkitHome, modes, installResult, env });
|
|
581
389
|
return 0;
|
|
582
390
|
} catch (error) {
|
|
583
|
-
stderr
|
|
391
|
+
formatAppError(stderr, error);
|
|
584
392
|
return 1;
|
|
585
393
|
}
|
|
586
394
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
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 '@laitszkin/tool-utils';
|
|
5
5
|
import type { InstallMode, InstallTarget, ManifestData, SyncResult } from './types.js';
|
|
6
6
|
|
|
7
|
+
const platformAdapter = createPlatformAdapter();
|
|
8
|
+
|
|
7
9
|
export interface TargetDefinition {
|
|
8
10
|
id: InstallMode;
|
|
9
11
|
label: string;
|
|
@@ -24,7 +26,7 @@ const SKILLS_DIRNAME = 'skills';
|
|
|
24
26
|
export const MANIFEST_FILENAME = '.apollo-toolkit-manifest.json';
|
|
25
27
|
|
|
26
28
|
export function resolveHomeDirectory(env: NodeJS.ProcessEnv = process.env): string {
|
|
27
|
-
return
|
|
29
|
+
return createPlatformAdapter().homeDir(env);
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
export function expandUserPath(inputPath: string, env: NodeJS.ProcessEnv = process.env): string {
|
|
@@ -115,12 +117,12 @@ export async function readManifest(targetRoot: string): Promise<ManifestData | n
|
|
|
115
117
|
}
|
|
116
118
|
}
|
|
117
119
|
|
|
118
|
-
function isSafeSkillName(skillName: string): boolean {
|
|
120
|
+
export function isSafeSkillName(skillName: string): boolean {
|
|
119
121
|
return typeof skillName === 'string'
|
|
120
122
|
&& skillName.length > 0
|
|
121
123
|
&& !skillName.includes('\0')
|
|
122
124
|
&& !skillName.includes('/')
|
|
123
|
-
&& !skillName.includes('\\')
|
|
125
|
+
&& !(skillName.includes('\\') && createPlatformAdapter().isWindows())
|
|
124
126
|
&& !path.isAbsolute(skillName)
|
|
125
127
|
&& skillName !== '.'
|
|
126
128
|
&& skillName !== '..';
|
|
@@ -148,7 +150,7 @@ export async function writeManifest(
|
|
|
148
150
|
await fsp.mkdir(targetRoot, { recursive: true });
|
|
149
151
|
await fsp.writeFile(
|
|
150
152
|
path.join(targetRoot, MANIFEST_FILENAME),
|
|
151
|
-
`${JSON.stringify(manifest, null, 2)}
|
|
153
|
+
`${JSON.stringify(manifest, null, 2)}${platformAdapter.EOL}`,
|
|
152
154
|
'utf8',
|
|
153
155
|
);
|
|
154
156
|
}
|
|
@@ -229,7 +231,7 @@ async function stageToolkitContents({ sourceRoot, destinationRoot, version, mode
|
|
|
229
231
|
const metadata = { version, installedAt: new Date().toISOString(), source: 'npm-package' };
|
|
230
232
|
await fsp.writeFile(
|
|
231
233
|
path.join(destinationRoot, '.apollo-toolkit-install.json'),
|
|
232
|
-
`${JSON.stringify(metadata, null, 2)}
|
|
234
|
+
`${JSON.stringify(metadata, null, 2)}${platformAdapter.EOL}`,
|
|
233
235
|
'utf8',
|
|
234
236
|
);
|
|
235
237
|
return copiedEntries.sort();
|
|
@@ -357,9 +359,19 @@ async function replaceWithCopy(sourcePath: string, targetPath: string): Promise<
|
|
|
357
359
|
}
|
|
358
360
|
|
|
359
361
|
async function replaceWithSymlink(sourcePath: string, targetPath: string): Promise<void> {
|
|
362
|
+
const adapter = createPlatformAdapter();
|
|
360
363
|
await fsp.rm(targetPath, { recursive: true, force: true });
|
|
361
364
|
await ensureDirectory(path.dirname(targetPath));
|
|
362
|
-
|
|
365
|
+
try {
|
|
366
|
+
await fsp.symlink(sourcePath, targetPath, adapter.symlinkType());
|
|
367
|
+
} catch (err: unknown) {
|
|
368
|
+
if ((err as NodeJS.ErrnoException).code === 'EPERM') {
|
|
369
|
+
process.stderr.write(`Warning: Symlink not supported (EPERM). Falling back to copy mode.${adapter.EOL}`);
|
|
370
|
+
await replaceWithCopy(sourcePath, targetPath);
|
|
371
|
+
} else {
|
|
372
|
+
throw err;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
363
375
|
}
|
|
364
376
|
|
|
365
377
|
export async function installLinks({ toolkitHome, modes, env = process.env, previousSkillNames = [], linkMode = 'copy', includeExclusiveSkills = false }: {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@laitszkin/cli",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Apollo Toolkit
|
|
3
|
+
"version": "5.0.0",
|
|
4
|
+
"description": "Apollo Toolkit \u2014 CLI command management (install, uninstall, tool routing)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@laitszkin/tui": "*",
|
|
21
21
|
"@laitszkin/tool-registry": "*",
|
|
22
|
+
"@laitszkin/tool-utils": "*",
|
|
22
23
|
"@laitszkin/tool-filter-logs": "*",
|
|
23
24
|
"@laitszkin/tool-search-logs": "*",
|
|
24
25
|
"@laitszkin/tool-validate-skill-frontmatter": "*",
|
|
@@ -35,8 +36,10 @@
|
|
|
35
36
|
"@laitszkin/tool-generate-storyboard-images": "*",
|
|
36
37
|
"@laitszkin/tool-enforce-video-aspect-ratio": "*",
|
|
37
38
|
"@laitszkin/tool-architecture": "*",
|
|
39
|
+
"@laitszkin/tool-codegraph": "*",
|
|
38
40
|
"@laitszkin/tool-create-specs": "*",
|
|
39
41
|
"@laitszkin/tool-create-review-report": "*",
|
|
42
|
+
"@laitszkin/tool-eval": "*",
|
|
40
43
|
"@laitszkin/tool-extract-pdf-text": "*"
|
|
41
44
|
}
|
|
42
|
-
}
|
|
45
|
+
}
|