@bicorne/task-flow 0.1.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 (58) hide show
  1. package/README.md +337 -145
  2. package/SKILL.md +9 -5
  3. package/assets/.harnessrc +0 -1
  4. package/dist/commands/analyze.js +160 -318
  5. package/dist/commands/archive.js +44 -48
  6. package/dist/commands/design.js +225 -400
  7. package/dist/commands/extract.js +174 -303
  8. package/dist/commands/init.js +103 -148
  9. package/dist/commands/merge/index.js +184 -295
  10. package/dist/commands/merge/merger.js +112 -134
  11. package/dist/commands/merge/types.js +3 -5
  12. package/dist/commands/merge/validators.js +115 -132
  13. package/dist/commands/merge.js +46 -13
  14. package/dist/commands/start.js +155 -248
  15. package/dist/commands/status.js +68 -129
  16. package/dist/commands/sync.js +37 -53
  17. package/dist/commands/tasks-gen/doc-parser.js +148 -228
  18. package/dist/commands/tasks-gen/generators.js +104 -116
  19. package/dist/commands/tasks-gen/index.js +206 -314
  20. package/dist/commands/tasks-gen/parsers.js +131 -232
  21. package/dist/commands/tasks-gen/templates.js +9 -10
  22. package/dist/commands/tasks-gen/types.js +36 -14
  23. package/dist/commands/tasks-gen/validators.js +33 -49
  24. package/dist/commands/tasks.js +58 -20
  25. package/dist/commands/worktree.js +167 -249
  26. package/dist/hooks/check-prd-exists.js +45 -55
  27. package/dist/hooks/check-worktree-conflict.js +68 -101
  28. package/dist/hooks/hook-runner/executor.js +134 -126
  29. package/dist/hooks/hook-runner/index.js +181 -196
  30. package/dist/hooks/hook-runner/loader.js +74 -113
  31. package/dist/hooks/hook-runner/types.js +3 -5
  32. package/dist/hooks/hook-runner.js +94 -28
  33. package/dist/hooks/phase-complete-detector.js +125 -191
  34. package/dist/hooks/phase-gate-validator.js +315 -376
  35. package/dist/hooks/save-checkpoint.js +87 -130
  36. package/dist/hooks/start-mcp-servers.js +50 -65
  37. package/dist/hooks/stop-mcp-servers.js +40 -49
  38. package/dist/index.js +84 -153
  39. package/dist/lib/archive.js +126 -209
  40. package/dist/lib/config.d.ts +0 -2
  41. package/dist/lib/config.js +141 -230
  42. package/dist/lib/constants.js +155 -145
  43. package/dist/lib/interactive.js +98 -148
  44. package/dist/lib/mcp-client.js +197 -320
  45. package/dist/lib/state.js +142 -253
  46. package/dist/slash/executor.js +309 -233
  47. package/dist/slash/index.js +69 -43
  48. package/dist/slash/parser.js +84 -97
  49. package/dist/slash/registry.js +100 -88
  50. package/dist/spec/openspec-to-task/builders.js +96 -109
  51. package/dist/spec/openspec-to-task/index.js +112 -173
  52. package/dist/spec/openspec-to-task/parsers.js +148 -219
  53. package/dist/spec/openspec-to-task/types.js +3 -5
  54. package/dist/spec/sync-openspec-to-task.js +47 -19
  55. package/dist/spec/sync-task-to-openspec.js +241 -272
  56. package/dist/types/ai-context.js +3 -8
  57. package/package.json +9 -7
  58. package/references/CLI-TUTORIAL.md +4 -10
package/dist/index.js CHANGED
@@ -1,50 +1,10 @@
1
1
  #!/usr/bin/env node
