@liriraid/agentflow-ai 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +79 -0
  3. package/bin/agentflow.mjs +332 -0
  4. package/orchestrator.js +1585 -0
  5. package/package.json +64 -0
  6. package/scripts/scaffold-agent-configs.mjs +100 -0
  7. package/scripts/scaffold-openspec-change.mjs +84 -0
  8. package/scripts/update-skill-registry.mjs +174 -0
  9. package/src/ink/app.mjs +240 -0
  10. package/src/ink/index.mjs +400 -0
  11. package/templates/en/.atl/skill-registry.md +27 -0
  12. package/templates/en/.claude/README.md +7 -0
  13. package/templates/en/.claude/skills/orchestrator-apply/SKILL.md +31 -0
  14. package/templates/en/.claude/skills/orchestrator-archive/SKILL.md +26 -0
  15. package/templates/en/.claude/skills/orchestrator-design/SKILL.md +27 -0
  16. package/templates/en/.claude/skills/orchestrator-explore/SKILL.md +29 -0
  17. package/templates/en/.claude/skills/orchestrator-init/SKILL.md +32 -0
  18. package/templates/en/.claude/skills/orchestrator-memory/SKILL.md +26 -0
  19. package/templates/en/.claude/skills/orchestrator-openspec/SKILL.md +35 -0
  20. package/templates/en/.claude/skills/orchestrator-propose/SKILL.md +26 -0
  21. package/templates/en/.claude/skills/orchestrator-queue-planning/SKILL.md +31 -0
  22. package/templates/en/.claude/skills/orchestrator-spec/SKILL.md +27 -0
  23. package/templates/en/.claude/skills/orchestrator-tasks/SKILL.md +27 -0
  24. package/templates/en/.claude/skills/orchestrator-verify/SKILL.md +27 -0
  25. package/templates/en/.codex/README.md +7 -0
  26. package/templates/en/.opencode/README.md +7 -0
  27. package/templates/en/AGENT-CONFIG.md +75 -0
  28. package/templates/en/CLAUDE.md +91 -0
  29. package/templates/en/ENGRAM.md +50 -0
  30. package/templates/en/ORCHESTRATOR.md +192 -0
  31. package/templates/en/PROJECT.md +70 -0
  32. package/templates/en/QUEUE.md +17 -0
  33. package/templates/en/README.md +188 -0
  34. package/templates/en/agents/ABACUS.md +36 -0
  35. package/templates/en/agents/BACKEND.md +37 -0
  36. package/templates/en/agents/CODEX.md +45 -0
  37. package/templates/en/agents/CURSOR.md +37 -0
  38. package/templates/en/agents/FRONTEND.md +36 -0
  39. package/templates/en/agents/GEMINI.md +37 -0
  40. package/templates/en/agents/OPENCODE.md +41 -0
  41. package/templates/en/docs/README.md +14 -0
  42. package/templates/en/docs/agents.md +33 -0
  43. package/templates/en/docs/architecture.md +43 -0
  44. package/templates/en/docs/components.md +14 -0
  45. package/templates/en/docs/engram.md +16 -0
  46. package/templates/en/docs/openspec.md +32 -0
  47. package/templates/en/docs/usage.md +66 -0
  48. package/templates/en/openspec/FLOW.md +24 -0
  49. package/templates/en/openspec/README.md +29 -0
  50. package/templates/en/openspec/changes/.gitkeep +1 -0
  51. package/templates/en/openspec/changes/archive/.gitkeep +1 -0
  52. package/templates/en/openspec/specs/.gitkeep +1 -0
  53. package/templates/en/openspec/templates/archive-report.md +21 -0
  54. package/templates/en/openspec/templates/change-metadata.yaml +9 -0
  55. package/templates/en/openspec/templates/design.md +26 -0
  56. package/templates/en/openspec/templates/proposal.md +27 -0
  57. package/templates/en/openspec/templates/spec.md +18 -0
  58. package/templates/en/openspec/templates/tasks.md +14 -0
  59. package/templates/en/openspec/templates/verify-report.md +21 -0
  60. package/templates/en/orchestrator.config.json +99 -0
  61. package/templates/es/.atl/skill-registry.md +133 -0
  62. package/templates/es/.claude/README.md +7 -0
  63. package/templates/es/.claude/skills/orchestrator-apply/SKILL.md +32 -0
  64. package/templates/es/.claude/skills/orchestrator-archive/SKILL.md +28 -0
  65. package/templates/es/.claude/skills/orchestrator-design/SKILL.md +32 -0
  66. package/templates/es/.claude/skills/orchestrator-explore/SKILL.md +31 -0
  67. package/templates/es/.claude/skills/orchestrator-init/SKILL.md +32 -0
  68. package/templates/es/.claude/skills/orchestrator-memory/SKILL.md +31 -0
  69. package/templates/es/.claude/skills/orchestrator-openspec/SKILL.md +55 -0
  70. package/templates/es/.claude/skills/orchestrator-propose/SKILL.md +33 -0
  71. package/templates/es/.claude/skills/orchestrator-queue-planning/SKILL.md +35 -0
  72. package/templates/es/.claude/skills/orchestrator-spec/SKILL.md +28 -0
  73. package/templates/es/.claude/skills/orchestrator-tasks/SKILL.md +32 -0
  74. package/templates/es/.claude/skills/orchestrator-verify/SKILL.md +31 -0
  75. package/templates/es/.codex/README.md +7 -0
  76. package/templates/es/.opencode/README.md +7 -0
  77. package/templates/es/AGENT-CONFIG.md +83 -0
  78. package/templates/es/CLAUDE.md +136 -0
  79. package/templates/es/ENGRAM.md +70 -0
  80. package/templates/es/ORCHESTRATOR.md +199 -0
  81. package/templates/es/PROJECT.md +237 -0
  82. package/templates/es/QUEUE.md +17 -0
  83. package/templates/es/README.md +568 -0
  84. package/templates/es/agents/ABACUS.md +25 -0
  85. package/templates/es/agents/BACKEND.md +28 -0
  86. package/templates/es/agents/CODEX.md +37 -0
  87. package/templates/es/agents/CURSOR.md +27 -0
  88. package/templates/es/agents/FRONTEND.md +29 -0
  89. package/templates/es/agents/GEMINI.md +26 -0
  90. package/templates/es/agents/OPENCODE.md +32 -0
  91. package/templates/es/docs/README.md +12 -0
  92. package/templates/es/docs/agents.md +57 -0
  93. package/templates/es/docs/architecture.md +41 -0
  94. package/templates/es/docs/components.md +33 -0
  95. package/templates/es/docs/engram.md +30 -0
  96. package/templates/es/docs/openspec.md +34 -0
  97. package/templates/es/docs/usage.md +54 -0
  98. package/templates/es/openspec/FLOW.md +139 -0
  99. package/templates/es/openspec/README.md +77 -0
  100. package/templates/es/openspec/changes/.gitkeep +1 -0
  101. package/templates/es/openspec/changes/archive/.gitkeep +1 -0
  102. package/templates/es/openspec/specs/.gitkeep +1 -0
  103. package/templates/es/openspec/templates/archive-report.md +23 -0
  104. package/templates/es/openspec/templates/change-metadata.yaml +9 -0
  105. package/templates/es/openspec/templates/design.md +33 -0
  106. package/templates/es/openspec/templates/proposal.md +36 -0
  107. package/templates/es/openspec/templates/spec.md +33 -0
  108. package/templates/es/openspec/templates/tasks.md +22 -0
  109. package/templates/es/openspec/templates/verify-report.md +24 -0
  110. package/templates/es/orchestrator.config.json +99 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 LiriRaid
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # agentflow
2
+
3
+ Reusable multi-agent orchestration workspace for coding projects.
4
+
5
+ This package installs a CLI that creates a separate orchestrator workspace next to your real project. The generated workspace can be created in **English** or **Spanish**.
6
+
7
+ ```text
8
+ my-product-workspace/
9
+ my-product/ # real project, stays clean
10
+ orchestrator-my-product/ # generated orchestrator workspace
11
+ ```
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ npm i -g @liriraid/agentflow
17
+ ```
18
+
19
+ ## Create a Workspace
20
+
21
+ Interactive language selection:
22
+
23
+ ```bash
24
+ agentflow init-workspace C:/code/my-project
25
+ ```
26
+
27
+ Direct language selection:
28
+
29
+ ```bash
30
+ agentflow init-workspace C:/code/my-project --lang en
31
+ agentflow init-workspace C:/code/mi-proyecto --lang es
32
+ ```
33
+
34
+ The selected language controls the generated workspace files:
35
+
36
+ - `ORCHESTRATOR.md`
37
+ - `CLAUDE.md`
38
+ - `QUEUE.md`
39
+ - `PROJECT.md`
40
+ - `README.md`
41
+ - `agents/`
42
+ - `docs/`
43
+ - `openspec/`
44
+ - `.claude/`
45
+ - `.codex/`
46
+ - `.opencode/`
47
+ - `.atl/`
48
+ - `orchestrator.config.json`
49
+
50
+ ## Runtime
51
+
52
+ The package runtime remains language-aware through `workspaceLanguage` in the generated `orchestrator.config.json`.
53
+
54
+ Start the TUI from the generated orchestrator workspace:
55
+
56
+ ```bash
57
+ cd C:/code/orchestrator-my-project
58
+ agentflow ink --paused
59
+ ```
60
+
61
+ Then open Claude Code in the same workspace and start with the prompt from that workspace's `ORCHESTRATOR.md`.
62
+
63
+ ## What Gets Packaged
64
+
65
+ The npm package ships:
66
+
67
+ - `bin/`
68
+ - `src/`
69
+ - `scripts/`
70
+ - `templates/en/`
71
+ - `templates/es/`
72
+ - `orchestrator.js`
73
+ - `LICENSE`
74
+
75
+ The workspace docs and prompts live inside `templates/en` and `templates/es`; they are copied into the generated workspace based on the selected language.
76
+
77
+ ## Acknowledgements
78
+
79
+ Inspired by [Orquestador-AI](https://github.com/ariellontero/Orquestador-AI) by Ariel Lontero (originally MIT). Built from scratch with a different architecture (Ink TUI, npm package, multi-language template system).
@@ -0,0 +1,332 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+ import {fileURLToPath} from 'url';
6
+ import {spawn} from 'child_process';
7
+ import {createInterface} from 'readline/promises';
8
+ import {stdin as input, stdout as output} from 'process';
9
+
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const PACKAGE_ROOT = path.dirname(path.dirname(__filename));
12
+ const argv = process.argv.slice(2);
13
+
14
+ const TEMPLATE_PATHS = [
15
+ 'README.md',
16
+ 'ORCHESTRATOR.md',
17
+ 'CLAUDE.md',
18
+ 'ENGRAM.md',
19
+ 'AGENT-CONFIG.md',
20
+ 'PROJECT.md',
21
+ '.atl',
22
+ 'docs',
23
+ 'orchestrator.config.json',
24
+ 'QUEUE.md',
25
+ 'agents',
26
+ 'openspec',
27
+ '.claude',
28
+ '.codex',
29
+ '.opencode'
30
+ ];
31
+
32
+ const RUNTIME_DIRS = ['logs', 'handoffs', 'progress', 'briefs'];
33
+ const SUPPORTED_LANGUAGES = new Set(['en', 'es']);
34
+ const DEFAULT_LANGUAGE = 'en';
35
+ const TEXT = {
36
+ es: {
37
+ unsupported: value => `Idioma no soportado: ${value}. Usa "en" o "es".`,
38
+ missingTemplate: language => `No existe el template de idioma: ${language}`,
39
+ installed: target => `Orquestador instalado en ${target}`,
40
+ language: language => `Idioma del workspace: ${language.toUpperCase()}`,
41
+ next: 'Siguiente paso recomendado:',
42
+ step1: '1. Edita orchestrator.config.json con rutas reales',
43
+ step2: '2. Revisa ORCHESTRATOR.md, CLAUDE.md y docs/',
44
+ step3: '3. Ejecuta: agentflow ink --paused',
45
+ invalidProject: projectPath => `Ruta de proyecto inválida: ${projectPath}`,
46
+ realProject: projectPath => `Proyecto real: ${projectPath}`,
47
+ workspace: workspaceDir => `Workspace del orquestador: ${workspaceDir}`,
48
+ sibling:
49
+ 'Este workspace queda fuera del repo del proyecto, como sibling, para no ensuciarlo con archivos del orquestador.',
50
+ unknown: command => `Comando desconocido: ${command}`
51
+ },
52
+ en: {
53
+ unsupported: value => `Unsupported language: ${value}. Use "en" or "es".`,
54
+ missingTemplate: language => `Language template not found: ${language}`,
55
+ installed: target => `Orchestrator installed at ${target}`,
56
+ language: language => `Workspace language: ${language.toUpperCase()}`,
57
+ next: 'Recommended next steps:',
58
+ step1: '1. Edit orchestrator.config.json with real paths',
59
+ step2: '2. Review ORCHESTRATOR.md, CLAUDE.md, and docs/',
60
+ step3: '3. Run: agentflow ink --paused',
61
+ invalidProject: projectPath => `Invalid project path: ${projectPath}`,
62
+ realProject: projectPath => `Real project: ${projectPath}`,
63
+ workspace: workspaceDir => `Orchestrator workspace: ${workspaceDir}`,
64
+ sibling:
65
+ 'This workspace stays next to the real project as a sibling, so orchestrator files do not pollute the product repo.',
66
+ unknown: command => `Unknown command: ${command}`
67
+ }
68
+ };
69
+
70
+ function printHelp() {
71
+ console.log(`
72
+ agentflow
73
+
74
+ Uso:
75
+ agentflow init [targetDir] [--project-name <name>] [--backend <path>] [--frontend <path>] [--lang <en|es>] [--force]
76
+ agentflow init-workspace <projectPath> [--workspace-name <name>] [--backend <path>] [--frontend <path>] [--lang <en|es>] [--force]
77
+ agentflow tui [--paused] [--yolo]
78
+ agentflow ink [--paused] [--yolo]
79
+ agentflow skills:registry
80
+ agentflow openspec:new <change-name>
81
+ agentflow agent-config:init
82
+
83
+ Ejemplos:
84
+ agentflow init . --project-name "Mi Proyecto" --lang es
85
+ agentflow init-workspace C:/code/mi-proyecto --lang en
86
+ agentflow tui --paused
87
+ agentflow ink
88
+ `);
89
+ }
90
+
91
+ function parseFlags(args) {
92
+ const flags = {};
93
+ const rest = [];
94
+
95
+ for (let i = 0; i < args.length; i += 1) {
96
+ const current = args[i];
97
+ if (!current.startsWith('--')) {
98
+ rest.push(current);
99
+ continue;
100
+ }
101
+
102
+ const key = current.slice(2);
103
+ const next = args[i + 1];
104
+ if (!next || next.startsWith('--')) {
105
+ flags[key] = true;
106
+ continue;
107
+ }
108
+
109
+ flags[key] = next;
110
+ i += 1;
111
+ }
112
+
113
+ return {flags, rest};
114
+ }
115
+
116
+ function normalizeLanguage(value) {
117
+ if (!value || value === true) return null;
118
+ const normalized = String(value).trim().toLowerCase();
119
+ if (normalized === '1' || normalized === 'en' || normalized === 'english') return 'en';
120
+ if (normalized === '2' || normalized === 'es' || normalized === 'spanish' || normalized === 'espanol' || normalized === 'español') return 'es';
121
+ return null;
122
+ }
123
+
124
+ async function resolveLanguage(flagValue) {
125
+ const fromFlag = normalizeLanguage(flagValue);
126
+ if (fromFlag) return fromFlag;
127
+
128
+ if (flagValue && !fromFlag) {
129
+ console.warn(TEXT.es.unsupported(flagValue));
130
+ }
131
+
132
+ if (!process.stdin.isTTY || !process.stdout.isTTY) return DEFAULT_LANGUAGE;
133
+
134
+ const rl = createInterface({input, output});
135
+ try {
136
+ console.log('');
137
+ console.log('Selecciona el idioma del workspace / Select workspace language:');
138
+ console.log(' 1) EN - English (recommended for AI agents)');
139
+ console.log(' 2) ES - Español');
140
+ const answer = await rl.question(`Language [${DEFAULT_LANGUAGE}]: `);
141
+ return normalizeLanguage(answer) || DEFAULT_LANGUAGE;
142
+ } finally {
143
+ rl.close();
144
+ }
145
+ }
146
+
147
+ function ensureDir(dir) {
148
+ fs.mkdirSync(dir, {recursive: true});
149
+ }
150
+
151
+ function copyRecursive(source, target, force = false) {
152
+ const stats = fs.statSync(source);
153
+
154
+ if (stats.isDirectory()) {
155
+ if (path.basename(source) === 'node_modules') return;
156
+ ensureDir(target);
157
+ for (const entry of fs.readdirSync(source)) {
158
+ copyRecursive(path.join(source, entry), path.join(target, entry), force);
159
+ }
160
+ return;
161
+ }
162
+
163
+ if (fs.existsSync(target) && !force) return;
164
+ ensureDir(path.dirname(target));
165
+ fs.copyFileSync(source, target);
166
+ }
167
+
168
+ function patchGitignore(targetDir) {
169
+ const gitignorePath = path.join(targetDir, '.gitignore');
170
+ const entries = ['.atl/', 'logs/', 'handoffs/', 'progress/', 'briefs/'];
171
+
172
+ let existing = '';
173
+ if (fs.existsSync(gitignorePath)) {
174
+ existing = fs.readFileSync(gitignorePath, 'utf8');
175
+ }
176
+
177
+ const toAdd = entries.filter(e => !existing.includes(e));
178
+ if (toAdd.length === 0) return;
179
+
180
+ const trailingNewline = existing.endsWith('\n') ? '' : '\n';
181
+ const block = `${trailingNewline}\n### agentflow\n${toAdd.join('\n')}\n`;
182
+ fs.writeFileSync(gitignorePath, existing + block, 'utf8');
183
+ }
184
+
185
+ function patchConfig(targetDir, options) {
186
+ const configPath = path.join(targetDir, 'orchestrator.config.json');
187
+ if (!fs.existsSync(configPath)) return;
188
+
189
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
190
+ const projectName = options.projectName || path.basename(path.resolve(targetDir)) || config.projectName;
191
+ config.projectName = projectName;
192
+ config.workspaceLanguage = options.language;
193
+
194
+ if (options.backend) {
195
+ config.repos.backend = options.backend;
196
+ }
197
+
198
+ if (options.frontend) {
199
+ config.repos.frontend = options.frontend;
200
+ }
201
+
202
+ fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`, 'utf8');
203
+ }
204
+
205
+ async function initProject(args) {
206
+ const {flags, rest} = parseFlags(args);
207
+ const targetDir = path.resolve(rest[0] || '.');
208
+ const force = Boolean(flags.force);
209
+ const language = await resolveLanguage(flags.lang);
210
+ const templateRoot = path.join(PACKAGE_ROOT, 'templates', language);
211
+
212
+ if (!fs.existsSync(templateRoot)) {
213
+ console.error(TEXT[language].missingTemplate(language));
214
+ process.exit(1);
215
+ }
216
+
217
+ ensureDir(targetDir);
218
+
219
+ for (const relativePath of TEMPLATE_PATHS) {
220
+ const source = path.join(templateRoot, relativePath);
221
+ if (!fs.existsSync(source)) continue;
222
+ const target = path.join(targetDir, relativePath);
223
+ copyRecursive(source, target, force);
224
+ }
225
+
226
+ for (const dir of RUNTIME_DIRS) {
227
+ ensureDir(path.join(targetDir, dir));
228
+ }
229
+
230
+ patchConfig(targetDir, {
231
+ projectName: flags['project-name'],
232
+ backend: flags.backend,
233
+ frontend: flags.frontend,
234
+ language
235
+ });
236
+
237
+ patchGitignore(targetDir);
238
+
239
+ const text = TEXT[language];
240
+ console.log(text.installed(targetDir));
241
+ console.log(text.language(language));
242
+ console.log(text.next);
243
+ console.log(text.step1);
244
+ console.log(text.step2);
245
+ console.log(text.step3);
246
+ }
247
+
248
+ async function initWorkspace(args) {
249
+ const {flags, rest} = parseFlags(args);
250
+ const projectPath = path.resolve(rest[0] || '.');
251
+ const language = await resolveLanguage(flags.lang);
252
+
253
+ if (!fs.existsSync(projectPath) || !fs.statSync(projectPath).isDirectory()) {
254
+ console.error(TEXT[language].invalidProject(projectPath));
255
+ process.exit(1);
256
+ }
257
+
258
+ const projectName = flags['project-name'] || path.basename(projectPath);
259
+ const workspaceName = flags['workspace-name'] || `orchestrator-${projectName.toLowerCase().replace(/\s+/g, '-')}`;
260
+ const workspaceDir = path.join(path.dirname(projectPath), workspaceName);
261
+
262
+ await initProject([
263
+ workspaceDir,
264
+ '--project-name',
265
+ projectName,
266
+ '--lang',
267
+ language,
268
+ '--backend',
269
+ flags.backend || projectPath,
270
+ '--frontend',
271
+ flags.frontend || projectPath,
272
+ ...(flags.force ? ['--force'] : [])
273
+ ]);
274
+
275
+ console.log('');
276
+ console.log(TEXT[language].realProject(projectPath));
277
+ console.log(TEXT[language].workspace(workspaceDir));
278
+ console.log(TEXT[language].sibling);
279
+ }
280
+
281
+ function runNodeScript(relativeScript, args = []) {
282
+ const scriptPath = path.join(PACKAGE_ROOT, relativeScript);
283
+ const child = spawn(process.execPath, [scriptPath, ...args], {
284
+ cwd: process.cwd(),
285
+ env: {
286
+ ...process.env,
287
+ ORCHESTRATOR_WORKSPACE: process.cwd(),
288
+ NODE_PATH: [path.join(PACKAGE_ROOT, 'node_modules'), process.env.NODE_PATH]
289
+ .filter(Boolean)
290
+ .join(path.delimiter)
291
+ },
292
+ stdio: 'inherit'
293
+ });
294
+
295
+ child.on('exit', code => process.exit(code ?? 0));
296
+ }
297
+
298
+ const command = argv[0];
299
+
300
+ switch (command) {
301
+ case undefined:
302
+ case 'help':
303
+ case '--help':
304
+ case '-h':
305
+ printHelp();
306
+ break;
307
+ case 'init':
308
+ await initProject(argv.slice(1));
309
+ break;
310
+ case 'init-workspace':
311
+ await initWorkspace(argv.slice(1));
312
+ break;
313
+ case 'tui':
314
+ runNodeScript('orchestrator.js', argv.slice(1));
315
+ break;
316
+ case 'ink':
317
+ runNodeScript(path.join('src', 'ink', 'index.mjs'), argv.slice(1));
318
+ break;
319
+ case 'skills:registry':
320
+ runNodeScript(path.join('scripts', 'update-skill-registry.mjs'));
321
+ break;
322
+ case 'openspec:new':
323
+ runNodeScript(path.join('scripts', 'scaffold-openspec-change.mjs'), argv.slice(1));
324
+ break;
325
+ case 'agent-config:init':
326
+ runNodeScript(path.join('scripts', 'scaffold-agent-configs.mjs'));
327
+ break;
328
+ default:
329
+ console.error(TEXT.es.unknown(command));
330
+ printHelp();
331
+ process.exit(1);
332
+ }