@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,407 +1,346 @@
1
- "use strict";
2
- /**
3
- * hooks/phase-gate-validator.ts
4
- * Validate phase transition gates
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.normalizePath = normalizePath;
41
- exports.normalizeValidationName = normalizeValidationName;
42
- exports.getValidationAliases = getValidationAliases;
43
- exports.isPassedStatus = isPassedStatus;
44
- exports.parseReviewConclusion = parseReviewConclusion;
45
- exports.parseReviewValidationMap = parseReviewValidationMap;
46
- exports.parseReviewReport = parseReviewReport;
47
- exports.deriveTransitionFromFilePath = deriveTransitionFromFilePath;
48
- exports.getTaskFilePath = getTaskFilePath;
49
- exports.readTaskJson = readTaskJson;
50
- exports.getValidationItems = getValidationItems;
51
- exports.getPlanningSummary = getPlanningSummary;
52
- exports.getPlanningList = getPlanningList;
53
- exports.getSnapshotValidationMap = getSnapshotValidationMap;
54
- exports.hasValidationPassed = hasValidationPassed;
55
- exports.assessTransitionGate = assessTransitionGate;
56
- const fs = __importStar(require("fs"));
57
- const path = __importStar(require("path"));
58
- const config_1 = require("../lib/config");
59
- const state_1 = require("../lib/state");
60
- const constants_1 = require("../lib/constants");
61
- function normalizePath(inputPath, projectRoot) {
62
- if (!inputPath || typeof inputPath !== 'string') {
63
- return '';
64
- }
65
- const absolutePath = path.isAbsolute(inputPath) ? inputPath : path.resolve(projectRoot, inputPath);
66
- return path.relative(projectRoot, absolutePath).replace(/\\/g, '/');
1
+ let e, t, r, s, n;
2
+ function i(e) {
3
+ return "function" != typeof WeakMap ? null : (i = function(e) {
4
+ return new WeakMap();
5
+ })(e);
67
6
  }
68
- function normalizeValidationName(name) {
69
- return String(name || '')
70
- .trim()
71
- .toLowerCase()
72
- .replace(/_/g, '-')
73
- .replace(/\s+/g, '-');
7
+ function o(e, t) {
8
+ var r, s, n;
9
+ if (!t && e && e.__esModule) return e;
10
+ if (null === e || "object" != typeof e && "function" != typeof e) return {
11
+ default: e
12
+ };
13
+ if ((r = i(t)) && r.has(e)) return r.get(e);
14
+ for(var o in s = {
15
+ __proto__: null
16
+ }, n = Object.defineProperty && Object.getOwnPropertyDescriptor, e)if ("default" !== o && Object.prototype.hasOwnProperty.call(e, o)) {
17
+ var a = n ? Object.getOwnPropertyDescriptor(e, o) : null;
18
+ a && (a.get || a.set) ? Object.defineProperty(s, o, a) : s[o] = e[o];
19
+ }
20
+ return s.default = e, r && r.set(e, s), s;
74
21
  }
75
- function getValidationAliases(validationName) {
76
- const normalized = normalizeValidationName(validationName);
77
- return constants_1.VALIDATION_ALIASES[normalized] || [normalized];
22
+ function a(e, t) {
23
+ if (!e || 'string' != typeof e) return '';
24
+ let r = P.isAbsolute(e) ? e : P.resolve(t, e);
25
+ return P.relative(t, r).replace(/\\/g, '/');
78
26
  }
79
- function isPassedStatus(status) {
80
- if (!status) {
81
- return false;
82
- }
83
- const normalized = status.trim().toLowerCase();
84
- return constants_1.VALIDATED_STATUSES.includes(normalized);
27
+ function l(e) {
28
+ return String(e || '').trim().toLowerCase().replace(/_/g, '-').replace(/\s+/g, '-');
85
29
  }
86
- function parseReviewConclusion(content) {
87
- const patterns = [
88
- { regex: /^\s*(?:结论 |Conclusion)\s*:\s*PASS\b/m, result: constants_1.REVIEW_CONCLUSION.PASS },
89
- { regex: /^\s*(?:结论 |Conclusion)\s*:\s*NEEDS_WORK\b/m, result: constants_1.REVIEW_CONCLUSION.NEEDS_WORK },
90
- { regex: /^\s*(?:结论 |Conclusion)\s*:\s*FAIL\b/m, result: constants_1.REVIEW_CONCLUSION.FAIL },
91
- { regex: /^##\s*结论\s*:\s*PASS\b/m, result: constants_1.REVIEW_CONCLUSION.PASS },
92
- { regex: /^##\s*结论\s*:\s*NEEDS_WORK\b/m, result: constants_1.REVIEW_CONCLUSION.NEEDS_WORK },
93
- { regex: /^##\s*结论\s*:\s*FAIL\b/m, result: constants_1.REVIEW_CONCLUSION.FAIL },
94
- { regex: /^#\s*PASS\b/m, result: constants_1.REVIEW_CONCLUSION.PASS },
95
- { regex: /^#\s*NEEDS_WORK\b/m, result: constants_1.REVIEW_CONCLUSION.NEEDS_WORK },
96
- { regex: /^#\s*FAIL\b/m, result: constants_1.REVIEW_CONCLUSION.FAIL },
97
- { regex: /\*\*结论\*\*\s*:\s*PASS\b/, result: constants_1.REVIEW_CONCLUSION.PASS },
98
- { regex: /\*\*结论\*\*\s*:\s*NEEDS_WORK\b/, result: constants_1.REVIEW_CONCLUSION.NEEDS_WORK },
99
- { regex: /\*\*结论\*\*\s*:\s*FAIL\b/, result: constants_1.REVIEW_CONCLUSION.FAIL },
100
- { regex: /\*\*PASS\*\*/, result: constants_1.REVIEW_CONCLUSION.PASS },
101
- { regex: /\*\*NEEDS_WORK\*\*/, result: constants_1.REVIEW_CONCLUSION.NEEDS_WORK },
102
- { regex: /\*\*FAIL\*\*/, result: constants_1.REVIEW_CONCLUSION.FAIL },
103
- // Additional pattern for "结论 : NEEDS_WORK" format (with space before colon)
104
- { regex: /结论\s*:\s*NEEDS_WORK\b/, result: constants_1.REVIEW_CONCLUSION.NEEDS_WORK },
105
- { regex: /结论\s*:\s*PASS\b/, result: constants_1.REVIEW_CONCLUSION.PASS },
106
- { regex: /结论\s*:\s*FAIL\b/, result: constants_1.REVIEW_CONCLUSION.FAIL },
30
+ function u(e) {
31
+ let t = l(e);
32
+ return b.VALIDATION_ALIASES[t] || [
33
+ t
107
34
  ];
108
- for (const { regex, result } of patterns) {
109
- if (regex.test(content)) {
110
- return result;
35
+ }
36
+ function p(e) {
37
+ if (!e) return !1;
38
+ let t = e.trim().toLowerCase();
39
+ return b.VALIDATED_STATUSES.includes(t);
40
+ }
41
+ function c(e) {
42
+ for (let { regex: t, result: r } of [
43
+ {
44
+ regex: /^\s*(?:结论 |Conclusion)\s*:\s*PASS\b/m,
45
+ result: b.REVIEW_CONCLUSION.PASS
46
+ },
47
+ {
48
+ regex: /^\s*(?:结论 |Conclusion)\s*:\s*NEEDS_WORK\b/m,
49
+ result: b.REVIEW_CONCLUSION.NEEDS_WORK
50
+ },
51
+ {
52
+ regex: /^\s*(?:结论 |Conclusion)\s*:\s*FAIL\b/m,
53
+ result: b.REVIEW_CONCLUSION.FAIL
54
+ },
55
+ {
56
+ regex: /^##\s*结论\s*:\s*PASS\b/m,
57
+ result: b.REVIEW_CONCLUSION.PASS
58
+ },
59
+ {
60
+ regex: /^##\s*结论\s*:\s*NEEDS_WORK\b/m,
61
+ result: b.REVIEW_CONCLUSION.NEEDS_WORK
62
+ },
63
+ {
64
+ regex: /^##\s*结论\s*:\s*FAIL\b/m,
65
+ result: b.REVIEW_CONCLUSION.FAIL
66
+ },
67
+ {
68
+ regex: /^#\s*PASS\b/m,
69
+ result: b.REVIEW_CONCLUSION.PASS
70
+ },
71
+ {
72
+ regex: /^#\s*NEEDS_WORK\b/m,
73
+ result: b.REVIEW_CONCLUSION.NEEDS_WORK
74
+ },
75
+ {
76
+ regex: /^#\s*FAIL\b/m,
77
+ result: b.REVIEW_CONCLUSION.FAIL
78
+ },
79
+ {
80
+ regex: /\*\*结论\*\*\s*:\s*PASS\b/,
81
+ result: b.REVIEW_CONCLUSION.PASS
82
+ },
83
+ {
84
+ regex: /\*\*结论\*\*\s*:\s*NEEDS_WORK\b/,
85
+ result: b.REVIEW_CONCLUSION.NEEDS_WORK
86
+ },
87
+ {
88
+ regex: /\*\*结论\*\*\s*:\s*FAIL\b/,
89
+ result: b.REVIEW_CONCLUSION.FAIL
90
+ },
91
+ {
92
+ regex: /\*\*PASS\*\*/,
93
+ result: b.REVIEW_CONCLUSION.PASS
94
+ },
95
+ {
96
+ regex: /\*\*NEEDS_WORK\*\*/,
97
+ result: b.REVIEW_CONCLUSION.NEEDS_WORK
98
+ },
99
+ {
100
+ regex: /\*\*FAIL\*\*/,
101
+ result: b.REVIEW_CONCLUSION.FAIL
102
+ },
103
+ {
104
+ regex: /结论\s*:\s*NEEDS_WORK\b/,
105
+ result: b.REVIEW_CONCLUSION.NEEDS_WORK
106
+ },
107
+ {
108
+ regex: /结论\s*:\s*PASS\b/,
109
+ result: b.REVIEW_CONCLUSION.PASS
110
+ },
111
+ {
112
+ regex: /结论\s*:\s*FAIL\b/,
113
+ result: b.REVIEW_CONCLUSION.FAIL
111
114
  }
112
- }
115
+ ])if (t.test(e)) return r;
113
116
  return null;
114
117
  }
115
- function parseReviewValidationMap(content) {
116
- const validationMap = {};
117
- const regex = /^\s*[-*]?\s*([a-z][a-z0-9_-]*)\s*:\s*([A-Za-z0-9_-]+)\s*$/gm;
118
- let match = regex.exec(content);
119
- while (match) {
120
- const key = match[1];
121
- const value = match[2];
122
- if (key && value) {
123
- validationMap[normalizeValidationName(key)] = value;
124
- }
125
- match = regex.exec(content);
118
+ function d(e) {
119
+ let t = {}, r = /^\s*[-*]?\s*([a-z][a-z0-9_-]*)\s*:\s*([A-Za-z0-9_-]+)\s*$/gm, s = r.exec(e);
120
+ for(; s;){
121
+ let n = s[1], i = s[2];
122
+ n && i && (t[l(n)] = i), s = r.exec(e);
126
123
  }
127
- return validationMap;
124
+ return t;
128
125
  }
129
- function parseReviewReport(content) {
130
- const conclusion = parseReviewConclusion(content);
131
- const validationMap = parseReviewValidationMap(content);
132
- if (conclusion && !validationMap['review-conclusion']) {
133
- validationMap['review-conclusion'] = conclusion;
134
- }
135
- return {
136
- conclusion,
137
- validationMap,
126
+ function g(e) {
127
+ let t = c(e), r = d(e);
128
+ return t && !r['review-conclusion'] && (r['review-conclusion'] = t), {
129
+ conclusion: t,
130
+ validationMap: r
138
131
  };
139
132
  }
140
- function deriveTransitionFromFilePath(filePath, config) {
141
- const relativePath = normalizePath(filePath, config.projectRoot);
142
- // Security: Prevent path traversal by ensuring path doesn't escape expected directories
143
- if (relativePath.includes('..') || (relativePath.startsWith('/') && !relativePath.startsWith(config.projectRoot))) {
144
- return null;
145
- }
146
- // Check if path is in harness directory or matches expected patterns
147
- const isInHarness = relativePath.includes('.harness/');
148
- const matchesTaskPattern = new RegExp(`^${normalizePath(config.tasksDirAbs, config.projectRoot)}/.+\\.json$`).test(relativePath);
149
- const matchesSnapshotPattern = new RegExp(`^${normalizePath(config.snapshotsDirAbs, config.projectRoot)}/.+\\.json$`).test(relativePath);
150
- const matchesReportPattern = new RegExp(`^${normalizePath(config.reportsDirAbs, config.projectRoot)}/.+\\.md$`).test(relativePath);
151
- if (!isInHarness && !matchesTaskPattern && !matchesSnapshotPattern && !matchesReportPattern) {
152
- return null;
153
- }
154
- const tasksPattern = new RegExp(`^${normalizePath(config.tasksDirAbs, config.projectRoot)}/.+\\.json$`);
155
- const snapshotPattern = new RegExp(`^${normalizePath(config.snapshotsDirAbs, config.projectRoot)}/.+\\.json$`);
156
- const reportPattern = new RegExp(`^${normalizePath(config.reportsDirAbs, config.projectRoot)}/.+\\.md$`);
157
- if (tasksPattern.test(relativePath)) {
158
- return { phaseCompleted: 'planning', nextPhase: 'implementation', relativePath };
159
- }
160
- if (snapshotPattern.test(relativePath) && /-impl\.json$/.test(relativePath)) {
161
- return { phaseCompleted: 'implementation', nextPhase: 'review', relativePath };
162
- }
163
- if (reportPattern.test(relativePath) && /-review\.md$/.test(relativePath)) {
164
- return { phaseCompleted: 'review', nextPhase: 'merge', relativePath };
165
- }
166
- return null;
133
+ function m(e, t) {
134
+ let r = a(e, t.projectRoot);
135
+ if (r.includes('..') || r.startsWith('/') && !r.startsWith(t.projectRoot)) return null;
136
+ let s = r.includes('.harness/'), n = RegExp(`^${a(t.tasksDirAbs, t.projectRoot)}/.+\\.json$`).test(r), i = RegExp(`^${a(t.snapshotsDirAbs, t.projectRoot)}/.+\\.json$`).test(r), o = RegExp(`^${a(t.reportsDirAbs, t.projectRoot)}/.+\\.md$`).test(r);
137
+ if (!s && !n && !i && !o) return null;
138
+ let l = RegExp(`^${a(t.tasksDirAbs, t.projectRoot)}/.+\\.json$`), u = RegExp(`^${a(t.snapshotsDirAbs, t.projectRoot)}/.+\\.json$`), p = RegExp(`^${a(t.reportsDirAbs, t.projectRoot)}/.+\\.md$`);
139
+ return l.test(r) ? {
140
+ phaseCompleted: 'planning',
141
+ nextPhase: 'implementation',
142
+ relativePath: r
143
+ } : u.test(r) && /-impl\.json$/.test(r) ? {
144
+ phaseCompleted: 'implementation',
145
+ nextPhase: 'review',
146
+ relativePath: r
147
+ } : p.test(r) && /-review\.md$/.test(r) ? {
148
+ phaseCompleted: 'review',
149
+ nextPhase: 'merge',
150
+ relativePath: r
151
+ } : null;
167
152
  }
168
- function getTaskFilePath(config, taskId) {
169
- return path.resolve(config.tasksDirAbs, `${taskId}.json`);
153
+ function S(e, t) {
154
+ return P.resolve(e.tasksDirAbs, `${t}.json`);
170
155
  }
171
- function readTaskJson(config, taskId) {
172
- const taskPath = getTaskFilePath(config, taskId);
173
- if (!fs.existsSync(taskPath)) {
174
- return null;
175
- }
156
+ function f(e, t) {
157
+ let r = S(e, t);
158
+ if (!x.existsSync(r)) return null;
176
159
  try {
177
- return JSON.parse(fs.readFileSync(taskPath, 'utf8'));
178
- }
179
- catch {
160
+ return JSON.parse(x.readFileSync(r, 'utf8'));
161
+ } catch {
180
162
  return null;
181
163
  }
182
164
  }
183
- function getValidationItems(taskJson, phaseName) {
184
- if (!taskJson) {
185
- return [];
186
- }
187
- if (phaseName === 'implementation') {
188
- return Array.isArray(taskJson.validation?.commands) ? taskJson.validation.commands : [];
189
- }
190
- if (phaseName === 'review') {
191
- return Array.isArray(taskJson.validation?.manual_checks) ? taskJson.validation.manual_checks : [];
192
- }
193
- return [];
165
+ function E(e, t) {
166
+ return e ? 'implementation' === t ? Array.isArray(e.validation?.commands) ? e.validation.commands : [] : 'review' === t && Array.isArray(e.validation?.manual_checks) ? e.validation.manual_checks : [] : [];
194
167
  }
195
- function getPlanningSummary(taskJson) {
196
- return taskJson?.implementation?.notes || '';
168
+ function O(e) {
169
+ return e?.implementation?.notes || '';
197
170
  }
198
- function getPlanningList(taskJson, key) {
199
- if (!taskJson) {
200
- return [];
201
- }
202
- if (key === 'implementationSteps') {
203
- const steps = Array.isArray(taskJson.implementation?.steps) ? taskJson.implementation.steps : [];
204
- return steps.map((item) => (typeof item === 'string' ? item : item.step || ''));
205
- }
206
- if (key === 'testStrategy') {
207
- return Array.isArray(taskJson.validation?.commands) ? taskJson.validation.commands : [];
208
- }
209
- return [];
171
+ function h(e, t) {
172
+ return e ? 'implementationSteps' === t ? (Array.isArray(e.implementation?.steps) ? e.implementation.steps : []).map((e)=>'string' == typeof e ? e : e.step || '') : 'testStrategy' === t && Array.isArray(e.validation?.commands) ? e.validation.commands : [] : [];
210
173
  }
211
- function getSnapshotValidationMap(snapshotPath) {
212
- if (!snapshotPath || !fs.existsSync(snapshotPath)) {
213
- return {};
214
- }
174
+ function A(e) {
175
+ if (!e || !x.existsSync(e)) return {};
215
176
  try {
216
- const snapshot = JSON.parse(fs.readFileSync(snapshotPath, 'utf8'));
217
- const results = Array.isArray(snapshot.validationResults) ? snapshot.validationResults : [];
218
- const map = {};
219
- for (const result of results) {
220
- if (!result?.name) {
221
- continue;
222
- }
223
- const name = normalizeValidationName(result.name);
224
- map[name] = isPassedStatus(result.status);
225
- }
226
- return map;
227
- }
228
- catch {
177
+ let t = JSON.parse(x.readFileSync(e, 'utf8')), r = Array.isArray(t.validationResults) ? t.validationResults : [], s = {};
178
+ for (let e of r)e?.name && (s[l(e.name)] = p(e.status));
179
+ return s;
180
+ } catch {
229
181
  return {};
230
182
  }
231
183
  }
232
- function hasValidationPassed(validationName, snapshotValidationMap) {
233
- const candidates = getValidationAliases(validationName).map(normalizeValidationName);
234
- return candidates.some((item) => snapshotValidationMap[item] === true || isPassedStatus(snapshotValidationMap[item]));
184
+ function C(e, t) {
185
+ return u(e).map(l).some((e)=>!0 === t[e] || p(t[e]));
235
186
  }
236
- /**
237
- * Validate planning phase
238
- */
239
- function validatePlanningPhase(taskJson, validations, config) {
240
- const missingValidations = [];
241
- const details = [];
242
- const taskOutput = taskJson.metadata?.outputs?.task;
243
- const taskOutputExists = taskOutput && fs.existsSync(path.resolve(config.projectRoot, taskOutput));
244
- if (!taskOutputExists) {
245
- missingValidations.push('planning-task-exists');
246
- }
247
- if (validations.includes('planning-ready')) {
248
- const summary = getPlanningSummary(taskJson);
249
- const implementationSteps = getPlanningList(taskJson, 'implementationSteps');
250
- const testStrategy = getPlanningList(taskJson, 'testStrategy');
251
- if (!summary) {
252
- missingValidations.push('planning.summary');
253
- }
254
- if (implementationSteps.length === 0) {
255
- missingValidations.push('planning.implementationSteps');
256
- }
257
- if (testStrategy.length === 0) {
258
- missingValidations.push('planning.testStrategy');
259
- }
260
- }
261
- return { missingValidations, details };
262
- }
263
- /**
264
- * Validate implementation phase
265
- */
266
- function validateImplementationPhase(validations, relativePath, config) {
267
- const missingValidations = [];
268
- const details = [];
269
- const snapshotPath = path.resolve(config.projectRoot, relativePath);
270
- const snapshotValidationMap = getSnapshotValidationMap(snapshotPath);
271
- for (const validation of validations) {
272
- if (!hasValidationPassed(validation, snapshotValidationMap)) {
273
- missingValidations.push(validation);
274
- }
275
- }
276
- details.push(`snapshot:${relativePath}`);
277
- return { missingValidations, details };
278
- }
279
- /**
280
- * Validate review phase
281
- */
282
- function validateReviewPhase(validations, relativePath, config, stateReviewConclusion) {
283
- const missingValidations = [];
284
- const details = [];
285
- let reviewConclusion = stateReviewConclusion;
286
- const reportPath = path.resolve(config.projectRoot, relativePath);
287
- if (!fs.existsSync(reportPath)) {
288
- missingValidations.push('review-report-exists');
289
- return { missingValidations, details, reviewConclusion };
290
- }
291
- const reportContent = fs.readFileSync(reportPath, 'utf8');
292
- const parsedReport = parseReviewReport(reportContent);
293
- if (parsedReport.conclusion) {
294
- reviewConclusion = parsedReport.conclusion;
295
- }
296
- for (const validation of validations) {
297
- const normalizedValidation = normalizeValidationName(validation);
298
- if (normalizedValidation === 'review-conclusion') {
299
- if (reviewConclusion !== 'PASS') {
300
- missingValidations.push('review-conclusion=PASS');
187
+ function R(e) {
188
+ let { taskId: t, filePath: r, state: s, config: n } = e, i = m(r, n);
189
+ if (!i) return {
190
+ allowed: !1,
191
+ skipped: !0,
192
+ reason: 'not-transition-artifact'
193
+ };
194
+ let o = f(n, t);
195
+ if (!o) return {
196
+ allowed: !1,
197
+ skipped: !1,
198
+ phaseCompleted: i.phaseCompleted,
199
+ nextPhase: i.nextPhase,
200
+ reason: `task-not-found:${a(S(n, t), n.projectRoot)}`
201
+ };
202
+ let u = E(o, i.phaseCompleted), p = [], c = [], d = s?.reviewConclusion || null;
203
+ if ('planning' === i.phaseCompleted) {
204
+ let e = function(e, t, r) {
205
+ let s = [], n = e.metadata?.outputs?.task;
206
+ if (n && x.existsSync(P.resolve(r.projectRoot, n)) || s.push('planning-task-exists'), t.includes('planning-ready')) {
207
+ let t = O(e), r = h(e, 'implementationSteps'), n = h(e, 'testStrategy');
208
+ t || s.push('planning.summary'), 0 === r.length && s.push('planning.implementationSteps'), 0 === n.length && s.push('planning.testStrategy');
301
209
  }
302
- continue;
303
- }
304
- if (!hasValidationPassed(normalizedValidation, parsedReport.validationMap)) {
305
- missingValidations.push(validation);
306
- }
307
- }
308
- details.push(`report:${relativePath}`);
309
- return { missingValidations, details, reviewConclusion };
310
- }
311
- /**
312
- * Assess transition gate
313
- * @param options - Options
314
- * @returns Gate assessment result
315
- */
316
- function assessTransitionGate(options) {
317
- const { taskId, filePath, state, config } = options;
318
- const transition = deriveTransitionFromFilePath(filePath, config);
319
- if (!transition) {
320
- return { allowed: false, skipped: true, reason: 'not-transition-artifact' };
321
- }
322
- const taskJson = readTaskJson(config, taskId);
323
- if (!taskJson) {
324
- return {
325
- allowed: false,
326
- skipped: false,
327
- phaseCompleted: transition.phaseCompleted,
328
- nextPhase: transition.nextPhase,
329
- reason: `task-not-found:${normalizePath(getTaskFilePath(config, taskId), config.projectRoot)}`,
330
- };
331
- }
332
- const validations = getValidationItems(taskJson, transition.phaseCompleted);
333
- let missingValidations = [];
334
- let details = [];
335
- let reviewConclusion = state?.reviewConclusion || null;
336
- if (transition.phaseCompleted === 'planning') {
337
- const planningResult = validatePlanningPhase(taskJson, validations, config);
338
- missingValidations = planningResult.missingValidations;
339
- details = planningResult.details;
340
- }
341
- if (transition.phaseCompleted === 'implementation') {
342
- const implResult = validateImplementationPhase(validations, transition.relativePath, config);
343
- missingValidations = implResult.missingValidations;
344
- details = implResult.details;
345
- }
346
- if (transition.phaseCompleted === 'review') {
347
- const reviewResult = validateReviewPhase(validations, transition.relativePath, config, reviewConclusion);
348
- missingValidations = reviewResult.missingValidations;
349
- details = reviewResult.details;
350
- reviewConclusion = reviewResult.reviewConclusion;
351
- }
352
- if (missingValidations.length > 0) {
353
- return {
354
- allowed: false,
355
- skipped: false,
356
- phaseCompleted: transition.phaseCompleted,
357
- nextPhase: transition.nextPhase,
358
- missingValidations,
359
- details,
360
- reviewConclusion,
361
- reason: 'phase-validation-failed',
362
- };
363
- }
364
- return {
365
- allowed: true,
366
- skipped: false,
367
- phaseCompleted: transition.phaseCompleted,
368
- nextPhase: transition.nextPhase,
369
- validations,
370
- details,
371
- reviewConclusion,
372
- reason: 'phase-validation-passed',
210
+ return {
211
+ missingValidations: s,
212
+ details: []
213
+ };
214
+ }(o, u, n);
215
+ p = e.missingValidations, c = e.details;
216
+ }
217
+ if ('implementation' === i.phaseCompleted) {
218
+ let e = function(e, t, r) {
219
+ let s = [], n = [], i = A(P.resolve(r.projectRoot, t));
220
+ for (let t of e)C(t, i) || s.push(t);
221
+ return n.push(`snapshot:${t}`), {
222
+ missingValidations: s,
223
+ details: n
224
+ };
225
+ }(u, i.relativePath, n);
226
+ p = e.missingValidations, c = e.details;
227
+ }
228
+ if ('review' === i.phaseCompleted) {
229
+ let e = function(e, t, r, s) {
230
+ let n = [], i = [], o = s, a = P.resolve(r.projectRoot, t);
231
+ if (!x.existsSync(a)) return n.push('review-report-exists'), {
232
+ missingValidations: n,
233
+ details: i,
234
+ reviewConclusion: o
235
+ };
236
+ let u = g(x.readFileSync(a, 'utf8'));
237
+ for (let t of (u.conclusion && (o = u.conclusion), e)){
238
+ let e = l(t);
239
+ if ('review-conclusion' === e) {
240
+ 'PASS' !== o && n.push('review-conclusion=PASS');
241
+ continue;
242
+ }
243
+ C(e, u.validationMap) || n.push(t);
244
+ }
245
+ return i.push(`report:${t}`), {
246
+ missingValidations: n,
247
+ details: i,
248
+ reviewConclusion: o
249
+ };
250
+ }(u, i.relativePath, n, d);
251
+ p = e.missingValidations, c = e.details, d = e.reviewConclusion;
252
+ }
253
+ return p.length > 0 ? {
254
+ allowed: !1,
255
+ skipped: !1,
256
+ phaseCompleted: i.phaseCompleted,
257
+ nextPhase: i.nextPhase,
258
+ missingValidations: p,
259
+ details: c,
260
+ reviewConclusion: d,
261
+ reason: 'phase-validation-failed'
262
+ } : {
263
+ allowed: !0,
264
+ skipped: !1,
265
+ phaseCompleted: i.phaseCompleted,
266
+ nextPhase: i.nextPhase,
267
+ validations: u,
268
+ details: c,
269
+ reviewConclusion: d,
270
+ reason: 'phase-validation-passed'
373
271
  };
374
272
  }
375
- /**
376
- * Main entry point for hook usage
377
- */
378
- function main() {
379
- const input = JSON.parse(process.argv[2] || '{}');
380
- const filePath = input.tool_input?.file_path || input.tool_input?.path || '';
381
- const config = (0, config_1.loadConfig)();
382
- const state = (0, state_1.loadState)(config);
383
- if (!state?.currentTask) {
384
- process.exit(0);
385
- }
386
- const result = assessTransitionGate({ taskId: state.currentTask, filePath, state, config });
387
- if (result.skipped) {
388
- process.exit(0);
389
- }
390
- if (!result.allowed) {
391
- console.error(`[PHASE-GATE] blocked ${result.phaseCompleted} -> ${result.nextPhase}: ${result.reason}`);
392
- if (Array.isArray(result.missingValidations) && result.missingValidations.length > 0) {
393
- console.error(`[PHASE-GATE] missing: ${result.missingValidations.join(', ')}`);
394
- }
395
- process.exit(2);
273
+ "use strict";
274
+ Object.defineProperty(exports, "__esModule", {
275
+ value: !0
276
+ });
277
+ var _ = exports, I = {
278
+ get assessTransitionGate () {
279
+ return R;
280
+ },
281
+ get default () {
282
+ return L;
283
+ },
284
+ get deriveTransitionFromFilePath () {
285
+ return m;
286
+ },
287
+ get getPlanningList () {
288
+ return h;
289
+ },
290
+ get getPlanningSummary () {
291
+ return O;
292
+ },
293
+ get getSnapshotValidationMap () {
294
+ return A;
295
+ },
296
+ get getTaskFilePath () {
297
+ return S;
298
+ },
299
+ get getValidationAliases () {
300
+ return u;
301
+ },
302
+ get getValidationItems () {
303
+ return E;
304
+ },
305
+ get hasValidationPassed () {
306
+ return C;
307
+ },
308
+ get isPassedStatus () {
309
+ return p;
310
+ },
311
+ get normalizePath () {
312
+ return a;
313
+ },
314
+ get normalizeValidationName () {
315
+ return l;
316
+ },
317
+ get parseReviewConclusion () {
318
+ return c;
319
+ },
320
+ get parseReviewReport () {
321
+ return g;
322
+ },
323
+ get parseReviewValidationMap () {
324
+ return d;
325
+ },
326
+ get readTaskJson () {
327
+ return f;
396
328
  }
397
- process.exit(0);
398
- }
399
- if (require.main === module) {
400
- main();
401
- }
402
- exports.default = {
403
- assessTransitionGate,
404
- deriveTransitionFromFilePath,
405
- parseReviewConclusion,
406
- parseReviewReport,
329
+ };
330
+ for(var N in I)Object.defineProperty(_, N, {
331
+ enumerable: !0,
332
+ get: Object.getOwnPropertyDescriptor(I, N).get
333
+ });
334
+ let x = /*#__PURE__*/ o(require("fs")), P = /*#__PURE__*/ o(require("path")), v = require("../lib/config"), y = require("../lib/state"), b = require("../lib/constants");
335
+ require.main === module && (e = JSON.parse(process.argv[2] || '{}'), t = e.tool_input?.file_path || e.tool_input?.path || '', r = (0, v.loadConfig)(), s = (0, y.loadState)(r), s?.currentTask || process.exit(0), (n = R({
336
+ taskId: s.currentTask,
337
+ filePath: t,
338
+ state: s,
339
+ config: r
340
+ })).skipped && process.exit(0), n.allowed || (console.error(`[PHASE-GATE] blocked ${n.phaseCompleted} -> ${n.nextPhase}: ${n.reason}`), Array.isArray(n.missingValidations) && n.missingValidations.length > 0 && console.error(`[PHASE-GATE] missing: ${n.missingValidations.join(', ')}`), process.exit(2)), process.exit(0));
341
+ let L = {
342
+ assessTransitionGate: R,
343
+ deriveTransitionFromFilePath: m,
344
+ parseReviewConclusion: c,
345
+ parseReviewReport: g
407
346
  };