@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,370 +1,247 @@
1
- "use strict";
2
- /**
3
- * lib/mcp-client.ts
4
- * MCP Server lifecycle management
5
- *
6
- * Features:
7
- * - Start/stop MCP servers
8
- * - Timeout control
9
- * - State management
10
- * - Connection info retrieval
11
- */
12
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
- if (k2 === undefined) k2 = k;
14
- var desc = Object.getOwnPropertyDescriptor(m, k);
15
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
- desc = { enumerable: true, get: function() { return m[k]; } };
17
- }
18
- Object.defineProperty(o, k2, desc);
19
- }) : (function(o, m, k, k2) {
20
- if (k2 === undefined) k2 = k;
21
- o[k2] = m[k];
22
- }));
23
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
- Object.defineProperty(o, "default", { enumerable: true, value: v });
25
- }) : function(o, v) {
26
- o["default"] = v;
27
- });
28
- var __importStar = (this && this.__importStar) || (function () {
29
- var ownKeys = function(o) {
30
- ownKeys = Object.getOwnPropertyNames || function (o) {
31
- var ar = [];
32
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
33
- return ar;
34
- };
35
- return ownKeys(o);
36
- };
37
- return function (mod) {
38
- if (mod && mod.__esModule) return mod;
39
- var result = {};
40
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
41
- __setModuleDefault(result, mod);
42
- return result;
43
- };
44
- })();
45
- Object.defineProperty(exports, "__esModule", { value: true });
46
- exports.startMcpServers = startMcpServers;
47
- exports.startMcpServer = startMcpServer;
48
- exports.stopMcpServer = stopMcpServer;
49
- exports.stopAllMcpServers = stopAllMcpServers;
50
- exports.getMcpStatus = getMcpStatus;
51
- exports.getAllMcpStatus = getAllMcpStatus;
52
- exports.getMcpConnectionInfo = getMcpConnectionInfo;
53
- exports.startMcpServerManual = startMcpServerManual;
54
- exports.getRunningCount = getRunningCount;
55
- exports.cleanup = cleanup;
56
- const child_process_1 = require("child_process");
57
- const path = __importStar(require("path"));
58
- /**
59
- * Global MCP process state management
60
- * Map<serverName, ServerState>
61
- */
62
- const mcpProcessState = new Map();
63
- /**
64
- * Start MCP Servers
65
- * @param mcpServers - List of MCP server configurations
66
- * @param projectRoot - Project root directory
67
- * @returns Start result
68
- */
69
- function startMcpServers(mcpServers, projectRoot) {
70
- const results = [];
71
- for (const mcp of mcpServers) {
72
- // Check if enabled
73
- if (mcp.enabled === false) {
74
- results.push({
75
- name: mcp.name,
1
+ function t(e) {
2
+ return "function" != typeof WeakMap ? null : (t = function(t) {
3
+ return new WeakMap();
4
+ })(e);
5
+ }
6
+ function e(t, e) {
7
+ let n = [];
8
+ for (let o of t){
9
+ if (!1 === o.enabled) {
10
+ n.push({
11
+ name: o.name,
76
12
  status: 'skipped',
77
- reason: 'enabled is false',
13
+ reason: 'enabled is false'
78
14
  });
79
15
  continue;
80
16
  }
81
- // Check if auto-start is required
82
- if (!mcp.lifecycle?.autoStart) {
83
- results.push({
84
- name: mcp.name,
17
+ if (!o.lifecycle?.autoStart) {
18
+ n.push({
19
+ name: o.name,
85
20
  status: 'skipped',
86
- reason: 'autoStart is false',
21
+ reason: 'autoStart is false'
87
22
  });
88
23
  continue;
89
24
  }
90
25
  try {
91
- const result = startMcpServer(mcp, projectRoot);
92
- results.push(result);
93
- }
94
- catch (error) {
95
- results.push({
96
- name: mcp.name,
26
+ let t = r(o, e);
27
+ n.push(t);
28
+ } catch (t) {
29
+ n.push({
30
+ name: o.name,
97
31
  status: 'error',
98
- error: error.message,
99
- stack: error.stack,
32
+ error: t.message,
33
+ stack: t.stack
100
34
  });
101
35
  }
102
36
  }
103
37
  return {
104
- success: results.every(r => r.status !== 'error'),
105
- results,
38
+ success: n.every((t)=>'error' !== t.status),
39
+ results: n
106
40
  };
107
41
  }
108
- /**
109
- * Start single MCP Server
110
- * @param mcp - MCP server configuration
111
- * @param projectRoot - Project root directory
112
- * @returns Start result
113
- */
114
- function startMcpServer(mcp, projectRoot) {
115
- const { name, command, args, lifecycle } = mcp;
116
- // Check if already running
117
- if (mcpProcessState.has(name)) {
118
- const existingState = mcpProcessState.get(name);
42
+ function r(t, e) {
43
+ let { name: r, command: o, args: s, lifecycle: i } = t;
44
+ if (S.has(r)) {
45
+ let t = S.get(r);
119
46
  return {
120
- name,
47
+ name: r,
121
48
  status: 'already-running',
122
- pid: existingState.pid,
123
- startedAt: existingState.startedAt.toISOString(),
49
+ pid: t.pid,
50
+ startedAt: t.startedAt.toISOString()
124
51
  };
125
52
  }
126
- // Resolve command and arguments
127
- const resolvedArgs = (args || []).map(arg => {
128
- // Handle relative paths (starting with . or ..)
129
- if (arg.startsWith('.') || arg.startsWith('..')) {
130
- return path.resolve(projectRoot, arg);
131
- }
132
- return arg;
133
- });
134
- console.log(`[MCP] Starting server: ${name} (${command} ${resolvedArgs.join(' ')})`);
135
- // Start process
136
- const proc = (0, child_process_1.spawn)(command, resolvedArgs, {
137
- stdio: ['pipe', 'pipe', 'pipe'],
53
+ let u = (s || []).map((t)=>t.startsWith('.') || t.startsWith('..') ? m.resolve(e, t) : t);
54
+ console.log(`[MCP] Starting server: ${r} (${o} ${u.join(' ')})`);
55
+ let a = (0, g.spawn)(o, u, {
56
+ stdio: [
57
+ 'pipe',
58
+ 'pipe',
59
+ 'pipe'
60
+ ],
138
61
  env: {
139
62
  ...process.env,
140
- HARNESS_PROJECT_ROOT: projectRoot,
141
- HARNESS_MCP_SERVER_NAME: name,
63
+ HARNESS_PROJECT_ROOT: e,
64
+ HARNESS_MCP_SERVER_NAME: r
142
65
  },
143
- cwd: projectRoot,
144
- });
145
- // Record state
146
- const state = {
147
- name,
148
- pid: proc.pid,
149
- process: proc,
66
+ cwd: e
67
+ }), l = {
68
+ name: r,
69
+ pid: a.pid,
70
+ process: a,
150
71
  startedAt: new Date(),
151
72
  status: 'running',
152
- timeout: lifecycle?.timeout || 300000, // Default 5 minutes
153
- config: mcp,
73
+ timeout: i?.timeout || 300000,
74
+ config: t
154
75
  };
155
- mcpProcessState.set(name, state);
156
- // Set timeout timer
157
- if (state.timeout) {
158
- state.timeoutTimer = setTimeout(() => {
159
- console.log(`[MCP] Server ${name} timed out (${state.timeout}ms), stopping...`);
160
- stopMcpServer(name);
161
- }, state.timeout);
162
- }
163
- // Listen to stdout
164
- proc.stdout.on('data', (data) => {
165
- const output = data.toString().trim();
166
- if (output) {
167
- console.log(`[MCP:${name}] ${output}`);
168
- }
169
- });
170
- // Listen to stderr
171
- proc.stderr.on('data', (data) => {
172
- const output = data.toString().trim();
173
- if (output) {
174
- console.error(`[MCP:${name}] ERROR: ${output}`);
175
- }
176
- });
177
- // Listen to exit
178
- proc.on('exit', (code, signal) => {
179
- console.log(`[MCP:${name}] Exited with code ${code}, signal: ${signal}`);
180
- mcpProcessState.delete(name);
181
- });
182
- // Listen to error
183
- proc.on('error', (error) => {
184
- console.error(`[MCP:${name}] Process error: ${error.message}`);
185
- state.status = 'error';
186
- });
187
- return {
188
- name,
76
+ return S.set(r, l), l.timeout && (l.timeoutTimer = setTimeout(()=>{
77
+ console.log(`[MCP] Server ${r} timed out (${l.timeout}ms), stopping...`), n(r);
78
+ }, l.timeout)), a.stdout.on('data', (t)=>{
79
+ let e = t.toString().trim();
80
+ e && console.log(`[MCP:${r}] ${e}`);
81
+ }), a.stderr.on('data', (t)=>{
82
+ let e = t.toString().trim();
83
+ e && console.error(`[MCP:${r}] ERROR: ${e}`);
84
+ }), a.on('exit', (t, e)=>{
85
+ console.log(`[MCP:${r}] Exited with code ${t}, signal: ${e}`), S.delete(r);
86
+ }), a.on('error', (t)=>{
87
+ console.error(`[MCP:${r}] Process error: ${t.message}`), l.status = 'error';
88
+ }), {
89
+ name: r,
189
90
  status: 'started',
190
- pid: proc.pid,
191
- command: `${command} ${resolvedArgs.join(' ')}`,
192
- startedAt: state.startedAt.toISOString(),
91
+ pid: a.pid,
92
+ command: `${o} ${u.join(' ')}`,
93
+ startedAt: l.startedAt.toISOString()
193
94
  };
194
95
  }
195
- /**
196
- * Stop MCP Server
197
- * @param name - Server name
198
- * @returns Stop result
199
- */
200
- function stopMcpServer(name) {
201
- const state = mcpProcessState.get(name);
202
- if (!state) {
203
- return {
204
- name,
205
- status: 'not-running',
206
- };
207
- }
208
- console.log(`[MCP] Stopping server: ${name} (pid: ${state.pid})`);
209
- // Clear timeout timer
210
- if (state.timeoutTimer) {
211
- clearTimeout(state.timeoutTimer);
212
- }
213
- // Clear force kill timer if exists
214
- if (state.forceKillTimer) {
215
- clearTimeout(state.forceKillTimer);
216
- }
96
+ function n(t) {
97
+ let e = S.get(t);
98
+ if (!e) return {
99
+ name: t,
100
+ status: 'not-running'
101
+ };
102
+ console.log(`[MCP] Stopping server: ${t} (pid: ${e.pid})`), e.timeoutTimer && clearTimeout(e.timeoutTimer), e.forceKillTimer && clearTimeout(e.forceKillTimer);
217
103
  try {
218
- // Graceful shutdown (SIGTERM)
219
- state.process.kill('SIGTERM');
220
- state.status = 'stopping';
221
- // Immediately delete state to prevent test leakage
222
- // The actual process will be cleaned up by the OS
223
- mcpProcessState.delete(name);
224
- // Force terminate if process doesn't exit within 5 seconds
225
- const forceKillTimer = setTimeout(() => {
104
+ return e.process.kill('SIGTERM'), e.status = 'stopping', S.delete(t), setTimeout(()=>{
226
105
  try {
227
- state.process.kill('SIGKILL');
228
- }
229
- catch {
230
- // Process already exited
231
- }
232
- }, 5000);
233
- // Unref the timer so it doesn't prevent process exit
234
- forceKillTimer.unref();
235
- return {
236
- name,
106
+ e.process.kill('SIGKILL');
107
+ } catch {}
108
+ }, 5000).unref(), {
109
+ name: t,
237
110
  status: 'stopping',
238
- pid: state.pid,
111
+ pid: e.pid
239
112
  };
240
- }
241
- catch (error) {
242
- console.error(`[MCP] Failed to stop server ${name}: ${error.message}`);
243
- mcpProcessState.delete(name);
244
- return {
245
- name,
113
+ } catch (e) {
114
+ return console.error(`[MCP] Failed to stop server ${t}: ${e.message}`), S.delete(t), {
115
+ name: t,
246
116
  status: 'error',
247
- error: error.message,
117
+ error: e.message
248
118
  };
249
119
  }
250
120
  }
251
- /**
252
- * Stop all MCP Servers
253
- * @returns Stop result
254
- */
255
- function stopAllMcpServers() {
256
- const results = [];
257
- const names = Array.from(mcpProcessState.keys());
258
- for (const name of names) {
259
- results.push(stopMcpServer(name));
260
- }
121
+ function o() {
122
+ let t = [];
123
+ for (let e of Array.from(S.keys()))t.push(n(e));
261
124
  return {
262
- success: true,
263
- results,
264
- stoppedCount: results.length,
125
+ success: !0,
126
+ results: t,
127
+ stoppedCount: t.length
265
128
  };
266
129
  }
267
- /**
268
- * Get MCP Server status
269
- * @param name - Server name
270
- * @returns Status info
271
- */
272
- function getMcpStatus(name) {
273
- const state = mcpProcessState.get(name);
274
- if (!state) {
275
- return {
276
- name,
277
- status: 'not-running',
278
- pid: 0,
279
- startedAt: '',
280
- uptime: 0,
281
- timeout: 0,
282
- };
283
- }
284
- const now = Date.now();
285
- const startTime = state.startedAt.getTime();
130
+ function s(t) {
131
+ let e = S.get(t);
132
+ if (!e) return {
133
+ name: t,
134
+ status: 'not-running',
135
+ pid: 0,
136
+ startedAt: '',
137
+ uptime: 0,
138
+ timeout: 0
139
+ };
140
+ let r = Date.now(), n = e.startedAt.getTime();
286
141
  return {
287
- name,
288
- status: state.status,
289
- pid: state.pid,
290
- startedAt: state.startedAt.toISOString(),
291
- uptime: now - startTime,
292
- timeout: state.timeout,
142
+ name: t,
143
+ status: e.status,
144
+ pid: e.pid,
145
+ startedAt: e.startedAt.toISOString(),
146
+ uptime: r - n,
147
+ timeout: e.timeout
293
148
  };
294
149
  }
295
- /**
296
- * Get all MCP Servers status
297
- * @returns List of status info
298
- */
299
- function getAllMcpStatus() {
300
- const results = [];
301
- for (const name of mcpProcessState.keys()) {
302
- results.push(getMcpStatus(name));
303
- }
304
- return results;
150
+ function i() {
151
+ let t = [];
152
+ for (let e of S.keys())t.push(s(e));
153
+ return t;
305
154
  }
306
- /**
307
- * Get MCP connection info (for injection to Agent)
308
- * @returns List of connection info
309
- */
310
- function getMcpConnectionInfo() {
311
- const connections = [];
312
- for (const [name, state] of mcpProcessState.entries()) {
313
- connections.push({
314
- name,
315
- transportType: 'stdio',
316
- pid: state.pid,
317
- status: state.status,
318
- });
319
- }
320
- return connections;
155
+ function u() {
156
+ let t = [];
157
+ for (let [e, r] of S.entries())t.push({
158
+ name: e,
159
+ transportType: 'stdio',
160
+ pid: r.pid,
161
+ status: r.status
162
+ });
163
+ return t;
321
164
  }
322
- /**
323
- * Manually start MCP Server (for CLI commands)
324
- * @param mcp - MCP server configuration
325
- * @param projectRoot - Project root directory
326
- * @returns Start result
327
- */
328
- function startMcpServerManual(mcp, projectRoot) {
329
- // Temporarily set autoStart to true
330
- const mcpWithAutoStart = {
331
- ...mcp,
165
+ function a(t, e) {
166
+ return r({
167
+ ...t,
332
168
  lifecycle: {
333
- ...mcp.lifecycle,
334
- autoStart: true,
335
- },
336
- };
337
- return startMcpServer(mcpWithAutoStart, projectRoot);
169
+ ...t.lifecycle,
170
+ autoStart: !0
171
+ }
172
+ }, e);
338
173
  }
339
- /**
340
- * Get count of running MCP Servers
341
- * @returns Running count
342
- */
343
- function getRunningCount() {
344
- return mcpProcessState.size;
174
+ function l() {
175
+ return S.size;
345
176
  }
346
- /**
347
- * Clean up all state (before process exit)
348
- */
349
- function cleanup() {
350
- console.log('[MCP] Cleaning up all servers...');
351
- stopAllMcpServers();
177
+ function p() {
178
+ console.log('[MCP] Cleaning up all servers...'), o();
352
179
  }
353
- // Note: Library code should not register global signal handlers.
354
- // The calling application is responsible for cleanup on process exit.
355
- // Export cleanup() for callers to invoke manually.
356
- exports.default = {
357
- // Core API
358
- startMcpServers,
359
- stopMcpServer,
360
- stopAllMcpServers,
361
- // Status query
362
- getMcpStatus,
363
- getAllMcpStatus,
364
- getMcpConnectionInfo,
365
- getRunningCount,
366
- // Manual control
367
- startMcpServerManual,
368
- // Utility functions
369
- cleanup,
180
+ "use strict";
181
+ Object.defineProperty(exports, "__esModule", {
182
+ value: !0
183
+ });
184
+ var c = exports, d = {
185
+ get cleanup () {
186
+ return p;
187
+ },
188
+ get default () {
189
+ return M;
190
+ },
191
+ get getAllMcpStatus () {
192
+ return i;
193
+ },
194
+ get getMcpConnectionInfo () {
195
+ return u;
196
+ },
197
+ get getMcpStatus () {
198
+ return s;
199
+ },
200
+ get getRunningCount () {
201
+ return l;
202
+ },
203
+ get startMcpServer () {
204
+ return r;
205
+ },
206
+ get startMcpServerManual () {
207
+ return a;
208
+ },
209
+ get startMcpServers () {
210
+ return e;
211
+ },
212
+ get stopAllMcpServers () {
213
+ return o;
214
+ },
215
+ get stopMcpServer () {
216
+ return n;
217
+ }
218
+ };
219
+ for(var f in d)Object.defineProperty(c, f, {
220
+ enumerable: !0,
221
+ get: Object.getOwnPropertyDescriptor(d, f).get
222
+ });
223
+ let g = require("child_process"), m = /*#__PURE__*/ function(e) {
224
+ var r, n, o;
225
+ if (e && e.__esModule) return e;
226
+ if (null === e || "object" != typeof e && "function" != typeof e) return {
227
+ default: e
228
+ };
229
+ if ((r = t(void 0)) && r.has(e)) return r.get(e);
230
+ for(var s in n = {
231
+ __proto__: null
232
+ }, o = Object.defineProperty && Object.getOwnPropertyDescriptor, e)if ("default" !== s && Object.prototype.hasOwnProperty.call(e, s)) {
233
+ var i = o ? Object.getOwnPropertyDescriptor(e, s) : null;
234
+ i && (i.get || i.set) ? Object.defineProperty(n, s, i) : n[s] = e[s];
235
+ }
236
+ return n.default = e, r && r.set(e, n), n;
237
+ }(require("path")), S = new Map(), M = {
238
+ startMcpServers: e,
239
+ stopMcpServer: n,
240
+ stopAllMcpServers: o,
241
+ getMcpStatus: s,
242
+ getAllMcpStatus: i,
243
+ getMcpConnectionInfo: u,
244
+ getRunningCount: l,
245
+ startMcpServerManual: a,
246
+ cleanup: p
370
247
  };