@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
package/dist/lib/state.js CHANGED
@@ -1,61 +1,25 @@
1
- "use strict";
2
- /**
3
- * state.ts
4
- * State management for task-flow
5
- */
6
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
- if (k2 === undefined) k2 = k;
8
- var desc = Object.getOwnPropertyDescriptor(m, k);
9
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
- desc = { enumerable: true, get: function() { return m[k]; } };
11
- }
12
- Object.defineProperty(o, k2, desc);
13
- }) : (function(o, m, k, k2) {
14
- if (k2 === undefined) k2 = k;
15
- o[k2] = m[k];
16
- }));
17
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
- Object.defineProperty(o, "default", { enumerable: true, value: v });
19
- }) : function(o, v) {
20
- o["default"] = v;
21
- });
22
- var __importStar = (this && this.__importStar) || (function () {
23
- var ownKeys = function(o) {
24
- ownKeys = Object.getOwnPropertyNames || function (o) {
25
- var ar = [];
26
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
- return ar;
28
- };
29
- return ownKeys(o);
30
- };
31
- return function (mod) {
32
- if (mod && mod.__esModule) return mod;
33
- var result = {};
34
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
- __setModuleDefault(result, mod);
36
- return result;
1
+ function e(t) {
2
+ return "function" != typeof WeakMap ? null : (e = function(e) {
3
+ return new WeakMap();
4
+ })(t);
5
+ }
6
+ function t(t, r) {
7
+ var n, a, o;
8
+ if (!r && t && t.__esModule) return t;
9
+ if (null === t || "object" != typeof t && "function" != typeof t) return {
10
+ default: t
37
11
  };
38
- })();
39
- Object.defineProperty(exports, "__esModule", { value: true });
40
- exports.createInitialState = createInitialState;
41
- exports.loadState = loadState;
42
- exports.saveState = saveState;
43
- exports.updateState = updateState;
44
- exports.upsertWorktree = upsertWorktree;
45
- exports.removeWorktree = removeWorktree;
46
- exports.addTaskToHistory = addTaskToHistory;
47
- exports.getActiveWorktrees = getActiveWorktrees;
48
- exports.getWorktreeByTask = getWorktreeByTask;
49
- exports.clearCurrentTask = clearCurrentTask;
50
- const fs = __importStar(require("fs"));
51
- const path = __importStar(require("path"));
52
- const config_1 = require("./config");
53
- /**
54
- * Create initial state object
55
- * @returns Initial state
56
- */
57
- function createInitialState() {
58
- const now = new Date().toISOString();
12
+ if ((n = e(r)) && n.has(t)) return n.get(t);
13
+ for(var s in a = {
14
+ __proto__: null
15
+ }, o = Object.defineProperty && Object.getOwnPropertyDescriptor, t)if ("default" !== s && Object.prototype.hasOwnProperty.call(t, s)) {
16
+ var l = o ? Object.getOwnPropertyDescriptor(t, s) : null;
17
+ l && (l.get || l.set) ? Object.defineProperty(a, s, l) : a[s] = t[s];
18
+ }
19
+ return a.default = t, n && n.set(t, a), a;
20
+ }
21
+ function r() {
22
+ let e = new Date().toISOString();
59
23
  return {
60
24
  version: '1.0',
61
25
  status: 'initialized',
@@ -70,224 +34,149 @@ function createInitialState() {
70
34
  lastGateBlockedReason: null,
71
35
  lastGateBlockedPhase: null,
72
36
  lastMissingValidations: [],
73
- startedAt: now,
74
- updatedAt: now,
37
+ startedAt: e,
38
+ updatedAt: e
75
39
  };
76
40
  }
77
- /**
78
- * Load state from file
79
- * @param config - Config object
80
- * @returns State object
81
- */
82
- function loadState(config) {
83
- const cfg = config || (0, config_1.loadConfig)();
84
- const statePath = path.resolve(cfg.harnessRootAbs || '.harness', 'state.json');
85
- if (!fs.existsSync(statePath)) {
86
- return createInitialState();
87
- }
41
+ function n(e) {
42
+ let t = e || (0, S.loadConfig)(), n = h.resolve(t.harnessRootAbs || '.harness', 'state.json');
43
+ if (!k.existsSync(n)) return r();
88
44
  try {
89
- return JSON.parse(fs.readFileSync(statePath, 'utf8'));
90
- }
91
- catch (error) {
92
- const errorMessage = error instanceof Error ? error.message : 'Unknown error';
93
- console.warn('[STATE] Failed to load state file, attempting to restore from backup:', errorMessage);
94
- // Try to restore from latest backup
45
+ return JSON.parse(k.readFileSync(n, 'utf8'));
46
+ } catch (e) {
47
+ console.warn('[STATE] Failed to load state file, attempting to restore from backup:', e instanceof Error ? e.message : 'Unknown error');
95
48
  try {
96
- const harnessDir = cfg.harnessRootAbs;
97
- if (!harnessDir) {
98
- throw new Error('harnessRootAbs is undefined');
99
- }
100
- const backupPattern = /state\.json\.bak\.(\d+)$/;
101
- const files = fs.readdirSync(harnessDir);
102
- const backups = files
103
- .filter(f => backupPattern.test(f))
104
- .sort((a, b) => {
105
- const matchA = a.match(backupPattern);
106
- const matchB = b.match(backupPattern);
107
- return (matchB?.[1] || '0').localeCompare(matchA?.[1] || '0');
49
+ let e = t.harnessRootAbs;
50
+ if (!e) throw Error('harnessRootAbs is undefined');
51
+ let r = /state\.json\.bak\.(\d+)$/, n = k.readdirSync(e).filter((e)=>r.test(e)).sort((e, t)=>{
52
+ let n = e.match(r), a = t.match(r);
53
+ return (a?.[1] || '0').localeCompare(n?.[1] || '0');
108
54
  });
109
- if (backups.length > 0) {
110
- const latestBackupName = backups[0];
111
- if (!latestBackupName) {
112
- throw new Error('No backup file found');
113
- }
114
- const latestBackup = path.resolve(harnessDir, latestBackupName);
115
- console.log(`[STATE] Restoring from backup: ${latestBackup}`);
116
- return JSON.parse(fs.readFileSync(latestBackup, 'utf8'));
55
+ if (n.length > 0) {
56
+ let t = n[0];
57
+ if (!t) throw Error('No backup file found');
58
+ let r = h.resolve(e, t);
59
+ return console.log(`[STATE] Restoring from backup: ${r}`), JSON.parse(k.readFileSync(r, 'utf8'));
117
60
  }
61
+ } catch (e) {
62
+ console.warn('[STATE] Failed to restore from backup:', e instanceof Error ? e.message : 'Unknown error');
118
63
  }
119
- catch (restoreError) {
120
- console.warn('[STATE] Failed to restore from backup:', restoreError instanceof Error ? restoreError.message : 'Unknown error');
121
- }
122
- console.warn('[STATE] Creating new state');
123
- return createInitialState();
64
+ return console.warn('[STATE] Creating new state'), r();
124
65
  }
125
66
  }
126
- /**
127
- * Save state to file
128
- * @param state - State object
129
- * @param config - Config object
130
- * @returns Success
131
- */
132
- function saveState(state, config) {
133
- const cfg = config || (0, config_1.loadConfig)();
134
- const harnessRoot = cfg.harnessRootAbs;
135
- if (!harnessRoot) {
136
- console.error('[STATE] harnessRootAbs is undefined, cannot save state');
137
- return false;
138
- }
139
- const statePath = path.resolve(harnessRoot, 'state.json');
67
+ function a(e, t) {
68
+ let r = (t || (0, S.loadConfig)()).harnessRootAbs;
69
+ if (!r) return console.error('[STATE] harnessRootAbs is undefined, cannot save state'), !1;
70
+ let n = h.resolve(r, 'state.json');
140
71
  try {
141
- state.updatedAt = new Date().toISOString();
142
- fs.mkdirSync(harnessRoot, { recursive: true });
143
- // Backup existing state file before overwriting (prevent data corruption)
144
- if (fs.existsSync(statePath)) {
145
- const backupPath = `${statePath}.bak.${Date.now()}`;
72
+ if (e.updatedAt = new Date().toISOString(), k.mkdirSync(r, {
73
+ recursive: !0
74
+ }), k.existsSync(n)) {
75
+ let e = `${n}.bak.${Date.now()}`;
146
76
  try {
147
- fs.copyFileSync(statePath, backupPath);
148
- console.log(`[STATE] Created backup: ${backupPath}`);
149
- }
150
- catch (backupError) {
151
- console.warn('[STATE] Failed to create backup:', backupError instanceof Error ? backupError.message : 'Unknown error');
77
+ k.copyFileSync(n, e), console.log(`[STATE] Created backup: ${e}`);
78
+ } catch (e) {
79
+ console.warn('[STATE] Failed to create backup:', e instanceof Error ? e.message : 'Unknown error');
152
80
  }
153
81
  }
154
- fs.writeFileSync(statePath, JSON.stringify(state, null, 2), 'utf8');
155
- return true;
156
- }
157
- catch (error) {
158
- const errorMessage = error instanceof Error ? error.message : 'Unknown error';
159
- console.error('[STATE] Failed to save state:', errorMessage);
160
- return false;
82
+ return k.writeFileSync(n, JSON.stringify(e, null, 2), 'utf8'), !0;
83
+ } catch (e) {
84
+ return console.error('[STATE] Failed to save state:', e instanceof Error ? e.message : 'Unknown error'), !1;
161
85
  }
162
86
  }
163
- /**
164
- * Update state with partial changes
165
- * @param updates - Updates to apply
166
- * @param config - Config object
167
- * @returns Updated state
168
- */
169
- function updateState(updates, config) {
170
- const state = loadState(config);
171
- const updated = {
172
- ...state,
173
- ...updates,
174
- updatedAt: new Date().toISOString(),
87
+ function o(e, t) {
88
+ let r = {
89
+ ...n(t),
90
+ ...e,
91
+ updatedAt: new Date().toISOString()
175
92
  };
176
- saveState(updated, config);
177
- return updated;
93
+ return a(r, t), r;
178
94
  }
179
- /**
180
- * Add or update worktree in state
181
- * @param worktree - Worktree info
182
- * @param config - Config object
183
- * @returns Updated state
184
- */
185
- function upsertWorktree(worktree, config) {
186
- const state = loadState(config);
187
- const worktrees = Array.isArray(state.worktrees) ? [...state.worktrees] : [];
188
- const existingIndex = worktrees.findIndex((wt) => wt?.name === worktree.name);
189
- const now = new Date().toISOString();
190
- const nextWorktree = {
191
- name: worktree.name || '',
192
- path: worktree.path,
193
- branch: worktree.branch,
194
- status: worktree.status || 'active',
195
- agent: worktree.agent || 'implementer',
196
- task: worktree.task,
197
- startedAt: (existingIndex >= 0 && worktrees[existingIndex]?.startedAt) ? worktrees[existingIndex].startedAt : now,
198
- lastActivity: now,
199
- pendingChanges: worktree.pendingChanges || [],
95
+ function s(e, t) {
96
+ let r = n(t), o = Array.isArray(r.worktrees) ? [
97
+ ...r.worktrees
98
+ ] : [], s = o.findIndex((t)=>t?.name === e.name), l = new Date().toISOString(), u = {
99
+ name: e.name || '',
100
+ path: e.path,
101
+ branch: e.branch,
102
+ status: e.status || 'active',
103
+ agent: e.agent || 'implementer',
104
+ task: e.task,
105
+ startedAt: s >= 0 && o[s]?.startedAt ? o[s].startedAt : l,
106
+ lastActivity: l,
107
+ pendingChanges: e.pendingChanges || []
200
108
  };
201
- if (existingIndex >= 0) {
202
- worktrees[existingIndex] = nextWorktree;
203
- }
204
- else {
205
- worktrees.push(nextWorktree);
206
- }
207
- state.worktrees = worktrees;
208
- saveState(state, config);
209
- return state;
109
+ return s >= 0 ? o[s] = u : o.push(u), r.worktrees = o, a(r, t), r;
210
110
  }
211
- /**
212
- * Remove worktree from state
213
- * @param worktreeName - Worktree name
214
- * @param config - Config object
215
- * @returns Updated state
216
- */
217
- function removeWorktree(worktreeName, config) {
218
- const state = loadState(config);
219
- state.worktrees = (state.worktrees || []).filter((wt) => wt?.name !== worktreeName);
220
- saveState(state, config);
221
- return state;
111
+ function l(e, t) {
112
+ let r = n(t);
113
+ return r.worktrees = (r.worktrees || []).filter((t)=>t?.name !== e), a(r, t), r;
222
114
  }
223
- /**
224
- * Add task to history
225
- * @param taskInfo - Task info
226
- * @param config - Config object
227
- * @returns Updated state
228
- */
229
- function addTaskToHistory(taskInfo, config) {
230
- const state = loadState(config);
231
- const history = Array.isArray(state.taskHistory) ? [...state.taskHistory] : [];
232
- const existingIndex = history.findIndex((item) => item?.taskId === taskInfo.taskId);
233
- const now = new Date().toISOString();
234
- const summary = {
235
- taskId: taskInfo.taskId || '',
236
- title: taskInfo.title,
237
- status: taskInfo.status || 'running',
238
- currentPhase: taskInfo.currentPhase ?? null,
239
- phaseCompleted: taskInfo.phaseCompleted ?? null,
240
- reviewConclusion: taskInfo.reviewConclusion ?? null,
241
- startedAt: taskInfo.startedAt || now,
242
- completedAt: taskInfo.completedAt ?? null,
243
- lastUpdatedAt: now,
244
- archivePath: taskInfo.archivePath,
115
+ function u(e, t) {
116
+ let r = n(t), o = Array.isArray(r.taskHistory) ? [
117
+ ...r.taskHistory
118
+ ] : [], s = o.findIndex((t)=>t?.taskId === e.taskId), l = new Date().toISOString(), u = {
119
+ taskId: e.taskId || '',
120
+ title: e.title,
121
+ status: e.status || 'running',
122
+ currentPhase: e.currentPhase ?? null,
123
+ phaseCompleted: e.phaseCompleted ?? null,
124
+ reviewConclusion: e.reviewConclusion ?? null,
125
+ startedAt: e.startedAt || l,
126
+ completedAt: e.completedAt ?? null,
127
+ lastUpdatedAt: l,
128
+ archivePath: e.archivePath
245
129
  };
246
- if (existingIndex >= 0) {
247
- history[existingIndex] = summary;
248
- }
249
- else {
250
- history.push(summary);
251
- }
252
- state.taskHistory = history.sort((a, b) => String(b.lastUpdatedAt || '').localeCompare(String(a.lastUpdatedAt || '')));
253
- saveState(state, config);
254
- return state;
130
+ return s >= 0 ? o[s] = u : o.push(u), r.taskHistory = o.sort((e, t)=>String(t.lastUpdatedAt || '').localeCompare(String(e.lastUpdatedAt || ''))), a(r, t), r;
255
131
  }
256
- /**
257
- * Get active worktrees
258
- * @param config - Config object
259
- * @returns Active worktrees
260
- */
261
- function getActiveWorktrees(config) {
262
- const state = loadState(config);
263
- return (state.worktrees || []).filter((wt) => wt?.status === 'active');
132
+ function i(e) {
133
+ return (n(e).worktrees || []).filter((e)=>e?.status === 'active');
264
134
  }
265
- /**
266
- * Get worktree by task ID
267
- * @param taskId - Task ID
268
- * @param config - Config object
269
- * @returns Worktree or null
270
- */
271
- function getWorktreeByTask(taskId, config) {
272
- const state = loadState(config);
273
- return (state.worktrees || []).find((wt) => wt?.task === taskId) || null;
135
+ function c(e, t) {
136
+ return (n(t).worktrees || []).find((t)=>t?.task === e) || null;
274
137
  }
275
- /**
276
- * Clear current task state (after merge)
277
- * @param config - Config object
278
- * @returns Updated state
279
- */
280
- function clearCurrentTask(config) {
281
- const state = loadState(config);
282
- const now = new Date().toISOString();
283
- state.status = 'completed';
284
- state.currentPhase = null;
285
- state.currentTask = null;
286
- state.currentSnapshot = null;
287
- state.reviewConclusion = null;
288
- state.phaseCompleted = null;
289
- state.worktrees = [];
290
- state.updatedAt = now;
291
- saveState(state, config);
292
- return state;
138
+ function d(e) {
139
+ let t = n(e), r = new Date().toISOString();
140
+ return t.status = 'completed', t.currentPhase = null, t.currentTask = null, t.currentSnapshot = null, t.reviewConclusion = null, t.phaseCompleted = null, t.worktrees = [], t.updatedAt = r, a(t, e), t;
293
141
  }
142
+ "use strict";
143
+ Object.defineProperty(exports, "__esModule", {
144
+ value: !0
145
+ });
146
+ var p = exports, f = {
147
+ get addTaskToHistory () {
148
+ return u;
149
+ },
150
+ get clearCurrentTask () {
151
+ return d;
152
+ },
153
+ get createInitialState () {
154
+ return r;
155
+ },
156
+ get getActiveWorktrees () {
157
+ return i;
158
+ },
159
+ get getWorktreeByTask () {
160
+ return c;
161
+ },
162
+ get loadState () {
163
+ return n;
164
+ },
165
+ get removeWorktree () {
166
+ return l;
167
+ },
168
+ get saveState () {
169
+ return a;
170
+ },
171
+ get updateState () {
172
+ return o;
173
+ },
174
+ get upsertWorktree () {
175
+ return s;
176
+ }
177
+ };
178
+ for(var g in f)Object.defineProperty(p, g, {
179
+ enumerable: !0,
180
+ get: Object.getOwnPropertyDescriptor(f, g).get
181
+ });
182
+ let k = /*#__PURE__*/ t(require("fs")), h = /*#__PURE__*/ t(require("path")), S = require("./config");