@bicorne/task-flow 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +2 -4
  2. package/SKILL.md +2 -4
  3. package/dist/commands/analyze.js +160 -318
  4. package/dist/commands/archive.js +44 -48
  5. package/dist/commands/design.js +225 -400
  6. package/dist/commands/extract.js +174 -303
  7. package/dist/commands/init.js +103 -147
  8. package/dist/commands/merge/index.js +184 -295
  9. package/dist/commands/merge/merger.js +112 -134
  10. package/dist/commands/merge/types.js +3 -5
  11. package/dist/commands/merge/validators.js +115 -132
  12. package/dist/commands/merge.js +46 -13
  13. package/dist/commands/start.js +155 -248
  14. package/dist/commands/status.js +68 -129
  15. package/dist/commands/sync.js +37 -53
  16. package/dist/commands/tasks-gen/doc-parser.js +148 -228
  17. package/dist/commands/tasks-gen/generators.js +104 -116
  18. package/dist/commands/tasks-gen/index.js +206 -314
  19. package/dist/commands/tasks-gen/parsers.js +131 -232
  20. package/dist/commands/tasks-gen/templates.js +9 -10
  21. package/dist/commands/tasks-gen/types.js +36 -14
  22. package/dist/commands/tasks-gen/validators.js +33 -49
  23. package/dist/commands/tasks.js +58 -20
  24. package/dist/commands/worktree.js +167 -249
  25. package/dist/hooks/check-prd-exists.js +45 -55
  26. package/dist/hooks/check-worktree-conflict.js +68 -101
  27. package/dist/hooks/hook-runner/executor.js +134 -126
  28. package/dist/hooks/hook-runner/index.js +181 -196
  29. package/dist/hooks/hook-runner/loader.js +74 -113
  30. package/dist/hooks/hook-runner/types.js +3 -5
  31. package/dist/hooks/hook-runner.js +94 -28
  32. package/dist/hooks/phase-complete-detector.js +125 -191
  33. package/dist/hooks/phase-gate-validator.js +315 -376
  34. package/dist/hooks/save-checkpoint.js +87 -130
  35. package/dist/hooks/start-mcp-servers.js +50 -65
  36. package/dist/hooks/stop-mcp-servers.js +40 -49
  37. package/dist/index.js +84 -153
  38. package/dist/lib/archive.js +126 -209
  39. package/dist/lib/config.js +141 -226
  40. package/dist/lib/constants.js +155 -145
  41. package/dist/lib/interactive.js +98 -148
  42. package/dist/lib/mcp-client.js +197 -320
  43. package/dist/lib/state.js +142 -253
  44. package/dist/slash/executor.js +299 -330
  45. package/dist/slash/index.js +69 -43
  46. package/dist/slash/parser.js +84 -97
  47. package/dist/slash/registry.js +100 -88
  48. package/dist/spec/openspec-to-task/builders.js +96 -109
  49. package/dist/spec/openspec-to-task/index.js +112 -173
  50. package/dist/spec/openspec-to-task/parsers.js +148 -219
  51. package/dist/spec/openspec-to-task/types.js +3 -5
  52. package/dist/spec/sync-openspec-to-task.js +47 -19
  53. package/dist/spec/sync-task-to-openspec.js +241 -272
  54. package/dist/types/ai-context.js +3 -8
  55. package/package.json +8 -6
  56. package/references/CLI-TUTORIAL.md +4 -10