2
- "use strict";
3
- /**
4
- * index.ts
5
- * CLI entry point for @bicorne/task-flow
6
- *
7
- * Supports both traditional CLI commands and slash commands:
8
- * task-flow extract --change my-feature
9
- * /tf:propose my-feature (in AI chat)
10
- */
11
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
- if (k2 === undefined) k2 = k;
13
- var desc = Object.getOwnPropertyDescriptor(m, k);
14
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
- desc = { enumerable: true, get: function() { return m[k]; } };
16
- }
17
- Object.defineProperty(o, k2, desc);
18
- }) : (function(o, m, k, k2) {
19
- if (k2 === undefined) k2 = k;
20
- o[k2] = m[k];
21
- }));
22
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
- Object.defineProperty(o, "default", { enumerable: true, value: v });
24
- }) : function(o, v) {
25
- o["default"] = v;
26
- });
27
- var __importStar = (this && this.__importStar) || (function () {
28
- var ownKeys = function(o) {
29
- ownKeys = Object.getOwnPropertyNames || function (o) {
30
- var ar = [];
31
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
- return ar;
33
- };
34
- return ownKeys(o);
35
- };
36
- return function (mod) {
37
- if (mod && mod.__esModule) return mod;
38
- var result = {};
39
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
- __setModuleDefault(result, mod);
41
- return result;
42
- };
43
- })();
44
- Object.defineProperty(exports, "__esModule", { value: true });
45
- const path = __importStar(require("path"));
46
- const slash_1 = require("./slash");
47
- function printHelp() {
2
+ function e(t) {
3
+ return "function" != typeof WeakMap ? null : (e = function(e) {
4
+ return new WeakMap();
5
+ })(t);
6
+ }
7
+ function t() {
48
8
  console.log(`
49
9
  task-flow - Git worktree-based parallel task execution system
50
10
 
@@ -66,7 +26,7 @@ Commands:
66
26
  merge Merge completed worktree back to main branch
67
27
  sync Sync task execution status to spec
68
28
  help Show this help message
69
- ${(0, slash_1.printSlashHelp)()}
29
+ ${(0, c.printSlashHelp)()}
70
30
  Tasks Command Options:
71
31
  --input <json> Provide tasks JSON directly (AI input)
72
32
  --yes, -y Skip interactive confirmation
@@ -106,133 +66,104 @@ Documentation:
106
66
  https://github.com/didengren/harness-task-flow
107
67
  `);
108
68
  }
109
- function printVersion() {
110
- // eslint-disable-next-line @typescript-eslint/no-require-imports
111
- const pkg = require('../package.json');
112
- console.log(`@bicorne/task-flow v${pkg.version}`);
69
+ function o() {
70
+ let e = require('../package.json');
71
+ console.log(`@bicorne/task-flow v${e.version}`);
113
72
  }
114
- function parseArgs(argv) {
115
- const args = {
73
+ function r(e) {
74
+ let t = {
116
75
  command: null,
117
76
  options: {},
118
- help: false,
119
- version: false,
77
+ help: !1,
78
+ version: !1
120
79
  };
121
- for (let i = 2; i < argv.length; i += 1) {
122
- const token = argv[i] || '';
123
- if (token.startsWith('--')) {
124
- const key = token.slice(2);
125
- if (key === 'help' || key === 'h') {
126
- args.help = true;
80
+ for(let o = 2; o < e.length; o += 1){
81
+ let r = e[o] || '';
82
+ if (r.startsWith('--')) {
83
+ let n = r.slice(2);
84
+ if ('help' === n || 'h' === n) {
85
+ t.help = !0;
127
86
  continue;
128
87
  }
129
- if (key === 'version' || key === 'v') {
130
- args.version = true;
88
+ if ('version' === n || 'v' === n) {
89
+ t.version = !0;
131
90
  continue;
132
91
  }
133
- const next = argv[i + 1];
134
- if (!next || next.startsWith('--')) {
135
- args.options[key] = true;
92
+ let s = e[o + 1];
93
+ if (!s || s.startsWith('--')) {
94
+ t.options[n] = !0;
136
95
  continue;
137
96
  }
138
- args.options[key] = next;
139
- i += 1;
140
- }
141
- else if (token.startsWith('-') && token.length === 2) {
142
- const shortOpt = token.slice(1);
143
- if (shortOpt === 'h') {
144
- args.help = true;
145
- }
146
- else if (shortOpt === 'v') {
147
- args.version = true;
148
- }
149
- }
150
- else if (!args.command) {
151
- args.command = token || null;
152
- }
97
+ t.options[n] = s, o += 1;
98
+ } else if (r.startsWith('-') && 2 === r.length) {
99
+ let e = r.slice(1);
100
+ 'h' === e ? t.help = !0 : 'v' === e && (t.version = !0);
101
+ } else t.command || (t.command = r || null);
153
102
  }
154
- return args;
103
+ return t;
155
104
  }
156
- function runCommand(command, options) {
157
- const commandPath = path.resolve(__dirname, 'commands', `${command}.js`);
105
+ function n(e, t) {
106
+ let o = i.resolve(__dirname, 'commands', `${e}.js`);
158
107
  try {
159
- // eslint-disable-next-line @typescript-eslint/no-require-imports
160
- const commandModule = require(commandPath);
161
- if (typeof commandModule === 'function') {
162
- commandModule(options);
163
- }
164
- else if (commandModule.main && typeof commandModule.main === 'function') {
165
- commandModule.main();
166
- }
167
- }
168
- catch (error) {
169
- if (error.code === 'MODULE_NOT_FOUND') {
170
- console.error(`[ERROR] Unknown command: ${command}`);
171
- console.error('Run "task-flow help" for available commands.');
172
- process.exit(1);
173
- }
174
- console.error(`[ERROR] Command failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
175
- process.exit(1);
108
+ let e = require(o);
109
+ 'function' == typeof e ? e(t) : e.main && 'function' == typeof e.main && e.main();
110
+ } catch (t) {
111
+ 'MODULE_NOT_FOUND' === t.code && (console.error(`[ERROR] Unknown command: ${e}`), console.error('Run "task-flow help" for available commands.'), process.exit(1)), console.error(`[ERROR] Command failed: ${t instanceof Error ? t.message : 'Unknown error'}`), process.exit(1);
176
112
  }
177
113
  }
178
- async function handleSlashCommand(input) {
179
- const result = await (0, slash_1.runSlashCommand)(input);
180
- if (result.success) {
181
- console.log('');
182
- console.log(`[SLASH]/tf:${result.command} completed`);
183
- if (result.steps) {
184
- for (const step of result.steps) {
185
- const icon = step.success ? '✓' : '✗';
186
- console.log(` ${icon} ${step.step}: ${step.message || (step.success ? 'OK' : 'Failed')}`);
187
- }
114
+ async function s(e) {
115
+ let t = await (0, c.runSlashCommand)(e);
116
+ if (t.success) {
117
+ if (console.log(''), console.log(`[SLASH] ✓ /tf:${t.command} completed`), t.steps) for (let e of t.steps){
118
+ let t = e.success ? '' : '✗';
119
+ console.log(` ${t} ${e.step}: ${e.message || (e.success ? 'OK' : 'Failed')}`);
188
120
  }
189
121
  console.log('');
190
- }
191
- else {
192
- console.error('');
193
- console.error(`[SLASH] ✗ /tf:${result.command} failed`);
194
- if (result.error) {
195
- console.error(` Error: ${result.error}`);
196
- }
197
- if (result.steps) {
198
- for (const step of result.steps) {
199
- if (!step.success) {
200
- console.error(` ✗ ${step.step}: ${step.message || 'Failed'}`);
201
- }
202
- }
203
- }
204
- console.error('');
205
- process.exit(1);
122
+ } else {
123
+ if (console.error(''), console.error(`[SLASH] ✗ /tf:${t.command} failed`), t.error && console.error(` Error: ${t.error}`), t.steps) for (let e of t.steps)e.success || console.error(` ✗ ${e.step}: ${e.message || 'Failed'}`);
124
+ console.error(''), process.exit(1);
206
125
  }
207
126
  }
208
- async function main() {
209
- const rawCommand = process.argv[2] || '';
210
- if ((0, slash_1.isSlashCommand)(rawCommand)) {
211
- const fullInput = process.argv.slice(2).join(' ');
212
- await handleSlashCommand(fullInput);
127
+ async function a() {
128
+ let e = process.argv[2] || '';
129
+ if ((0, c.isSlashCommand)(e)) {
130
+ let e = process.argv.slice(2).join(' ');
131
+ await s(e);
213
132
  return;
214
133
  }
215
- const args = parseArgs(process.argv);
216
- if (args.version) {
217
- printVersion();
218
- process.exit(0);
219
- }
220
- if (args.help || !args.command) {
221
- printHelp();
222
- process.exit(0);
134
+ let a = r(process.argv);
135
+ a.version && (o(), process.exit(0)), (a.help || !a.command) && (t(), process.exit(0)), 'help' === a.command && (t(), process.exit(0)), n(a.command, a.options);
136
+ }
137
+ "use strict";
138
+ Object.defineProperty(exports, "__esModule", {
139
+ value: !0
140
+ }), Object.defineProperty(exports, "default", {
141
+ enumerable: !0,
142
+ get: function() {
143
+ return l;
223
144
  }
224
- if (args.command === 'help') {
225
- printHelp();
226
- process.exit(0);
145
+ });
146
+ let i = /*#__PURE__*/ function(t) {
147
+ var o, r, n;
148
+ if (t && t.__esModule) return t;
149
+ if (null === t || "object" != typeof t && "function" != typeof t) return {
150
+ default: t
151
+ };
152
+ if ((o = e(void 0)) && o.has(t)) return o.get(t);
153
+ for(var s in r = {
154
+ __proto__: null
155
+ }, n = Object.defineProperty && Object.getOwnPropertyDescriptor, t)if ("default" !== s && Object.prototype.hasOwnProperty.call(t, s)) {
156
+ var a = n ? Object.getOwnPropertyDescriptor(t, s) : null;
157
+ a && (a.get || a.set) ? Object.defineProperty(r, s, a) : r[s] = t[s];
227
158
  }
228
- runCommand(args.command, args.options);
229
- }
230
- main();
231
- exports.default = {
232
- main,
233
- printHelp,
234
- printVersion,
235
- parseArgs,
236
- runCommand,
237
- handleSlashCommand,
159
+ return r.default = t, o && o.set(t, r), r;
160
+ }(require("path")), c = require("./slash");
161
+ a();
162
+ let l = {
163
+ main: a,
164
+ printHelp: t,
165
+ printVersion: o,
166
+ parseArgs: r,
167
+ runCommand: n,
168
+ handleSlashCommand: s
238
169
  };
@@ -1,226 +1,143 @@
1
- "use strict";
2
- /**
3
- * archive.ts
4
- * Archive task state to persistent storage
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;
37
- };
38
- })();
39
- Object.defineProperty(exports, "__esModule", { value: true });
40
- exports.archiveTaskState = archiveTaskState;
41
- const fs = __importStar(require("fs"));
42
- const path = __importStar(require("path"));
43
- const config_1 = require("./config");
44
- const state_1 = require("./state");
45
- /**
46
- * Ensure path uses POSIX separators
47
- */
48
- function ensurePosix(input) {
49
- return String(input || '').replace(/\\/g, '/');
1
+ function e(t) {
2
+ return "function" != typeof WeakMap ? null : (e = function(e) {
3
+ return new WeakMap();
4
+ })(t);
50
5
  }
51
- /**
52
- * Read JSON file if exists
53
- */
54
- function readJsonIfExists(filePath) {
55
- if (!filePath || !fs.existsSync(filePath)) {
56
- return null;
57
- }
58
- try {
59
- return JSON.parse(fs.readFileSync(filePath, 'utf8'));
60
- }
61
- catch {
62
- return null;
6
+ function t(t, r) {
7
+ var a, s, n;
8
+ if (!r && t && t.__esModule) return t;
9
+ if (null === t || "object" != typeof t && "function" != typeof t) return {
10
+ default: t
11
+ };
12
+ if ((a = e(r)) && a.has(t)) return a.get(t);
13
+ for(var l in s = {
14
+ __proto__: null
15
+ }, n = Object.defineProperty && Object.getOwnPropertyDescriptor, t)if ("default" !== l && Object.prototype.hasOwnProperty.call(t, l)) {
16
+ var i = n ? Object.getOwnPropertyDescriptor(t, l) : null;
17
+ i && (i.get || i.set) ? Object.defineProperty(s, l, i) : s[l] = t[l];
63
18
  }
19
+ return s.default = t, a && a.set(t, s), s;
64
20
  }
65
- /**
66
- * Get task file path
67
- */
68
- function getTaskFilePath(config, taskId) {
69
- return path.resolve(config.tasksDirAbs, `${taskId}.json`);
70
- }
71
- /**
72
- * Read task JSON file
73
- */
74
- function readTaskJson(config, taskId) {
75
- const taskPath = getTaskFilePath(config, taskId);
76
- return readJsonIfExists(taskPath);
21
+ function r(e) {
22
+ return String(e || '').replace(/\\/g, '/');
77
23
  }
78
- /**
79
- * Get task summary from JSON
80
- */
81
- function getTaskSummary(taskJson, taskId) {
82
- return {
83
- taskId,
84
- title: taskJson?.title || '',
85
- type: taskJson?.type || '',
86
- priority: taskJson?.priority || 'medium',
87
- };
88
- }
89
- /**
90
- * Get Spec metadata from task JSON
91
- */
92
- function getMetadataSpec(taskJson) {
93
- if (!taskJson?.metadata?.change) {
24
+ function a(e) {
25
+ if (!e || !o.existsSync(e)) return null;
26
+ try {
27
+ return JSON.parse(o.readFileSync(e, 'utf8'));
28
+ } catch {
94
29
  return null;
95
30
  }
96
- return {
97
- change: taskJson.metadata.change,
98
- proposal: taskJson.docs_to_read?.[0] || null,
99
- design: taskJson.docs_to_read?.[1] || null,
100
- tasks: taskJson.docs_to_read?.[2] || null,
101
- manifest: taskJson.metadata?.manifest || null,
102
- execution: taskJson.metadata?.execution || null,
103
- version: 'v1',
104
- };
105
31
  }
106
- /**
107
- * Get artifacts paths
108
- */
109
- function getArtifacts(config, taskId, taskJson, spec) {
110
- return {
111
- task: ensurePosix(path.relative(config.projectRoot, path.resolve(config.tasksDirAbs, `${taskId}.json`))),
112
- implementationSnapshot: taskJson?.metadata?.outputs?.snapshot || null,
113
- review: taskJson?.metadata?.outputs?.report || null,
114
- execution: spec?.execution || null,
115
- archive: ensurePosix(path.relative(config.projectRoot, path.resolve(config.archiveDirAbs, `${taskId}.json`))),
32
+ function s(e = {}) {
33
+ var t;
34
+ let n = (0, p.loadConfig)({
35
+ cwd: e.cwd
36
+ }), l = (0, c.loadState)(n), i = e.taskId || l.currentTask;
37
+ if (!i) return {
38
+ skipped: !0,
39
+ reason: 'missing-task-id'
116
40
  };
117
- }
118
- /**
119
- * Build event object
120
- */
121
- function buildEvent(options, state) {
122
- return {
123
- type: options.eventType || 'state_synced',
124
- at: options.at || new Date().toISOString(),
125
- status: options.status || state?.status || null,
126
- phase: options.phase || state?.currentPhase || null,
127
- phaseCompleted: options.phaseCompleted || state?.phaseCompleted || null,
128
- reviewConclusion: options.reviewConclusion || state?.reviewConclusion || null,
129
- reason: options.reason || state?.lastGateBlockedReason || null,
130
- };
131
- }
132
- /**
133
- * Check if two events are the same
134
- */
135
- function isSameEvent(left, right) {
136
- if (!left || !right) {
137
- return false;
138
- }
139
- return left.type === right.type
140
- && left.status === right.status
141
- && left.phase === right.phase
142
- && left.phaseCompleted === right.phaseCompleted
143
- && left.reviewConclusion === right.reviewConclusion
144
- && left.reason === right.reason;
145
- }
146
- /**
147
- * Archive task state
148
- */
149
- function archiveTaskState(options = {}) {
150
- const config = (0, config_1.loadConfig)({ cwd: options.cwd });
151
- const state = (0, state_1.loadState)(config);
152
- const taskId = options.taskId || state.currentTask;
153
- if (!taskId) {
154
- return { skipped: true, reason: 'missing-task-id' };
155
- }
156
- const taskJson = readTaskJson(config, taskId);
157
- if (!taskJson) {
158
- return { skipped: true, reason: 'missing-task-file' };
159
- }
160
- const archiveDir = config.archiveDirAbs;
161
- const archivePath = path.resolve(archiveDir, `${taskId}.json`);
162
- const archiveRelativePath = ensurePosix(path.relative(config.projectRoot, archivePath));
163
- const previous = readJsonIfExists(archivePath) || {};
164
- const taskSummary = getTaskSummary(taskJson, taskId);
165
- const spec = getMetadataSpec(taskJson);
166
- const now = options.at || new Date().toISOString();
167
- const lifecycleStatus = options.status || state.status || previous.lifecycle?.status || 'initialized';
168
- const lifecycle = {
169
- createdAt: previous.lifecycle?.createdAt || state.startedAt || now,
170
- startedAt: previous.lifecycle?.startedAt || state.startedAt || now,
171
- completedAt: lifecycleStatus === 'completed' ? (options.completedAt || now) : (previous.lifecycle?.completedAt || null),
172
- lastUpdatedAt: now,
173
- status: lifecycleStatus,
174
- currentPhase: options.phase || state.currentPhase || null,
175
- phaseCompleted: options.phaseCompleted || state.phaseCompleted || null,
176
- reviewConclusion: options.reviewConclusion || state.reviewConclusion || null,
41
+ let d = a(u.resolve(n.tasksDirAbs, `${i}.json`));
42
+ if (!d) return {
43
+ skipped: !0,
44
+ reason: 'missing-task-file'
177
45
  };
178
- const archiveDoc = {
179
- taskId,
180
- title: taskSummary.title,
181
- type: taskSummary.type,
182
- priority: taskSummary.priority,
183
- spec,
184
- lifecycle,
185
- artifacts: getArtifacts(config, taskId, taskJson, spec),
186
- mergeStrategy: taskJson?.metadata?.mergeStrategy || { type: 'squash', deleteBranch: true, deleteWorktree: true },
187
- worktrees: Array.isArray(state.worktrees) ? state.worktrees.filter((item) => item?.task === taskId) : [],
46
+ let h = n.archiveDirAbs, y = u.resolve(h, `${i}.json`), f = r(u.relative(n.projectRoot, y)), v = a(y) || {}, m = {
47
+ taskId: i,
48
+ title: d?.title || '',
49
+ type: d?.type || '',
50
+ priority: d?.priority || 'medium'
51
+ }, g = d?.metadata?.change ? {
52
+ change: d.metadata.change,
53
+ proposal: d.docs_to_read?.[0] || null,
54
+ design: d.docs_to_read?.[1] || null,
55
+ tasks: d.docs_to_read?.[2] || null,
56
+ manifest: d.metadata?.manifest || null,
57
+ execution: d.metadata?.execution || null,
58
+ version: 'v1'
59
+ } : null, k = e.at || new Date().toISOString(), w = e.status || l.status || v.lifecycle?.status || 'initialized', C = {
60
+ createdAt: v.lifecycle?.createdAt || l.startedAt || k,
61
+ startedAt: v.lifecycle?.startedAt || l.startedAt || k,
62
+ completedAt: 'completed' === w ? e.completedAt || k : v.lifecycle?.completedAt || null,
63
+ lastUpdatedAt: k,
64
+ status: w,
65
+ currentPhase: e.phase || l.currentPhase || null,
66
+ phaseCompleted: e.phaseCompleted || l.phaseCompleted || null,
67
+ reviewConclusion: e.reviewConclusion || l.reviewConclusion || null
68
+ }, _ = {
69
+ taskId: i,
70
+ title: m.title,
71
+ type: m.type,
72
+ priority: m.priority,
73
+ spec: g,
74
+ lifecycle: C,
75
+ artifacts: {
76
+ task: r(u.relative(n.projectRoot, u.resolve(n.tasksDirAbs, `${i}.json`))),
77
+ implementationSnapshot: d?.metadata?.outputs?.snapshot || null,
78
+ review: d?.metadata?.outputs?.report || null,
79
+ execution: g?.execution || null,
80
+ archive: r(u.relative(n.projectRoot, u.resolve(n.archiveDirAbs, `${i}.json`)))
81
+ },
82
+ mergeStrategy: d?.metadata?.mergeStrategy || {
83
+ type: 'squash',
84
+ deleteBranch: !0,
85
+ deleteWorktree: !0
86
+ },
87
+ worktrees: Array.isArray(l.worktrees) ? l.worktrees.filter((e)=>e?.task === i) : [],
188
88
  lastGate: {
189
- blockedAt: state.lastGateBlockedAt || null,
190
- reason: options.reason || state.lastGateBlockedReason || null,
191
- phase: state.lastGateBlockedPhase || null,
192
- missingValidations: Array.isArray(state.lastMissingValidations) ? state.lastMissingValidations : [],
89
+ blockedAt: l.lastGateBlockedAt || null,
90
+ reason: e.reason || l.lastGateBlockedReason || null,
91
+ phase: l.lastGateBlockedPhase || null,
92
+ missingValidations: Array.isArray(l.lastMissingValidations) ? l.lastMissingValidations : []
193
93
  },
194
94
  taskPhases: {
195
- planning: taskJson?.status || 'pending',
196
- implementation: taskJson?.status || 'pending',
197
- review: taskJson?.status || 'pending',
95
+ planning: d?.status || 'pending',
96
+ implementation: d?.status || 'pending',
97
+ review: d?.status || 'pending'
198
98
  },
199
- events: Array.isArray(previous.events) ? previous.events : [],
99
+ events: Array.isArray(v.events) ? v.events : []
100
+ }, A = {
101
+ type: e.eventType || 'state_synced',
102
+ at: e.at || new Date().toISOString(),
103
+ status: e.status || l?.status || null,
104
+ phase: e.phase || l?.currentPhase || null,
105
+ phaseCompleted: e.phaseCompleted || l?.phaseCompleted || null,
106
+ reviewConclusion: e.reviewConclusion || l?.reviewConclusion || null,
107
+ reason: e.reason || l?.lastGateBlockedReason || null
200
108
  };
201
- const nextEvent = buildEvent(options, state);
202
- if (!isSameEvent(archiveDoc.events[archiveDoc.events.length - 1], nextEvent)) {
203
- archiveDoc.events.push(nextEvent);
204
- }
205
- fs.mkdirSync(archiveDir, { recursive: true });
206
- fs.writeFileSync(archivePath, JSON.stringify(archiveDoc, null, 2), 'utf8');
207
- if (options.updateState !== false) {
208
- (0, state_1.addTaskToHistory)({
209
- taskId,
210
- title: taskSummary.title,
211
- status: lifecycleStatus,
212
- currentPhase: options.phase || state.currentPhase,
213
- phaseCompleted: options.phaseCompleted || state.phaseCompleted,
214
- reviewConclusion: options.reviewConclusion || state.reviewConclusion,
215
- archivePath: archiveRelativePath,
216
- }, config);
217
- }
218
- return {
219
- skipped: false,
220
- taskId,
221
- archivePath: archiveRelativePath,
109
+ return (t = _.events[_.events.length - 1]) && A && t.type === A.type && t.status === A.status && t.phase === A.phase && t.phaseCompleted === A.phaseCompleted && t.reviewConclusion === A.reviewConclusion && t.reason === A.reason || _.events.push(A), o.mkdirSync(h, {
110
+ recursive: !0
111
+ }), o.writeFileSync(y, JSON.stringify(_, null, 2), 'utf8'), !1 !== e.updateState && (0, c.addTaskToHistory)({
112
+ taskId: i,
113
+ title: m.title,
114
+ status: w,
115
+ currentPhase: e.phase || l.currentPhase,
116
+ phaseCompleted: e.phaseCompleted || l.phaseCompleted,
117
+ reviewConclusion: e.reviewConclusion || l.reviewConclusion,
118
+ archivePath: f
119
+ }, n), {
120
+ skipped: !1,
121
+ taskId: i,
122
+ archivePath: f
222
123
  };
223
124
  }
224
- exports.default = {
225
- archiveTaskState,
125
+ "use strict";
126
+ Object.defineProperty(exports, "__esModule", {
127
+ value: !0
128
+ });
129
+ var n = exports, l = {
130
+ get archiveTaskState () {
131
+ return s;
132
+ },
133
+ get default () {
134
+ return d;
135
+ }
136
+ };
137
+ for(var i in l)Object.defineProperty(n, i, {
138
+ enumerable: !0,
139
+ get: Object.getOwnPropertyDescriptor(l, i).get
140
+ });
141
+ let o = /*#__PURE__*/ t(require("fs")), u = /*#__PURE__*/ t(require("path")), p = require("./config"), c = require("./state"), d = {
142
+ archiveTaskState: s
226
143
  };
@@ -21,7 +21,6 @@ export interface Config {
21
21
  snapshotsDir?: string;
22
22
  archiveDir?: string;
23
23
  reportsDir?: string;
24
- plansDir?: string;
25
24
  specRoot?: string;
26
25
  configFile?: string;
27
26
  harnessRootAbs?: string;
@@ -30,7 +29,6 @@ export interface Config {
30
29
  snapshotsDirAbs?: string;
31
30
  archiveDirAbs?: string;
32
31
  reportsDirAbs?: string;
33
- plansDirAbs?: string;
34
32
  specRootAbs?: string;
35
33
  projectRoot?: string;
36
34
  configPath?: string;