@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,288 +1,257 @@
1
- "use strict";
2
- /**
3
- * sync-task-to-openspec.ts
4
- * Sync task execution status back to Spec
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.syncTaskToSpec = syncTaskToSpec;
41
- exports.main = main;
42
- const fs = __importStar(require("fs"));
43
- const path = __importStar(require("path"));
44
- const config_1 = require("../lib/config");
45
- const state_1 = require("../lib/state");
46
- /**
47
- * Validate that a resolved path is within the project root (prevent path traversal)
48
- * @param resolvedPath - The resolved absolute path
49
- * @param projectRoot - The project root directory
50
- * @returns True if path is within project root
51
- */
52
- function isPathWithinProject(resolvedPath, projectRoot) {
53
- const relativePath = path.relative(projectRoot, resolvedPath);
54
- return !relativePath.startsWith('..') && !path.isAbsolute(relativePath);
1
+ function e(t) {
2
+ return "function" != typeof WeakMap ? null : (e = function(e) {
3
+ return new WeakMap();
4
+ })(t);
55
5
  }
56
- function parseArgs(argv) {
57
- const args = {};
58
- for (let i = 2; i < argv.length; i += 1) {
59
- const token = argv[i] || '';
60
- if (!token.startsWith('--')) {
61
- continue;
62
- }
63
- const key = token.slice(2);
64
- const next = argv[i + 1] || '';
65
- if (!next || next.startsWith('--')) {
66
- args[key] = true;
67
- continue;
68
- }
69
- args[key] = next;
70
- i += 1;
6
+ function t(t, n) {
7
+ var r, s, a;
8
+ if (!n && t && t.__esModule) return t;
9
+ if (null === t || "object" != typeof t && "function" != typeof t) return {
10
+ default: t
11
+ };
12
+ if ((r = e(n)) && r.has(t)) return r.get(t);
13
+ for(var l in s = {
14
+ __proto__: null
15
+ }, a = Object.defineProperty && Object.getOwnPropertyDescriptor, t)if ("default" !== l && Object.prototype.hasOwnProperty.call(t, l)) {
16
+ var o = a ? Object.getOwnPropertyDescriptor(t, l) : null;
17
+ o && (o.get || o.set) ? Object.defineProperty(s, l, o) : s[l] = t[l];
71
18
  }
72
- return args;
19
+ return s.default = t, r && r.set(t, s), s;
73
20
  }
74
- function ensurePosix(p) {
75
- return String(p || '').replace(/\\/g, '/');
21
+ function n(e) {
22
+ return String(e || '').replace(/\\/g, '/');
76
23
  }
77
- function readJsonIfExists(filePath) {
78
- if (!filePath || !fs.existsSync(filePath)) {
79
- return null;
80
- }
24
+ function r(e) {
25
+ if (!e || !c.existsSync(e)) return null;
81
26
  try {
82
- return JSON.parse(fs.readFileSync(filePath, 'utf8'));
83
- }
84
- catch {
85
- return null;
86
- }
87
- }
88
- function readTextIfExists(filePath) {
89
- if (!filePath || !fs.existsSync(filePath)) {
90
- return '';
91
- }
92
- return fs.readFileSync(filePath, 'utf8');
93
- }
94
- function getTaskFilePath(config, taskId) {
95
- return path.resolve(config.tasksDirAbs, `${taskId}.json`);
96
- }
97
- function readTaskJson(config, taskId) {
98
- const taskPath = getTaskFilePath(config, taskId);
99
- if (!fs.existsSync(taskPath)) {
27
+ return JSON.parse(c.readFileSync(e, 'utf8'));
28
+ } catch {
100
29
  return null;
101
30
  }
102
- return readJsonIfExists(taskPath);
103
31
  }
104
- function normalizeSnapshotValidations(snapshot) {
105
- const results = Array.isArray(snapshot?.validationResults) ? snapshot.validationResults : [];
106
- return results.map((item) => ({
107
- name: item?.name || '',
108
- status: item?.status || 'unknown',
109
- detail: item?.detail || null,
110
- }));
32
+ function s(e, t) {
33
+ return p.resolve(e.tasksDirAbs, `${t}.json`);
111
34
  }
112
- function toExecutionStatus(state) {
113
- if (state?.status === 'completed') {
114
- return 'completed';
115
- }
116
- if (state?.lastGateBlockedReason) {
117
- return 'blocked';
118
- }
119
- return state?.status || 'running';
120
- }
121
- function resolveReviewPath(config, taskJson) {
122
- const report = taskJson?.metadata?.outputs?.report;
123
- if (!report) {
124
- return null;
125
- }
126
- return path.resolve(config.projectRoot, report);
127
- }
128
- function resolveSnapshotPath(config, state, taskJson) {
129
- if (state?.currentSnapshot) {
130
- return path.resolve(config.projectRoot, state.currentSnapshot);
131
- }
132
- const snapshot = taskJson?.metadata?.outputs?.snapshot;
133
- if (!snapshot) {
134
- return null;
135
- }
136
- return path.resolve(config.projectRoot, snapshot);
137
- }
138
- function parseReviewConclusion(content) {
139
- const patterns = [
140
- { regex: /^\s*(?:结论 |Conclusion)\s*:\s*PASS\b/m, result: 'PASS' },
141
- { regex: /^\s*(?:结论 |Conclusion)\s*:\s*NEEDS_WORK\b/m, result: 'NEEDS_WORK' },
142
- { regex: /^\s*(?:结论 |Conclusion)\s*:\s*FAIL\b/m, result: 'FAIL' },
143
- { regex: /^##\s*结论\s*:\s*PASS\b/m, result: 'PASS' },
144
- { regex: /^##\s*结论\s*:\s*NEEDS_WORK\b/m, result: 'NEEDS_WORK' },
145
- { regex: /^##\s*结论\s*:\s*FAIL\b/m, result: 'FAIL' },
146
- { regex: /^#\s*PASS\b/m, result: 'PASS' },
147
- { regex: /^#\s*NEEDS_WORK\b/m, result: 'NEEDS_WORK' },
148
- { regex: /^#\s*FAIL\b/m, result: 'FAIL' },
149
- { regex: /\*\*结论\*\*\s*:\s*PASS\b/, result: 'PASS' },
150
- { regex: /\*\*结论\*\*\s*:\s*NEEDS_WORK\b/, result: 'NEEDS_WORK' },
151
- { regex: /\*\*结论\*\*\s*:\s*FAIL\b/, result: 'FAIL' },
152
- { regex: /\*\*PASS\*\*/, result: 'PASS' },
153
- { regex: /\*\*NEEDS_WORK\*\*/, result: 'NEEDS_WORK' },
154
- { regex: /\*\*FAIL\*\*/, result: 'FAIL' },
155
- ];
156
- for (const { regex, result } of patterns) {
157
- const match = content.match(regex);
158
- if (match) {
159
- return result;
160
- }
161
- }
162
- return null;
163
- }
164
- function buildExecutionDocument(params) {
165
- const { config, taskJson, state, taskId, spec } = params;
166
- const snapshotPath = resolveSnapshotPath(config, state, taskJson);
167
- const reportPath = resolveReviewPath(config, taskJson);
168
- const snapshot = readJsonIfExists(snapshotPath);
169
- const reportContent = readTextIfExists(reportPath);
170
- const report = reportContent ? { conclusion: parseReviewConclusion(reportContent), validationMap: {} } : { conclusion: null, validationMap: {} };
171
- const archivePath = path.resolve(config.archiveDirAbs, `${taskId}.json`);
172
- const archive = readJsonIfExists(archivePath);
173
- return {
174
- change: spec.change,
175
- taskId,
176
- status: toExecutionStatus(state),
177
- currentPhase: state?.currentPhase || null,
178
- phaseCompleted: state?.phaseCompleted || null,
179
- reviewConclusion: state?.reviewConclusion || report.conclusion || null,
180
- currentSnapshot: state?.currentSnapshot || (snapshotPath ? ensurePosix(path.relative(config.projectRoot, snapshotPath)) : null),
181
- updatedAt: state?.updatedAt || new Date().toISOString(),
182
- startedAt: state?.startedAt || null,
183
- archive: {
184
- path: fs.existsSync(archivePath) ? ensurePosix(path.relative(config.projectRoot, archivePath)) : null,
185
- eventCount: Array.isArray(archive?.events) ? archive.events.length : 0,
186
- lastEvent: Array.isArray(archive?.events) && archive.events.length > 0 ? archive.events[archive.events.length - 1] : null,
187
- },
188
- lastGate: {
189
- blockedAt: state?.lastGateBlockedAt || null,
190
- reason: state?.lastGateBlockedReason || null,
191
- phase: state?.lastGateBlockedPhase || null,
192
- missingValidations: Array.isArray(state?.lastMissingValidations) ? state.lastMissingValidations : [],
193
- },
194
- taskPhases: {
195
- planning: taskJson?.status || 'pending',
196
- implementation: taskJson?.status || 'pending',
197
- review: taskJson?.status || 'pending',
198
- },
199
- artifacts: {
200
- task: ensurePosix(path.relative(config.projectRoot, getTaskFilePath(config, taskId))),
201
- proposal: spec.proposal || null,
202
- design: spec.design || null,
203
- tasks: spec.tasks || null,
204
- snapshot: snapshotPath ? ensurePosix(path.relative(config.projectRoot, snapshotPath)) : null,
205
- review: reportPath ? ensurePosix(path.relative(config.projectRoot, reportPath)) : null,
206
- },
207
- planning: {
208
- embedded: true,
209
- summary: taskJson?.implementation?.notes || '',
210
- },
211
- validations: {
212
- implementation: normalizeSnapshotValidations(snapshot),
213
- review: Object.entries(report.validationMap || {}).map(([name, status]) => ({ name, status })),
214
- },
215
- mergeStrategy: taskJson?.metadata?.mergeStrategy || { type: 'squash', deleteBranch: true, deleteWorktree: true },
35
+ function a(e = {}) {
36
+ var t;
37
+ let l, o, i = (0, d.loadConfig)({
38
+ cwd: e.cwd
39
+ }), u = (0, g.loadState)(i), S = e.taskId || u.currentTask;
40
+ if (!S) return {
41
+ skipped: !0,
42
+ reason: 'missing-task-id'
216
43
  };
217
- }
218
- function getMetadataSpec(taskJson) {
219
- if (!taskJson?.metadata?.change) {
220
- return null;
221
- }
222
- return {
223
- change: taskJson.metadata.change,
224
- proposal: taskJson.docs_to_read?.[0] || null,
225
- design: taskJson.docs_to_read?.[1] || null,
226
- tasks: taskJson.docs_to_read?.[2] || null,
227
- manifest: taskJson.metadata.manifest || null,
228
- execution: taskJson.metadata.execution || null,
229
- version: 'v1',
44
+ let f = (l = s(i, S), c.existsSync(l) ? r(l) : null);
45
+ if (!f) return {
46
+ skipped: !0,
47
+ reason: 'missing-task-file'
230
48
  };
231
- }
232
- /**
233
- * Sync task to Spec
234
- */
235
- function syncTaskToSpec(options = {}) {
236
- const config = (0, config_1.loadConfig)({ cwd: options.cwd });
237
- const state = (0, state_1.loadState)(config);
238
- const taskId = options.taskId || state.currentTask;
239
- if (!taskId) {
240
- return { skipped: true, reason: 'missing-task-id' };
241
- }
242
- const taskJson = readTaskJson(config, taskId);
243
- if (!taskJson) {
244
- return { skipped: true, reason: 'missing-task-file' };
245
- }
246
- const spec = getMetadataSpec(taskJson);
247
- if (!spec?.change) {
248
- return { skipped: true, reason: 'missing-spec-metadata' };
249
- }
250
- const executionTarget = spec.execution || ensurePosix(`spec/changes/${spec.change}/execution.json`);
251
- const executionPath = path.resolve(config.projectRoot, executionTarget);
252
- // Security: Validate execution path is within project root
253
- if (!isPathWithinProject(executionPath, config.projectRoot)) {
254
- console.error(`[SPEC-SYNC] Execution path escapes project root: ${executionTarget}`);
255
- return { skipped: true, reason: 'invalid-execution-path' };
256
- }
257
- const executionDoc = buildExecutionDocument({ config, taskJson, state, taskId, spec });
258
- fs.mkdirSync(path.dirname(executionPath), { recursive: true });
259
- fs.writeFileSync(executionPath, JSON.stringify(executionDoc, null, 2), 'utf8');
260
- return {
261
- skipped: false,
262
- taskId,
263
- change: spec.change,
264
- executionPath: ensurePosix(path.relative(config.projectRoot, executionPath)),
49
+ let m = f?.metadata?.change ? {
50
+ change: f.metadata.change,
51
+ proposal: f.docs_to_read?.[0] || null,
52
+ design: f.docs_to_read?.[1] || null,
53
+ tasks: f.docs_to_read?.[2] || null,
54
+ manifest: f.metadata.manifest || null,
55
+ execution: f.metadata.execution || null,
56
+ version: 'v1'
57
+ } : null;
58
+ if (!m?.change) return {
59
+ skipped: !0,
60
+ reason: 'missing-spec-metadata'
265
61
  };
266
- }
267
- /**
268
- * Main entry point
269
- */
270
- function main() {
271
- const args = parseArgs(process.argv);
272
- const result = syncTaskToSpec({
273
- cwd: args.cwd,
274
- taskId: args['task-id'],
62
+ let v = m.execution || n(`spec/changes/${m.change}/execution.json`), h = p.resolve(i.projectRoot, v);
63
+ if (t = i.projectRoot, (o = p.relative(t, h)).startsWith('..') || p.isAbsolute(o)) return console.error(`[SPEC-SYNC] Execution path escapes project root: ${v}`), {
64
+ skipped: !0,
65
+ reason: 'invalid-execution-path'
66
+ };
67
+ let A = function(e) {
68
+ let t, { config: a, taskJson: l, state: o, taskId: i, spec: u } = e, d = function(e, t, n) {
69
+ if (t?.currentSnapshot) return p.resolve(e.projectRoot, t.currentSnapshot);
70
+ let r = n?.metadata?.outputs?.snapshot;
71
+ return r ? p.resolve(e.projectRoot, r) : null;
72
+ }(a, o, l), g = (t = l?.metadata?.outputs?.report) ? p.resolve(a.projectRoot, t) : null, S = r(d), f = g && c.existsSync(g) ? c.readFileSync(g, 'utf8') : '', m = f ? {
73
+ conclusion: function(e) {
74
+ for (let { regex: t, result: n } of [
75
+ {
76
+ regex: /^\s*(?:结论 |Conclusion)\s*:\s*PASS\b/m,
77
+ result: 'PASS'
78
+ },
79
+ {
80
+ regex: /^\s*(?:结论 |Conclusion)\s*:\s*NEEDS_WORK\b/m,
81
+ result: 'NEEDS_WORK'
82
+ },
83
+ {
84
+ regex: /^\s*(?:结论 |Conclusion)\s*:\s*FAIL\b/m,
85
+ result: 'FAIL'
86
+ },
87
+ {
88
+ regex: /^##\s*结论\s*:\s*PASS\b/m,
89
+ result: 'PASS'
90
+ },
91
+ {
92
+ regex: /^##\s*结论\s*:\s*NEEDS_WORK\b/m,
93
+ result: 'NEEDS_WORK'
94
+ },
95
+ {
96
+ regex: /^##\s*结论\s*:\s*FAIL\b/m,
97
+ result: 'FAIL'
98
+ },
99
+ {
100
+ regex: /^#\s*PASS\b/m,
101
+ result: 'PASS'
102
+ },
103
+ {
104
+ regex: /^#\s*NEEDS_WORK\b/m,
105
+ result: 'NEEDS_WORK'
106
+ },
107
+ {
108
+ regex: /^#\s*FAIL\b/m,
109
+ result: 'FAIL'
110
+ },
111
+ {
112
+ regex: /\*\*结论\*\*\s*:\s*PASS\b/,
113
+ result: 'PASS'
114
+ },
115
+ {
116
+ regex: /\*\*结论\*\*\s*:\s*NEEDS_WORK\b/,
117
+ result: 'NEEDS_WORK'
118
+ },
119
+ {
120
+ regex: /\*\*结论\*\*\s*:\s*FAIL\b/,
121
+ result: 'FAIL'
122
+ },
123
+ {
124
+ regex: /\*\*PASS\*\*/,
125
+ result: 'PASS'
126
+ },
127
+ {
128
+ regex: /\*\*NEEDS_WORK\*\*/,
129
+ result: 'NEEDS_WORK'
130
+ },
131
+ {
132
+ regex: /\*\*FAIL\*\*/,
133
+ result: 'FAIL'
134
+ }
135
+ ])if (e.match(t)) return n;
136
+ return null;
137
+ }(f),
138
+ validationMap: {}
139
+ } : {
140
+ conclusion: null,
141
+ validationMap: {}
142
+ }, v = p.resolve(a.archiveDirAbs, `${i}.json`), h = r(v);
143
+ return {
144
+ change: u.change,
145
+ taskId: i,
146
+ status: o?.status === 'completed' ? 'completed' : o?.lastGateBlockedReason ? 'blocked' : o?.status || 'running',
147
+ currentPhase: o?.currentPhase || null,
148
+ phaseCompleted: o?.phaseCompleted || null,
149
+ reviewConclusion: o?.reviewConclusion || m.conclusion || null,
150
+ currentSnapshot: o?.currentSnapshot || (d ? n(p.relative(a.projectRoot, d)) : null),
151
+ updatedAt: o?.updatedAt || new Date().toISOString(),
152
+ startedAt: o?.startedAt || null,
153
+ archive: {
154
+ path: c.existsSync(v) ? n(p.relative(a.projectRoot, v)) : null,
155
+ eventCount: Array.isArray(h?.events) ? h.events.length : 0,
156
+ lastEvent: Array.isArray(h?.events) && h.events.length > 0 ? h.events[h.events.length - 1] : null
157
+ },
158
+ lastGate: {
159
+ blockedAt: o?.lastGateBlockedAt || null,
160
+ reason: o?.lastGateBlockedReason || null,
161
+ phase: o?.lastGateBlockedPhase || null,
162
+ missingValidations: Array.isArray(o?.lastMissingValidations) ? o.lastMissingValidations : []
163
+ },
164
+ taskPhases: {
165
+ planning: l?.status || 'pending',
166
+ implementation: l?.status || 'pending',
167
+ review: l?.status || 'pending'
168
+ },
169
+ artifacts: {
170
+ task: n(p.relative(a.projectRoot, s(a, i))),
171
+ proposal: u.proposal || null,
172
+ design: u.design || null,
173
+ tasks: u.tasks || null,
174
+ snapshot: d ? n(p.relative(a.projectRoot, d)) : null,
175
+ review: g ? n(p.relative(a.projectRoot, g)) : null
176
+ },
177
+ planning: {
178
+ embedded: !0,
179
+ summary: l?.implementation?.notes || ''
180
+ },
181
+ validations: {
182
+ implementation: (Array.isArray(S?.validationResults) ? S.validationResults : []).map((e)=>({
183
+ name: e?.name || '',
184
+ status: e?.status || 'unknown',
185
+ detail: e?.detail || null
186
+ })),
187
+ review: Object.entries(m.validationMap || {}).map(([e, t])=>({
188
+ name: e,
189
+ status: t
190
+ }))
191
+ },
192
+ mergeStrategy: l?.metadata?.mergeStrategy || {
193
+ type: 'squash',
194
+ deleteBranch: !0,
195
+ deleteWorktree: !0
196
+ }
197
+ };
198
+ }({
199
+ config: i,
200
+ taskJson: f,
201
+ state: u,
202
+ taskId: S,
203
+ spec: m
275
204
  });
276
- if (result.skipped) {
277
- console.log(`[SPEC-SYNC] skipped: ${result.reason}`);
278
- process.exit(0);
279
- }
280
- console.log(`[SPEC-SYNC] updated: ${result.executionPath}`);
281
- process.exit(0);
205
+ return c.mkdirSync(p.dirname(h), {
206
+ recursive: !0
207
+ }), c.writeFileSync(h, JSON.stringify(A, null, 2), 'utf8'), {
208
+ skipped: !1,
209
+ taskId: S,
210
+ change: m.change,
211
+ executionPath: n(p.relative(i.projectRoot, h))
212
+ };
282
213
  }
283
- if (require.main === module) {
284
- main();
214
+ function l() {
215
+ let e = function(e) {
216
+ let t = {};
217
+ for(let n = 2; n < e.length; n += 1){
218
+ let r = e[n] || '';
219
+ if (!r.startsWith('--')) continue;
220
+ let s = r.slice(2), a = e[n + 1] || '';
221
+ if (!a || a.startsWith('--')) {
222
+ t[s] = !0;
223
+ continue;
224
+ }
225
+ t[s] = a, n += 1;
226
+ }
227
+ return t;
228
+ }(process.argv), t = a({
229
+ cwd: e.cwd,
230
+ taskId: e['task-id']
231
+ });
232
+ t.skipped && (console.log(`[SPEC-SYNC] skipped: ${t.reason}`), process.exit(0)), console.log(`[SPEC-SYNC] updated: ${t.executionPath}`), process.exit(0);
285
233
  }
286
- exports.default = {
287
- syncTaskToSpec,
234
+ "use strict";
235
+ Object.defineProperty(exports, "__esModule", {
236
+ value: !0
237
+ });
238
+ var o = exports, i = {
239
+ get default () {
240
+ return S;
241
+ },
242
+ get main () {
243
+ return l;
244
+ },
245
+ get syncTaskToSpec () {
246
+ return a;
247
+ }
248
+ };
249
+ for(var u in i)Object.defineProperty(o, u, {
250
+ enumerable: !0,
251
+ get: Object.getOwnPropertyDescriptor(i, u).get
252
+ });
253
+ let c = /*#__PURE__*/ t(require("fs")), p = /*#__PURE__*/ t(require("path")), d = require("../lib/config"), g = require("../lib/state");
254
+ require.main === module && l();
255
+ let S = {
256
+ syncTaskToSpec: a
288
257
  };
@@ -1,9 +1,4 @@
1
1
  "use strict";
2
- /**
3
- * types/ai-context.ts
4
- * AI 项目上下文协议定义
5
- *
6
- * AI 在调用 extract/design/tasks 命令前,先分析宿主项目并生成此结构,
7
- * 通过 --context-file 参数传入。CLI 命令会将其注入到生成的文档中。
8
- */
9
- Object.defineProperty(exports, "__esModule", { value: true });
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: !0
4
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bicorne/task-flow",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Harness Engineering tool for requirements analysis and task decomposition. AI-driven PRD generation, technical specs, and multi-phase task planning with zero-conflict parallel development via Git worktree.",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
@@ -41,6 +41,8 @@
41
41
  "devDependencies": {
42
42
  "@changesets/cli": "^2.27.0",
43
43
  "@eslint/js": "^9.0.0",
44
+ "@swc/cli": "^0.8.1",
45
+ "@swc/core": "^1.15.24",
44
46
  "@types/node": "^24.12.0",
45
47
  "@typescript-eslint/eslint-plugin": "8.58.0",
46
48
  "@typescript-eslint/parser": "8.58.0",
@@ -55,12 +57,12 @@
55
57
  "scripts": {
56
58
  "test": "node --test tests/**/*.test.js",
57
59
  "lint": "eslint src/",
58
- "build": "tsc --project tsconfig.build.json",
59
- "build:dev": "tsc",
60
- "build:watch": "tsc --watch",
60
+ "build:dev": "swc src -d dist --strip-leading-paths --source-maps && tsc --project tsconfig.declarations.json",
61
+ "build:watch": "swc src -d dist --strip-leading-paths --watch",
62
+ "build:prod": "swc src -d dist --strip-leading-paths --config-file .swcrc.prod && tsc --project tsconfig.declarations.json",
61
63
  "typecheck": "tsc --noEmit",
62
64
  "changeset": "changeset",
63
- "version": "changeset version",
64
- "release": "pnpm build && changeset publish"
65
+ "consume": "changeset version",
66
+ "release": "pnpm typecheck && pnpm build:prod && changeset publish"
65
67
  }
66
68
  }
@@ -74,10 +74,7 @@ task-flow worktree --change my-feature --yes
74
74
  cd .worktrees/harness-feat-my-feature
75
75
  # 编码...
76
76
 
77
- # 步骤 10: 验证
78
- pnpm build && pnpm test && pnpm lint
79
-
80
- # 步骤 11: 合并
77
+ # 步骤 10: 完成后合并
81
78
  cd ../.. # 回到主仓库
82
79
  task-flow merge my-feature
83
80
  ```
@@ -333,19 +330,16 @@ cd .worktrees/harness-feat-add-auth
333
330
  pnpm install
334
331
  # ... 编码 ...
335
332
 
336
- # 11. 验证
337
- pnpm build && pnpm test && pnpm lint
338
-
339
- # 12. 提交
333
+ # 11. 完成后提交
340
334
  git add .
341
335
  git commit -m "feat: add user authentication"
342
336
 
343
- # 13. 回到主仓库并合并
337
+ # 12. 回到主仓库并合并
344
338
  cd ../..
345
339
  task-flow merge add-auth --dry-run # 先检查
346
340
  task-flow merge add-auth # 实际合并
347
341
 
348
- # 14. 查看状态
342
+ # 13. 查看状态
349
343
  task-flow status
350
344
  ```
351
345