@@ -1,366 +1,335 @@
1
- "use strict";
2
- /**
3
- * slash/executor.ts
4
- * Execute slash commands by dispatching to the appropriate command modules.
5
- * Supports both single commands and composite (multi-step) commands.
6
- */
7
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
- if (k2 === undefined) k2 = k;
9
- var desc = Object.getOwnPropertyDescriptor(m, k);
10
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
- desc = { enumerable: true, get: function() { return m[k]; } };
12
- }
13
- Object.defineProperty(o, k2, desc);
14
- }) : (function(o, m, k, k2) {
15
- if (k2 === undefined) k2 = k;
16
- o[k2] = m[k];
17
- }));
18
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
- Object.defineProperty(o, "default", { enumerable: true, value: v });
20
- }) : function(o, v) {
21
- o["default"] = v;
22
- });
23
- var __importStar = (this && this.__importStar) || (function () {
24
- var ownKeys = function(o) {
25
- ownKeys = Object.getOwnPropertyNames || function (o) {
26
- var ar = [];
27
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
- return ar;
29
- };
30
- return ownKeys(o);
31
- };
32
- return function (mod) {
33
- if (mod && mod.__esModule) return mod;
34
- var result = {};
35
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
- __setModuleDefault(result, mod);
37
- return result;
38
- };
39
- })();
40
- Object.defineProperty(exports, "__esModule", { value: true });
41
- exports.executeSlashCommand = executeSlashCommand;
42
- const fs = __importStar(require("fs"));
43
- const path = __importStar(require("path"));
44
- const registry_1 = require("./registry");
45
- const extract_1 = require("../commands/extract");
46
- const design_1 = require("../commands/design");
47
- const tasks_gen_1 = require("../commands/tasks-gen");
48
- const worktree_1 = require("../commands/worktree");
49
- const init_1 = require("../commands/init");
50
- const status_1 = require("../commands/status");
51
- const archive_1 = require("../lib/archive");
52
- const merge_1 = require("../commands/merge");
53
- const sync_task_to_openspec_1 = require("../spec/sync-task-to-openspec");
54
- const analyze_1 = require("../commands/analyze");
55
- const config_1 = require("../lib/config");
56
- function extractChangeName(parsed) {
57
- const firstArg = parsed.args[0];
58
- if (firstArg && !firstArg.startsWith('--')) {
59
- return firstArg;
60
- }
61
- for (let i = 0; i < parsed.args.length - 1; i += 1) {
62
- if (parsed.args[i] === '--change' || parsed.args[i] === '--task-id') {
63
- return parsed.args[i + 1];
64
- }
65
- }
66
- return undefined;
1
+ function e(s) {
2
+ return "function" != typeof WeakMap ? null : (e = function(e) {
3
+ return new WeakMap();
4
+ })(s);
67
5
  }
68
- function extractTaskId(parsed) {
69
- for (let i = 0; i < parsed.args.length - 1; i += 1) {
70
- if (parsed.args[i] === '--task-id') {
71
- return parsed.args[i + 1];
72
- }
73
- }
74
- const firstArg = parsed.args[0];
75
- if (firstArg && !firstArg.startsWith('--')) {
76
- return firstArg;
6
+ function s(s, t) {
7
+ var a, r, n;
8
+ if (!t && s && s.__esModule) return s;
9
+ if (null === s || "object" != typeof s && "function" != typeof s) return {
10
+ default: s
11
+ };
12
+ if ((a = e(t)) && a.has(s)) return a.get(s);
13
+ for(var c in r = {
14
+ __proto__: null
15
+ }, n = Object.defineProperty && Object.getOwnPropertyDescriptor, s)if ("default" !== c && Object.prototype.hasOwnProperty.call(s, c)) {
16
+ var o = n ? Object.getOwnPropertyDescriptor(s, c) : null;
17
+ o && (o.get || o.set) ? Object.defineProperty(r, c, o) : r[c] = s[c];
77
18
  }
78
- return undefined;
19
+ return r.default = s, a && a.set(s, r), r;
79
20
  }
80
- function extractFlagValue(parsed, flag) {
81
- const idx = parsed.args.indexOf(`--${flag}`);
82
- if (idx === -1 || idx + 1 >= parsed.args.length) {
83
- return undefined;
84
- }
85
- return parsed.args[idx + 1];
21
+ function t(e, s) {
22
+ let t = e.args.indexOf(`--${s}`);
23
+ if (-1 !== t && !(t + 1 >= e.args.length)) return e.args[t + 1];
86
24
  }
87
- function hasFlag(parsed, flag) {
88
- return parsed.args.includes(`--${flag}`) || parsed.args.includes(`-${flag}`);
25
+ function a(e, s) {
26
+ return e.args.includes(`--${s}`) || e.args.includes(`-${s}`);
89
27
  }
90
- async function executeSingleCommand(commandName, changeName, taskId, parsed, extraContextFile) {
91
- const contextFile = extractFlagValue(parsed, 'context-file') || extraContextFile;
92
- switch (commandName) {
93
- case 'extract': {
94
- if (!changeName) {
95
- return { step: 'extract', success: false, message: 'Missing change name. Usage: /tf:extract <change-name>' };
28
+ async function r(e, s, r, n, c) {
29
+ let o = t(n, 'context-file') || c;
30
+ switch(e){
31
+ case 'extract':
32
+ {
33
+ if (!s) return {
34
+ step: 'extract',
35
+ success: !1,
36
+ message: 'Missing change name. Usage: /tf:extract <change-name>'
37
+ };
38
+ let e = await (0, m.extract)({
39
+ change: s,
40
+ force: a(n, 'force'),
41
+ contextFile: o
42
+ });
43
+ return {
44
+ step: 'extract',
45
+ success: e.success,
46
+ message: e.success ? `PRD created: ${e.prdPath}` : e.message,
47
+ detail: e.success ? {
48
+ prdPath: e.prdPath,
49
+ changeDir: e.changeDir
50
+ } : void 0
51
+ };
96
52
  }
97
- const result = await (0, extract_1.extract)({
98
- change: changeName,
99
- force: hasFlag(parsed, 'force'),
100
- contextFile,
101
- });
102
- return {
103
- step: 'extract',
104
- success: result.success,
105
- message: result.success ? `PRD created: ${result.prdPath}` : result.message,
106
- detail: result.success ? { prdPath: result.prdPath, changeDir: result.changeDir } : undefined,
107
- };
108
- }
109
- case 'design': {
110
- if (!changeName) {
111
- return { step: 'design', success: false, message: 'Missing change name. Usage: /tf:design <change-name>' };
53
+ case 'design':
54
+ {
55
+ if (!s) return {
56
+ step: 'design',
57
+ success: !1,
58
+ message: 'Missing change name. Usage: /tf:design <change-name>'
59
+ };
60
+ let e = await (0, g.generateDesign)({
61
+ change: s,
62
+ force: a(n, 'force'),
63
+ skipPrompt: !0,
64
+ contextFile: o
65
+ });
66
+ return {
67
+ step: 'design',
68
+ success: e.success,
69
+ message: e.success ? `Design created: ${e.designPath}` : e.message,
70
+ detail: e.success ? {
71
+ designPath: e.designPath
72
+ } : void 0
73
+ };
112
74
  }
113
- const result = await (0, design_1.generateDesign)({
114
- change: changeName,
115
- force: hasFlag(parsed, 'force'),
116
- skipPrompt: true,
117
- contextFile,
118
- });
119
- return {
120
- step: 'design',
121
- success: result.success,
122
- message: result.success ? `Design created: ${result.designPath}` : result.message,
123
- detail: result.success ? { designPath: result.designPath } : undefined,
124
- };
125
- }
126
- case 'tasks': {
127
- if (!changeName) {
128
- return { step: 'tasks', success: false, message: 'Missing change name. Usage: /tf:tasks <change-name>' };
129
- }
130
- const result = await (0, tasks_gen_1.generateTasks)({
131
- change: changeName,
132
- yes: true,
133
- });
134
- return {
135
- step: 'tasks',
136
- success: result.success,
137
- message: result.success ? `Tasks generated: ${result.generatedFiles?.length || 0} files` : result.message,
138
- detail: result.success ? { tasksDir: result.tasksDir, manifestPath: result.manifestPath } : undefined,
139
- };
140
- }
141
- case 'worktree': {
142
- if (!changeName) {
143
- return { step: 'worktree', success: false, message: 'Missing change name. Usage: /tf:worktree <change-name>' };
75
+ case 'tasks':
76
+ {
77
+ if (!s) return {
78
+ step: 'tasks',
79
+ success: !1,
80
+ message: 'Missing change name. Usage: /tf:tasks <change-name>'
81
+ };
82
+ let e = await (0, l.generateTasks)({
83
+ change: s,
84
+ yes: !0
85
+ });
86
+ return {
87
+ step: 'tasks',
88
+ success: e.success,
89
+ message: e.success ? `Tasks generated: ${e.generatedFiles?.length || 0} files` : e.message,
90
+ detail: e.success ? {
91
+ tasksDir: e.tasksDir,
92
+ manifestPath: e.manifestPath
93
+ } : void 0
94
+ };
144
95
  }
145
- const result = await (0, worktree_1.createWorktree)({
146
- change: changeName,
147
- yes: true,
148
- });
149
- return {
150
- step: 'worktree',
151
- success: result.success,
152
- message: result.success ? `Worktree created: ${result.worktreePath}` : result.message,
153
- detail: result.success ? { worktreePath: result.worktreePath, branchName: result.branchName } : undefined,
154
- };
155
- }
156
- case 'init': {
157
- const result = (0, init_1.initHarness)({
158
- force: hasFlag(parsed, 'force'),
159
- });
160
- return {
161
- step: 'init',
162
- success: result.success,
163
- message: result.success ? 'Task flow initialized' : result.message,
164
- };
165
- }
166
- case 'status': {
167
- (0, status_1.showStatus)({});
168
- return { step: 'status', success: true, message: 'Status displayed' };
169
- }
170
- case 'archive': {
171
- const tid = taskId || changeName;
172
- if (!tid) {
173
- return { step: 'archive', success: false, message: 'Missing task ID. Usage: /tf:archive --task-id <id>' };
96
+ case 'worktree':
97
+ {
98
+ if (!s) return {
99
+ step: 'worktree',
100
+ success: !1,
101
+ message: 'Missing change name. Usage: /tf:worktree <change-name>'
102
+ };
103
+ let e = await (0, d.createWorktree)({
104
+ change: s,
105
+ yes: !0
106
+ });
107
+ return {
108
+ step: 'worktree',
109
+ success: e.success,
110
+ message: e.success ? `Worktree created: ${e.worktreePath}` : e.message,
111
+ detail: e.success ? {
112
+ worktreePath: e.worktreePath,
113
+ branchName: e.branchName
114
+ } : void 0
115
+ };
174
116
  }
175
- const result = (0, archive_1.archiveTaskState)({
176
- taskId: tid,
177
- eventType: 'task_completed',
178
- status: 'completed',
179
- });
180
- if ('skipped' in result && result.skipped) {
181
- return { step: 'archive', success: true, message: `Skipped: ${result.reason}` };
117
+ case 'init':
118
+ {
119
+ let e = (0, f.initHarness)({
120
+ force: a(n, 'force')
121
+ });
122
+ return {
123
+ step: 'init',
124
+ success: e.success,
125
+ message: e.success ? 'Task flow initialized' : e.message
126
+ };
182
127
  }
183
- return {
184
- step: 'archive',
185
- success: true,
186
- message: `Archived: ${result.archivePath}`,
128
+ case 'status':
129
+ return (0, p.showStatus)({}), {
130
+ step: 'status',
131
+ success: !0,
132
+ message: 'Status displayed'
187
133
  };
188
- }
189
- case 'merge': {
190
- const tid = taskId || changeName;
191
- if (!tid) {
192
- return { step: 'merge', success: false, message: 'Missing task ID. Usage: /tf:merge <task-id>' };
134
+ case 'archive':
135
+ {
136
+ let e = r || s;
137
+ if (!e) return {
138
+ step: 'archive',
139
+ success: !1,
140
+ message: 'Missing task ID. Usage: /tf:archive --task-id <id>'
141
+ };
142
+ let t = (0, h.archiveTaskState)({
143
+ taskId: e,
144
+ eventType: 'task_completed',
145
+ status: 'completed'
146
+ });
147
+ if ('skipped' in t && t.skipped) return {
148
+ step: 'archive',
149
+ success: !0,
150
+ message: `Skipped: ${t.reason}`
151
+ };
152
+ return {
153
+ step: 'archive',
154
+ success: !0,
155
+ message: `Archived: ${t.archivePath}`
156
+ };
193
157
  }
194
- const result = (0, merge_1.mergeTask)({
195
- taskId: tid,
196
- skipReviewCheck: hasFlag(parsed, 'skip-review-check'),
197
- dryRun: hasFlag(parsed, 'dry-run'),
198
- });
199
- return {
200
- step: 'merge',
201
- success: result.success,
202
- message: result.success ? `Merged: ${result.taskId}` : result.message,
203
- };
204
- }
205
- case 'sync': {
206
- const tid = taskId || changeName;
207
- if (!tid) {
208
- return { step: 'sync', success: false, message: 'Missing task ID. Usage: /tf:sync --task-id <id>' };
158
+ case 'merge':
159
+ {
160
+ let e = r || s;
161
+ if (!e) return {
162
+ step: 'merge',
163
+ success: !1,
164
+ message: 'Missing task ID. Usage: /tf:merge <task-id>'
165
+ };
166
+ let t = (0, k.mergeTask)({
167
+ taskId: e,
168
+ skipReviewCheck: a(n, 'skip-review-check'),
169
+ dryRun: a(n, 'dry-run')
170
+ });
171
+ return {
172
+ step: 'merge',
173
+ success: t.success,
174
+ message: t.success ? `Merged: ${t.taskId}` : t.message
175
+ };
209
176
  }
210
- const result = (0, sync_task_to_openspec_1.syncTaskToSpec)({ taskId: tid });
211
- if (result.skipped) {
212
- return { step: 'sync', success: true, message: `Skipped: ${result.reason}` };
177
+ case 'sync':
178
+ {
179
+ let e = r || s;
180
+ if (!e) return {
181
+ step: 'sync',
182
+ success: !1,
183
+ message: 'Missing task ID. Usage: /tf:sync --task-id <id>'
184
+ };
185
+ let t = (0, y.syncTaskToSpec)({
186
+ taskId: e
187
+ });
188
+ if (t.skipped) return {
189
+ step: 'sync',
190
+ success: !0,
191
+ message: `Skipped: ${t.reason}`
192
+ };
193
+ return {
194
+ step: 'sync',
195
+ success: !0,
196
+ message: 'Synced'
197
+ };
213
198
  }
214
- return { step: 'sync', success: true, message: 'Synced' };
215
- }
216
199
  default:
217
- return { step: commandName, success: false, message: `Unknown command: ${commandName}` };
218
- }
219
- }
220
- function findExistingContextFile(projectRoot) {
221
- const candidatePaths = [
222
- path.resolve(projectRoot, 'context.json'),
223
- path.resolve(projectRoot, '.harness', 'context.json'),
224
- path.resolve(projectRoot, '.tmp', 'context.json'),
225
- ];
226
- for (const p of candidatePaths) {
227
- if (fs.existsSync(p)) {
228
- return p;
229
- }
230
- }
231
- return null;
232
- }
233
- function generateTempContextFile(projectRoot) {
234
- const tmpDir = path.resolve(projectRoot, '.tmp');
235
- if (!fs.existsSync(tmpDir)) {
236
- fs.mkdirSync(tmpDir, { recursive: true });
237
- }
238
- const contextPath = path.resolve(tmpDir, 'context.json');
239
- const result = (0, analyze_1.analyzeProject)({ cwd: projectRoot, output: contextPath });
240
- if (!result.success || !result.outputPath) {
241
- throw new Error(`Failed to generate context: ${result.message}`);
200
+ return {
201
+ step: e,
202
+ success: !1,
203
+ message: `Unknown command: ${e}`
204
+ };
242
205
  }
243
- return result.outputPath;
244
206
  }
245
- async function executeCompositeCommand(cmdDef, changeName, taskId, parsed) {
246
- const steps = cmdDef.steps || [];
247
- const stepResults = [];
248
- let contextFile;
249
- console.log(`[SLASH] Executing composite command: /tf:${cmdDef.name}`);
250
- console.log(`[SLASH] Steps: ${steps.join(' → ')}`);
251
- console.log('');
252
- if (cmdDef.name === 'propose') {
253
- const explicitContextFile = extractFlagValue(parsed, 'context-file');
254
- if (explicitContextFile) {
255
- console.log(`[SLASH] ✓ Using explicit context: ${explicitContextFile}`);
256
- contextFile = explicitContextFile;
257
- }
207
+ async function n(e, s, a, n) {
208
+ let c, u = e.steps || [], m = [];
209
+ if (console.log(`[SLASH] Executing composite command: /tf:${e.name}`), console.log(`[SLASH] Steps: ${u.join(' → ')}`), console.log(''), 'propose' === e.name) {
210
+ let r = t(n, 'context-file');
211
+ if (r) console.log(`[SLASH] Using explicit context: ${r}`), c = r;
258
212
  else {
259
- const config = (0, config_1.loadConfig)({});
260
- const projectRoot = config.projectRoot || process.cwd();
261
- const existingContext = findExistingContextFile(projectRoot);
262
- if (existingContext) {
263
- console.log(`[SLASH] Using existing context: ${existingContext}`);
264
- contextFile = existingContext;
265
- }
213
+ let t = (0, S.loadConfig)({}).projectRoot || process.cwd(), r = function(e) {
214
+ for (let s of [
215
+ i.resolve(e, 'context.json'),
216
+ i.resolve(e, '.harness', 'context.json'),
217
+ i.resolve(e, '.tmp', 'context.json')
218
+ ])if (o.existsSync(s)) return s;
219
+ return null;
220
+ }(t);
221
+ if (r) console.log(`[SLASH] ✓ Using existing context: ${r}`), c = r;
266
222
  else {
267
223
  console.log('[SLASH] → Step: analyze (auto)');
268
224
  try {
269
- contextFile = generateTempContextFile(projectRoot);
270
- console.log(`[SLASH] analyze: Context generated at ${contextFile}`);
271
- stepResults.push({
225
+ c = function(e) {
226
+ let s = i.resolve(e, '.tmp');
227
+ o.existsSync(s) || o.mkdirSync(s, {
228
+ recursive: !0
229
+ });
230
+ let t = i.resolve(s, 'context.json'), a = (0, $.analyzeProject)({
231
+ cwd: e,
232
+ output: t
233
+ });
234
+ if (!a.success || !a.outputPath) throw Error(`Failed to generate context: ${a.message}`);
235
+ return a.outputPath;
236
+ }(t), console.log(`[SLASH] ✓ analyze: Context generated at ${c}`), m.push({
272
237
  step: 'analyze',
273
- success: true,
274
- message: `Context generated: ${contextFile}`,
275
- detail: { contextPath: contextFile },
238
+ success: !0,
239
+ message: `Context generated: ${c}`,
240
+ detail: {
241
+ contextPath: c
242
+ }
276
243
  });
277
- }
278
- catch (error) {
279
- const errorMsg = error instanceof Error ? error.message : 'Unknown error';
280
- console.log(`[SLASH] ✗ analyze: ${errorMsg}`);
281
- return {
282
- success: false,
283
- command: cmdDef.name,
284
- changeName,
285
- taskId,
286
- steps: stepResults,
287
- message: `Failed to generate context: ${errorMsg}`,
288
- error: errorMsg,
244
+ } catch (r) {
245
+ let t = r instanceof Error ? r.message : 'Unknown error';
246
+ return console.log(`[SLASH] analyze: ${t}`), {
247
+ success: !1,
248
+ command: e.name,
249
+ changeName: s,
250
+ taskId: a,
251
+ steps: m,
252
+ message: `Failed to generate context: ${t}`,
253
+ error: t
289
254
  };
290
255
  }
291
256
  console.log('');
292
257
  }
293
258
  }
294
259
  }
295
- for (const step of steps) {
296
- console.log(`[SLASH] → Step: ${step}`);
297
- const result = await executeSingleCommand(step, changeName, taskId, parsed, contextFile);
298
- stepResults.push(result);
299
- if (result.success) {
300
- console.log(`[SLASH] ✓ ${step}: ${result.message || 'OK'}`);
301
- }
302
- else {
303
- console.log(`[SLASH] ✗ ${step}: ${result.message || 'Failed'}`);
304
- return {
305
- success: false,
306
- command: cmdDef.name,
307
- changeName,
308
- taskId,
309
- steps: stepResults,
310
- message: `Composite command "${cmdDef.name}" failed at step "${step}": ${result.message}`,
311
- error: result.message,
312
- };
313
- }
314
- console.log('');
260
+ for (let t of u){
261
+ console.log(`[SLASH] → Step: ${t}`);
262
+ let o = await r(t, s, a, n, c);
263
+ if (m.push(o), !o.success) return console.log(`[SLASH] ✗ ${t}: ${o.message || 'Failed'}`), {
264
+ success: !1,
265
+ command: e.name,
266
+ changeName: s,
267
+ taskId: a,
268
+ steps: m,
269
+ message: `Composite command "${e.name}" failed at step "${t}": ${o.message}`,
270
+ error: o.message
271
+ };
272
+ console.log(`[SLASH] ✓ ${t}: ${o.message || 'OK'}`), console.log('');
315
273
  }
316
274
  return {
317
- success: true,
318
- command: cmdDef.name,
319
- changeName,
320
- taskId,
321
- steps: stepResults,
322
- message: `Composite command "/tf:${cmdDef.name}" completed successfully`,
275
+ success: !0,
276
+ command: e.name,
277
+ changeName: s,
278
+ taskId: a,
279
+ steps: m,
280
+ message: `Composite command "/tf:${e.name}" completed successfully`
323
281
  };
324
282
  }
325
- async function executeSlashCommand(parsed) {
326
- const cmdDef = (0, registry_1.getCommand)(parsed.command);
327
- if (!cmdDef) {
328
- return {
329
- success: false,
330
- command: parsed.command,
331
- message: `Unknown slash command: /tf:${parsed.command}`,
332
- error: `Command "${parsed.command}" not found. Run /tf:help for available commands.`,
333
- };
334
- }
335
- const changeName = extractChangeName(parsed);
336
- const taskId = extractTaskId(parsed);
337
- if (cmdDef.requiresChange && !changeName) {
338
- return {
339
- success: false,
340
- command: parsed.command,
341
- message: `Command "/tf:${parsed.command}" requires a change name. Usage: ${cmdDef.usage}`,
342
- error: 'Missing change name',
343
- };
344
- }
345
- if (cmdDef.requiresTaskId && !taskId && !changeName) {
346
- return {
347
- success: false,
348
- command: parsed.command,
349
- message: `Command "/tf:${parsed.command}" requires a task ID. Usage: ${cmdDef.usage}`,
350
- error: 'Missing task ID',
351
- };
352
- }
353
- if (cmdDef.category === 'composite') {
354
- return executeCompositeCommand(cmdDef, changeName, taskId, parsed);
355
- }
356
- const stepResult = await executeSingleCommand(parsed.command, changeName, taskId, parsed);
283
+ async function c(e) {
284
+ let s = (0, u.getCommand)(e.command);
285
+ if (!s) return {
286
+ success: !1,
287
+ command: e.command,
288
+ message: `Unknown slash command: /tf:${e.command}`,
289
+ error: `Command "${e.command}" not found. Run /tf:help for available commands.`
290
+ };
291
+ let t = function(e) {
292
+ let s = e.args[0];
293
+ if (s && !s.startsWith('--')) return s;
294
+ for(let s = 0; s < e.args.length - 1; s += 1)if ('--change' === e.args[s] || '--task-id' === e.args[s]) return e.args[s + 1];
295
+ }(e), a = function(e) {
296
+ for(let s = 0; s < e.args.length - 1; s += 1)if ('--task-id' === e.args[s]) return e.args[s + 1];
297
+ let s = e.args[0];
298
+ if (s && !s.startsWith('--')) return s;
299
+ }(e);
300
+ if (s.requiresChange && !t) return {
301
+ success: !1,
302
+ command: e.command,
303
+ message: `Command "/tf:${e.command}" requires a change name. Usage: ${s.usage}`,
304
+ error: 'Missing change name'
305
+ };
306
+ if (s.requiresTaskId && !a && !t) return {
307
+ success: !1,
308
+ command: e.command,
309
+ message: `Command "/tf:${e.command}" requires a task ID. Usage: ${s.usage}`,
310
+ error: 'Missing task ID'
311
+ };
312
+ if ('composite' === s.category) return n(s, t, a, e);
313
+ let c = await r(e.command, t, a, e);
357
314
  return {
358
- success: stepResult.success,
359
- command: parsed.command,
360
- changeName,
361
- taskId,
362
- steps: [stepResult],
363
- message: stepResult.message,
364
- error: stepResult.success ? undefined : stepResult.message,
315
+ success: c.success,
316
+ command: e.command,
317
+ changeName: t,
318
+ taskId: a,
319
+ steps: [
320
+ c
321
+ ],
322
+ message: c.message,
323
+ error: c.success ? void 0 : c.message
365
324
  };
366
325
  }
326
+ "use strict";
327
+ Object.defineProperty(exports, "__esModule", {
328
+ value: !0
329
+ }), Object.defineProperty(exports, "executeSlashCommand", {
330
+ enumerable: !0,
331
+ get: function() {
332
+ return c;
333
+ }
334
+ });
335
+ let o = /*#__PURE__*/ s(require("fs")), i = /*#__PURE__*/ s(require("path")), u = require("./registry"), m = require("../commands/extract"), g = require("../commands/design"), l = require("../commands/tasks-gen"), d = require("../commands/worktree"), f = require("../commands/init"), p = require("../commands/status"), h = require("../lib/archive"), k = require("../commands/merge"), y = require("../spec/sync-task-to-openspec"), $ = require("../commands/analyze"), S = require("../lib/config");