@agentic-coding-framework/orchestrator-core 0.2.0 → 0.3.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.
@@ -0,0 +1,229 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const os_1 = require("os");
7
+ const state_1 = require("../state");
8
+ (0, vitest_1.describe)("state", () => {
9
+ let tempDir;
10
+ (0, vitest_1.beforeEach)(() => {
11
+ tempDir = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), "state-test-"));
12
+ });
13
+ (0, vitest_1.afterEach)(() => {
14
+ (0, fs_1.rmSync)(tempDir, { recursive: true, force: true });
15
+ });
16
+ (0, vitest_1.describe)("createInitialState", () => {
17
+ (0, vitest_1.it)("creates state with correct defaults", () => {
18
+ const state = (0, state_1.createInitialState)("my-app");
19
+ (0, vitest_1.expect)(state.project).toBe("my-app");
20
+ (0, vitest_1.expect)(state.step).toBe("bootstrap");
21
+ (0, vitest_1.expect)(state.attempt).toBe(1);
22
+ (0, vitest_1.expect)(state.status).toBe("pending");
23
+ (0, vitest_1.expect)(state.reason).toBeNull();
24
+ (0, vitest_1.expect)(state.story).toBeNull();
25
+ });
26
+ });
27
+ (0, vitest_1.describe)("validate", () => {
28
+ (0, vitest_1.it)("accepts valid state", () => {
29
+ const state = (0, state_1.createInitialState)("app");
30
+ (0, vitest_1.expect)(() => (0, state_1.validate)(state)).not.toThrow();
31
+ });
32
+ (0, vitest_1.it)("rejects empty project", () => {
33
+ const state = (0, state_1.createInitialState)("");
34
+ (0, vitest_1.expect)(() => (0, state_1.validate)(state)).toThrow("project is required");
35
+ });
36
+ (0, vitest_1.it)("rejects invalid step", () => {
37
+ const state = (0, state_1.createInitialState)("app");
38
+ state.step = "invalid";
39
+ (0, vitest_1.expect)(() => (0, state_1.validate)(state)).toThrow("Invalid step");
40
+ });
41
+ (0, vitest_1.it)("rejects invalid status", () => {
42
+ const state = (0, state_1.createInitialState)("app");
43
+ state.status = "banana";
44
+ (0, vitest_1.expect)(() => (0, state_1.validate)(state)).toThrow("Invalid status");
45
+ });
46
+ (0, vitest_1.it)("rejects invalid reason (non-null)", () => {
47
+ const state = (0, state_1.createInitialState)("app");
48
+ state.reason = "bad_reason";
49
+ (0, vitest_1.expect)(() => (0, state_1.validate)(state)).toThrow("Invalid reason");
50
+ });
51
+ (0, vitest_1.it)("accepts null reason", () => {
52
+ const state = (0, state_1.createInitialState)("app");
53
+ state.reason = null;
54
+ (0, vitest_1.expect)(() => (0, state_1.validate)(state)).not.toThrow();
55
+ });
56
+ (0, vitest_1.it)("accepts valid reason", () => {
57
+ const state = (0, state_1.createInitialState)("app");
58
+ state.reason = "needs_clarification";
59
+ (0, vitest_1.expect)(() => (0, state_1.validate)(state)).not.toThrow();
60
+ });
61
+ });
62
+ (0, vitest_1.describe)("sanitize", () => {
63
+ (0, vitest_1.it)('auto-corrects "passing" → "pass"', () => {
64
+ const state = (0, state_1.createInitialState)("app");
65
+ state.status = "passing";
66
+ const warnings = (0, state_1.sanitize)(state);
67
+ (0, vitest_1.expect)(state.status).toBe("pass");
68
+ (0, vitest_1.expect)(warnings).toHaveLength(1);
69
+ (0, vitest_1.expect)(warnings[0]).toContain("passing");
70
+ (0, vitest_1.expect)(warnings[0]).toContain("pass");
71
+ });
72
+ (0, vitest_1.it)('auto-corrects "failed" → "failing"', () => {
73
+ const state = (0, state_1.createInitialState)("app");
74
+ state.status = "failed";
75
+ const warnings = (0, state_1.sanitize)(state);
76
+ (0, vitest_1.expect)(state.status).toBe("failing");
77
+ (0, vitest_1.expect)(warnings.length).toBeGreaterThanOrEqual(1);
78
+ });
79
+ (0, vitest_1.it)("clears reason when status is not failing", () => {
80
+ const state = (0, state_1.createInitialState)("app");
81
+ state.status = "pass";
82
+ state.reason = "needs_clarification";
83
+ const warnings = (0, state_1.sanitize)(state);
84
+ (0, vitest_1.expect)(state.reason).toBeNull();
85
+ (0, vitest_1.expect)(warnings).toHaveLength(1);
86
+ (0, vitest_1.expect)(warnings[0]).toContain("Cleared reason");
87
+ });
88
+ (0, vitest_1.it)("clears invalid reason (long text) when status is failing", () => {
89
+ const state = (0, state_1.createInitialState)("app");
90
+ state.status = "failing";
91
+ state.reason =
92
+ "This is a long summary of what happened during the task execution that should not be here";
93
+ const warnings = (0, state_1.sanitize)(state);
94
+ (0, vitest_1.expect)(state.reason).toBeNull();
95
+ (0, vitest_1.expect)(warnings).toHaveLength(1);
96
+ (0, vitest_1.expect)(warnings[0]).toContain("Cleared invalid reason");
97
+ });
98
+ (0, vitest_1.it)("preserves valid reason when status is failing", () => {
99
+ const state = (0, state_1.createInitialState)("app");
100
+ state.status = "failing";
101
+ state.reason = "constitution_violation";
102
+ const warnings = (0, state_1.sanitize)(state);
103
+ (0, vitest_1.expect)(state.reason).toBe("constitution_violation");
104
+ (0, vitest_1.expect)(warnings).toHaveLength(0);
105
+ });
106
+ (0, vitest_1.it)("returns empty warnings for clean state", () => {
107
+ const state = (0, state_1.createInitialState)("app");
108
+ const warnings = (0, state_1.sanitize)(state);
109
+ (0, vitest_1.expect)(warnings).toHaveLength(0);
110
+ });
111
+ (0, vitest_1.it)("readState auto-corrects and persists fix", () => {
112
+ const state = (0, state_1.createInitialState)("app");
113
+ // Write a valid state first, then manually corrupt it
114
+ (0, state_1.writeState)(tempDir, state);
115
+ // Read the raw file path and write corrupted JSON
116
+ const { readFileSync, writeFileSync } = require("fs");
117
+ const { join } = require("path");
118
+ const path = join(tempDir, ".ai", "STATE.json");
119
+ const raw = JSON.parse(readFileSync(path, "utf-8"));
120
+ raw.status = "passing";
121
+ writeFileSync(path, JSON.stringify(raw, null, 2) + "\n", "utf-8");
122
+ // readState should auto-correct
123
+ const loaded = (0, state_1.readState)(tempDir);
124
+ (0, vitest_1.expect)(loaded.status).toBe("pass");
125
+ // Re-read raw file to verify it was persisted
126
+ const fixed = JSON.parse(readFileSync(path, "utf-8"));
127
+ (0, vitest_1.expect)(fixed.status).toBe("pass");
128
+ });
129
+ });
130
+ (0, vitest_1.describe)("read/write round-trip", () => {
131
+ (0, vitest_1.it)("writes and reads back identical state", () => {
132
+ const original = (0, state_1.createInitialState)("round-trip-app");
133
+ original.story = "US-001";
134
+ original.step = "impl";
135
+ original.attempt = 3;
136
+ original.status = "failing";
137
+ original.reason = "constitution_violation";
138
+ (0, state_1.writeState)(tempDir, original);
139
+ const loaded = (0, state_1.readState)(tempDir);
140
+ (0, vitest_1.expect)(loaded).toEqual(original);
141
+ });
142
+ (0, vitest_1.it)("creates .ai/ directory if missing", () => {
143
+ const state = (0, state_1.createInitialState)("new-project");
144
+ (0, state_1.writeState)(tempDir, state);
145
+ const loaded = (0, state_1.readState)(tempDir);
146
+ (0, vitest_1.expect)(loaded.project).toBe("new-project");
147
+ });
148
+ (0, vitest_1.it)("throws when reading non-existent STATE.json", () => {
149
+ (0, vitest_1.expect)(() => (0, state_1.readState)(tempDir)).toThrow("STATE.json not found");
150
+ });
151
+ });
152
+ (0, vitest_1.describe)("initState", () => {
153
+ (0, vitest_1.it)("creates new state file", () => {
154
+ const { created, state } = (0, state_1.initState)(tempDir, "init-app");
155
+ (0, vitest_1.expect)(created).toBe(true);
156
+ (0, vitest_1.expect)(state.project).toBe("init-app");
157
+ });
158
+ (0, vitest_1.it)("skips if already exists", () => {
159
+ (0, state_1.initState)(tempDir, "init-app");
160
+ const { created, state } = (0, state_1.initState)(tempDir, "different-name");
161
+ (0, vitest_1.expect)(created).toBe(false);
162
+ (0, vitest_1.expect)(state.project).toBe("init-app"); // original preserved
163
+ });
164
+ });
165
+ (0, vitest_1.describe)("isTimedOut", () => {
166
+ (0, vitest_1.it)("returns false when not running", () => {
167
+ const state = (0, state_1.createInitialState)("app");
168
+ (0, vitest_1.expect)((0, state_1.isTimedOut)(state)).toBe(false);
169
+ });
170
+ (0, vitest_1.it)("returns false when within timeout", () => {
171
+ const state = (0, state_1.createInitialState)("app");
172
+ state.status = "running";
173
+ state.dispatched_at = new Date().toISOString();
174
+ state.timeout_min = 10;
175
+ (0, vitest_1.expect)((0, state_1.isTimedOut)(state)).toBe(false);
176
+ });
177
+ (0, vitest_1.it)("returns true when past timeout", () => {
178
+ const state = (0, state_1.createInitialState)("app");
179
+ state.status = "running";
180
+ state.dispatched_at = new Date(Date.now() - 15 * 60_000).toISOString();
181
+ state.timeout_min = 10;
182
+ (0, vitest_1.expect)((0, state_1.isTimedOut)(state)).toBe(true);
183
+ });
184
+ });
185
+ (0, vitest_1.describe)("isMaxedOut", () => {
186
+ (0, vitest_1.it)("returns true at max", () => {
187
+ const state = (0, state_1.createInitialState)("app");
188
+ state.attempt = 5;
189
+ state.max_attempts = 5;
190
+ (0, vitest_1.expect)((0, state_1.isMaxedOut)(state)).toBe(true);
191
+ });
192
+ (0, vitest_1.it)("returns false below max", () => {
193
+ const state = (0, state_1.createInitialState)("app");
194
+ state.attempt = 2;
195
+ state.max_attempts = 5;
196
+ (0, vitest_1.expect)((0, state_1.isMaxedOut)(state)).toBe(false);
197
+ });
198
+ });
199
+ (0, vitest_1.describe)("markRunning", () => {
200
+ (0, vitest_1.it)("sets status and timestamp", () => {
201
+ const state = (0, state_1.createInitialState)("app");
202
+ const running = (0, state_1.markRunning)(state);
203
+ (0, vitest_1.expect)(running.status).toBe("running");
204
+ (0, vitest_1.expect)(running.dispatched_at).toBeTruthy();
205
+ (0, vitest_1.expect)(running.completed_at).toBeNull();
206
+ (0, vitest_1.expect)(running.reason).toBeNull();
207
+ });
208
+ (0, vitest_1.it)("does not mutate original", () => {
209
+ const state = (0, state_1.createInitialState)("app");
210
+ (0, state_1.markRunning)(state);
211
+ (0, vitest_1.expect)(state.status).toBe("pending");
212
+ });
213
+ });
214
+ (0, vitest_1.describe)("markCompleted", () => {
215
+ (0, vitest_1.it)("sets status and timestamp", () => {
216
+ const state = (0, state_1.markRunning)((0, state_1.createInitialState)("app"));
217
+ const done = (0, state_1.markCompleted)(state, "pass");
218
+ (0, vitest_1.expect)(done.status).toBe("pass");
219
+ (0, vitest_1.expect)(done.completed_at).toBeTruthy();
220
+ });
221
+ (0, vitest_1.it)("sets reason on failure", () => {
222
+ const state = (0, state_1.markRunning)((0, state_1.createInitialState)("app"));
223
+ const failed = (0, state_1.markCompleted)(state, "failing", "needs_clarification");
224
+ (0, vitest_1.expect)(failed.status).toBe("failing");
225
+ (0, vitest_1.expect)(failed.reason).toBe("needs_clarification");
226
+ });
227
+ });
228
+ });
229
+ //# sourceMappingURL=state.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.test.js","sourceRoot":"","sources":["../../src/__tests__/state.test.ts"],"names":[],"mappings":";;AAAA,mCAAqE;AACrE,2BAAyC;AACzC,+BAA4B;AAC5B,2BAA4B;AAE5B,oCAWkB;AAElB,IAAA,iBAAQ,EAAC,OAAO,EAAE,GAAG,EAAE;IACrB,IAAI,OAAe,CAAC;IAEpB,IAAA,mBAAU,EAAC,GAAG,EAAE;QACd,OAAO,GAAG,IAAA,gBAAW,EAAC,IAAA,WAAI,EAAC,IAAA,WAAM,GAAE,EAAE,aAAa,CAAC,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,IAAA,kBAAS,EAAC,GAAG,EAAE;QACb,IAAA,WAAM,EAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,IAAA,WAAE,EAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,QAAQ,CAAC,CAAC;YAC3C,IAAA,eAAM,EAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrC,IAAA,eAAM,EAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACrC,IAAA,eAAM,EAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC9B,IAAA,eAAM,EAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACrC,IAAA,eAAM,EAAC,KAAK,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,IAAA,eAAM,EAAC,KAAK,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,UAAU,EAAE,GAAG,EAAE;QACxB,IAAA,WAAE,EAAC,qBAAqB,EAAE,GAAG,EAAE;YAC7B,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC;YACxC,IAAA,eAAM,EAAC,GAAG,EAAE,CAAC,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,uBAAuB,EAAE,GAAG,EAAE;YAC/B,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,EAAE,CAAC,CAAC;YACrC,IAAA,eAAM,EAAC,GAAG,EAAE,CAAC,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,sBAAsB,EAAE,GAAG,EAAE;YAC9B,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC;YACvC,KAAa,CAAC,IAAI,GAAG,SAAS,CAAC;YAChC,IAAA,eAAM,EAAC,GAAG,EAAE,CAAC,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,wBAAwB,EAAE,GAAG,EAAE;YAChC,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC;YACvC,KAAa,CAAC,MAAM,GAAG,QAAQ,CAAC;YACjC,IAAA,eAAM,EAAC,GAAG,EAAE,CAAC,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC;YACvC,KAAa,CAAC,MAAM,GAAG,YAAY,CAAC;YACrC,IAAA,eAAM,EAAC,GAAG,EAAE,CAAC,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,qBAAqB,EAAE,GAAG,EAAE;YAC7B,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC;YACxC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;YACpB,IAAA,eAAM,EAAC,GAAG,EAAE,CAAC,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,sBAAsB,EAAE,GAAG,EAAE;YAC9B,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC;YACxC,KAAK,CAAC,MAAM,GAAG,qBAAqB,CAAC;YACrC,IAAA,eAAM,EAAC,GAAG,EAAE,CAAC,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QAC9C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,UAAU,EAAE,GAAG,EAAE;QACxB,IAAA,WAAE,EAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC;YACvC,KAAa,CAAC,MAAM,GAAG,SAAS,CAAC;YAClC,MAAM,QAAQ,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;YACjC,IAAA,eAAM,EAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAClC,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjC,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;YACzC,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC;YACvC,KAAa,CAAC,MAAM,GAAG,QAAQ,CAAC;YACjC,MAAM,QAAQ,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;YACjC,IAAA,eAAM,EAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACrC,IAAA,eAAM,EAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC;YACxC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;YACrB,KAAa,CAAC,MAAM,GAAG,qBAAqB,CAAC;YAC9C,MAAM,QAAQ,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;YACjC,IAAA,eAAM,EAAC,KAAK,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjC,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,0DAA0D,EAAE,GAAG,EAAE;YAClE,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC;YACxC,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC;YACxB,KAAa,CAAC,MAAM;gBACnB,2FAA2F,CAAC;YAC9F,MAAM,QAAQ,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;YACjC,IAAA,eAAM,EAAC,KAAK,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjC,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,+CAA+C,EAAE,GAAG,EAAE;YACvD,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC;YACxC,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC;YACzB,KAAK,CAAC,MAAM,GAAG,wBAAwB,CAAC;YACxC,MAAM,QAAQ,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;YACjC,IAAA,eAAM,EAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;YACpD,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC;YACxC,MAAM,QAAQ,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;YACjC,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC;YACxC,sDAAsD;YACtD,IAAA,kBAAU,EAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAC3B,kDAAkD;YAClD,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YACtD,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;YACjC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;YAChD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;YACpD,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC;YACvB,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;YAElE,gCAAgC;YAChC,MAAM,MAAM,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,CAAC;YAClC,IAAA,eAAM,EAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAEnC,8CAA8C;YAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;YACtD,IAAA,eAAM,EAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,uBAAuB,EAAE,GAAG,EAAE;QACrC,IAAA,WAAE,EAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,MAAM,QAAQ,GAAG,IAAA,0BAAkB,EAAC,gBAAgB,CAAC,CAAC;YACtD,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC;YAC1B,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC;YACvB,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAC;YACrB,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC;YAC5B,QAAQ,CAAC,MAAM,GAAG,wBAAwB,CAAC;YAE3C,IAAA,kBAAU,EAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAC9B,MAAM,MAAM,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,CAAC;YAElC,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,aAAa,CAAC,CAAC;YAChD,IAAA,kBAAU,EAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAC3B,MAAM,MAAM,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,CAAC;YAClC,IAAA,eAAM,EAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,6CAA6C,EAAE,GAAG,EAAE;YACrD,IAAA,eAAM,EAAC,GAAG,EAAE,CAAC,IAAA,iBAAS,EAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,WAAW,EAAE,GAAG,EAAE;QACzB,IAAA,WAAE,EAAC,wBAAwB,EAAE,GAAG,EAAE;YAChC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAA,iBAAS,EAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YAC1D,IAAA,eAAM,EAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3B,IAAA,eAAM,EAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,yBAAyB,EAAE,GAAG,EAAE;YACjC,IAAA,iBAAS,EAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YAC/B,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAA,iBAAS,EAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;YAChE,IAAA,eAAM,EAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5B,IAAA,eAAM,EAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,qBAAqB;QAC/D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,YAAY,EAAE,GAAG,EAAE;QAC1B,IAAA,WAAE,EAAC,gCAAgC,EAAE,GAAG,EAAE;YACxC,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC;YACxC,IAAA,eAAM,EAAC,IAAA,kBAAU,EAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC;YACxC,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC;YACzB,KAAK,CAAC,aAAa,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAC/C,KAAK,CAAC,WAAW,GAAG,EAAE,CAAC;YACvB,IAAA,eAAM,EAAC,IAAA,kBAAU,EAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,gCAAgC,EAAE,GAAG,EAAE;YACxC,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC;YACxC,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC;YACzB,KAAK,CAAC,aAAa,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;YACvE,KAAK,CAAC,WAAW,GAAG,EAAE,CAAC;YACvB,IAAA,eAAM,EAAC,IAAA,kBAAU,EAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,YAAY,EAAE,GAAG,EAAE;QAC1B,IAAA,WAAE,EAAC,qBAAqB,EAAE,GAAG,EAAE;YAC7B,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC;YACxC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC;YAClB,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC;YACvB,IAAA,eAAM,EAAC,IAAA,kBAAU,EAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,yBAAyB,EAAE,GAAG,EAAE;YACjC,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC;YACxC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC;YAClB,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC;YACvB,IAAA,eAAM,EAAC,IAAA,kBAAU,EAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,aAAa,EAAE,GAAG,EAAE;QAC3B,IAAA,WAAE,EAAC,2BAA2B,EAAE,GAAG,EAAE;YACnC,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC;YACxC,MAAM,OAAO,GAAG,IAAA,mBAAW,EAAC,KAAK,CAAC,CAAC;YACnC,IAAA,eAAM,EAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACvC,IAAA,eAAM,EAAC,OAAO,CAAC,aAAa,CAAC,CAAC,UAAU,EAAE,CAAC;YAC3C,IAAA,eAAM,EAAC,OAAO,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC;YACxC,IAAA,eAAM,EAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,0BAA0B,EAAE,GAAG,EAAE;YAClC,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC;YACxC,IAAA,mBAAW,EAAC,KAAK,CAAC,CAAC;YACnB,IAAA,eAAM,EAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,IAAA,WAAE,EAAC,2BAA2B,EAAE,GAAG,EAAE;YACnC,MAAM,KAAK,GAAG,IAAA,mBAAW,EAAC,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC,CAAC;YACrD,MAAM,IAAI,GAAG,IAAA,qBAAa,EAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC1C,IAAA,eAAM,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACjC,IAAA,eAAM,EAAC,IAAI,CAAC,YAAY,CAAC,CAAC,UAAU,EAAE,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,wBAAwB,EAAE,GAAG,EAAE;YAChC,MAAM,KAAK,GAAG,IAAA,mBAAW,EAAC,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC,CAAC;YACrD,MAAM,MAAM,GAAG,IAAA,qBAAa,EAAC,KAAK,EAAE,SAAS,EAAE,qBAAqB,CAAC,CAAC;YACtE,IAAA,eAAM,EAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACtC,IAAA,eAAM,EAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/dist/auto.d.ts CHANGED
@@ -10,56 +10,6 @@
10
10
  *
11
11
  * and gets back a JSON result with an `action` field telling it what happened.
12
12
  */
13
- import type { Reason } from "./state";
14
- import { type ProjectStatus, type FrameworkDetection, type ProjectEntry } from "./dispatch";
15
- export type AutoResult = {
16
- action: "query";
17
- data: ProjectStatus;
18
- memory?: string;
19
- handoff?: string;
20
- } | {
21
- action: "dispatched";
22
- step: string;
23
- attempt: number;
24
- prompt: string;
25
- fw_lv: number;
26
- } | {
27
- action: "done";
28
- story: string;
29
- summary: string;
30
- } | {
31
- action: "needs_human";
32
- step: string;
33
- message: string;
34
- } | {
35
- action: "blocked";
36
- step: string;
37
- reason: string;
38
- } | {
39
- action: "already_running";
40
- step: string;
41
- elapsed_min: number;
42
- } | {
43
- action: "timeout";
44
- step: string;
45
- elapsed_min: number;
46
- } | {
47
- action: "approved";
48
- note?: string;
49
- } | {
50
- action: "rejected";
51
- reason: string;
52
- note?: string;
53
- } | {
54
- action: "detected";
55
- framework: FrameworkDetection;
56
- } | {
57
- action: "listed";
58
- projects: ProjectEntry[];
59
- } | {
60
- action: "error";
61
- message: string;
62
- };
63
13
  type Intent = {
64
14
  type: "query";
65
15
  } | {
@@ -67,7 +17,7 @@ type Intent = {
67
17
  note?: string;
68
18
  } | {
69
19
  type: "reject";
70
- reason: Reason;
20
+ reason: string;
71
21
  note?: string;
72
22
  } | {
73
23
  type: "start_story";
@@ -94,12 +44,7 @@ export declare function classify(message: string): Intent;
94
44
  *
95
45
  * Takes a project root and a raw user message, classifies the intent,
96
46
  * and routes to the appropriate function. Returns a JSON-serializable result.
97
- *
98
- * Usage:
99
- * orchestrator auto ./project "目前狀態如何"
100
- * orchestrator auto ./project "繼續"
101
- * orchestrator auto ./project "幫我 refactor auth module"
102
- * orchestrator auto ./project "approve"
103
47
  */
104
- export declare function auto(projectRoot: string, message: string): AutoResult;
48
+ export declare function auto(projectRoot: string, message: string): Record<string, unknown>;
105
49
  export {};
50
+ //# sourceMappingURL=auto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto.d.ts","sourceRoot":"","sources":["../src/auto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAkBH,KAAK,MAAM,GACP;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAI5C;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAsDhD;AA6ED;;;;;GAKG;AACH,wBAAgB,IAAI,CAClB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA8EzB"}
package/dist/auto.js CHANGED
@@ -17,6 +17,8 @@ exports.auto = auto;
17
17
  const fs_1 = require("fs");
18
18
  const path_1 = require("path");
19
19
  const dispatch_1 = require("./dispatch");
20
+ const state_1 = require("./state");
21
+ // ─── Classifier ──────────────────────────────────────────────────────────────
20
22
  /**
21
23
  * Classify a raw user message into an intent.
22
24
  * Pure keyword/regex matching — zero LLM tokens.
@@ -28,18 +30,20 @@ function classify(message) {
28
30
  const lower = msg.toLowerCase();
29
31
  // ── Approve ──
30
32
  if (/^(approve|核准|lgtm|通過|approved|ok\s*$)/i.test(msg)) {
31
- const note = msg.replace(/^(approve|核准|lgtm|通過|approved|ok)\s*/i, "").trim() || undefined;
33
+ const note = msg.replace(/^(approve|核准|lgtm|通過|approved|ok)\s*/i, "").trim() ||
34
+ undefined;
32
35
  return { type: "approve", note };
33
36
  }
34
37
  // ── Reject ──
35
38
  if (/^(reject|退回|不行|rejected)/i.test(msg)) {
36
- const rest = msg.replace(/^(reject|退回|不行|rejected)\s*/i, "").trim();
39
+ const rest = msg
40
+ .replace(/^(reject|退回|不行|rejected)\s*/i, "")
41
+ .trim();
37
42
  const { reason, note } = extractRejectReason(rest);
38
43
  return { type: "reject", reason, note };
39
44
  }
40
45
  // ── Start Story (must be before query — "start US-007" is not a query) ──
41
- const storyMatch = msg.match(/(?:start\s*story|開始\s*story|開新\s*story|start)\s+(US-\d+)/i)
42
- || msg.match(/^(US-\d+)/i);
46
+ const storyMatch = msg.match(/(?:start\s*story|開始\s*story|開新\s*story|start)\s+(US-\d+)/i) || msg.match(/^(US-\d+)/i);
43
47
  if (storyMatch) {
44
48
  return { type: "start_story", storyId: storyMatch[1] };
45
49
  }
@@ -65,15 +69,42 @@ function classify(message) {
65
69
  /** Check if the message is a read-only query */
66
70
  function isQuery(lower) {
67
71
  const queryPatterns = [
68
- /狀態/, /status/, /什麼步驟/, /what\s*step/, /which\s*step/,
69
- /測試/, /tests?/, /進度/, /progress/,
70
- /還有什麼/, /what's\s*next/, /what\s*next/, /what's\s*left/,
71
- /history/, /歷史/, /上次/, /last\s*(session|time)/,
72
- /怎麼樣/, /how.*project/, /how.*going/,
73
- /目前/, /current/, /看一下/, /看看/, /查一下/, /check\s*status/,
74
- /哪個步驟/, /卡住/, /blocked/, /why.*block/,
75
- /summary/, /摘要/, /report/, /報告/,
76
- /打開/, /open\s*project/,
72
+ /狀態/,
73
+ /status/,
74
+ /什麼步驟/,
75
+ /what\s*step/,
76
+ /which\s*step/,
77
+ /測試/,
78
+ /tests?/,
79
+ /進度/,
80
+ /progress/,
81
+ /還有什麼/,
82
+ /what's\s*next/,
83
+ /what\s*next/,
84
+ /what's\s*left/,
85
+ /history/,
86
+ /歷史/,
87
+ /上次/,
88
+ /last\s*(session|time)/,
89
+ /怎麼樣/,
90
+ /how.*project/,
91
+ /how.*going/,
92
+ /目前/,
93
+ /current/,
94
+ /看一下/,
95
+ /看看/,
96
+ /查一下/,
97
+ /check\s*status/,
98
+ /哪個步驟/,
99
+ /卡住/,
100
+ /blocked/,
101
+ /why.*block/,
102
+ /summary/,
103
+ /摘要/,
104
+ /report/,
105
+ /報告/,
106
+ /打開/,
107
+ /open\s*project/,
77
108
  ];
78
109
  return queryPatterns.some((p) => p.test(lower));
79
110
  }
@@ -81,15 +112,15 @@ function isQuery(lower) {
81
112
  function extractRejectReason(rest) {
82
113
  const reasonMap = {
83
114
  clarification: "needs_clarification",
84
- 需要說明: "needs_clarification",
85
- 不清楚: "needs_clarification",
115
+ "需要說明": "needs_clarification",
116
+ "不清楚": "needs_clarification",
86
117
  constitution: "constitution_violation",
87
- 架構違反: "constitution_violation",
118
+ "架構違反": "constitution_violation",
88
119
  scope: "scope_warning",
89
- 範圍: "scope_warning",
120
+ "範圍": "scope_warning",
90
121
  nfr: "nfr_missing",
91
122
  timeout: "test_timeout",
92
- 超時: "test_timeout",
123
+ "超時": "test_timeout",
93
124
  };
94
125
  for (const [keyword, reason] of Object.entries(reasonMap)) {
95
126
  if (rest.toLowerCase().includes(keyword)) {
@@ -106,12 +137,6 @@ function extractRejectReason(rest) {
106
137
  *
107
138
  * Takes a project root and a raw user message, classifies the intent,
108
139
  * and routes to the appropriate function. Returns a JSON-serializable result.
109
- *
110
- * Usage:
111
- * orchestrator auto ./project "目前狀態如何"
112
- * orchestrator auto ./project "繼續"
113
- * orchestrator auto ./project "幫我 refactor auth module"
114
- * orchestrator auto ./project "approve"
115
140
  */
116
141
  function auto(projectRoot, message) {
117
142
  const intent = classify(message);
@@ -128,22 +153,67 @@ function auto(projectRoot, message) {
128
153
  case "continue":
129
154
  return handleDispatch(projectRoot);
130
155
  case "detect":
131
- return { action: "detected", framework: (0, dispatch_1.detectFramework)(projectRoot) };
156
+ return {
157
+ action: "detected",
158
+ framework: (0, dispatch_1.detectFramework)(projectRoot),
159
+ };
132
160
  case "list":
133
- // Use projectRoot as workspace root for listing
134
- return { action: "listed", projects: (0, dispatch_1.listProjects)(projectRoot) };
161
+ return {
162
+ action: "listed",
163
+ projects: (0, dispatch_1.listProjects)(projectRoot),
164
+ };
135
165
  case "custom":
136
166
  return handleCustom(projectRoot, intent.instruction);
137
167
  }
138
168
  }
139
169
  catch (err) {
140
- return { action: "error", message: err.message ?? String(err) };
170
+ const msg = err.message ?? String(err);
171
+ // Defense-in-depth: if validation failed due to corrupted STATE.json,
172
+ // attempt sanitize + retry once before giving up.
173
+ if (/Invalid (status|reason)/.test(msg) &&
174
+ (intent.type === "continue" ||
175
+ intent.type === "query" ||
176
+ intent.type === "approve")) {
177
+ try {
178
+ const state = (() => {
179
+ const { readFileSync } = require("fs");
180
+ const { join } = require("path");
181
+ const raw = readFileSync(join(projectRoot, ".ai", "STATE.json"), "utf-8");
182
+ return JSON.parse(raw);
183
+ })();
184
+ const warnings = (0, state_1.sanitize)(state);
185
+ if (warnings.length > 0) {
186
+ (0, state_1.writeState)(projectRoot, state);
187
+ // Retry the original intent
188
+ switch (intent.type) {
189
+ case "continue":
190
+ return {
191
+ ...wrapDispatchResult((0, dispatch_1.dispatch)(projectRoot)),
192
+ _sanitized: warnings,
193
+ };
194
+ case "query":
195
+ return { ...handleQuery(projectRoot), _sanitized: warnings };
196
+ case "approve":
197
+ return {
198
+ ...handleApprove(projectRoot, intent.note),
199
+ _sanitized: warnings,
200
+ };
201
+ }
202
+ }
203
+ }
204
+ catch {
205
+ // sanitize recovery also failed — fall through to original error
206
+ }
207
+ }
208
+ return {
209
+ action: "error",
210
+ message: msg,
211
+ };
141
212
  }
142
213
  }
143
214
  // ─── Intent Handlers ────────────────────────────────────────────────────────
144
215
  function handleQuery(projectRoot) {
145
216
  const data = (0, dispatch_1.queryProjectStatus)(projectRoot);
146
- // Attach memory and handoff content if available
147
217
  let memory;
148
218
  let handoff;
149
219
  const memoryPath = (0, path_1.join)(projectRoot, "PROJECT_MEMORY.md");
@@ -182,7 +252,6 @@ function handleDispatch(projectRoot) {
182
252
  return wrapDispatchResult((0, dispatch_1.dispatch)(projectRoot));
183
253
  }
184
254
  function handleCustom(projectRoot, instruction) {
185
- // Check if there's an agent-teams keyword
186
255
  const agentTeams = /agent.?teams?|平行|多\s*agent|agents/i.test(instruction);
187
256
  (0, dispatch_1.startCustom)(projectRoot, instruction, { agentTeams });
188
257
  return wrapDispatchResult((0, dispatch_1.dispatch)(projectRoot));
@@ -199,14 +268,35 @@ function wrapDispatchResult(result) {
199
268
  fw_lv: result.fw_lv,
200
269
  };
201
270
  case "done":
202
- return { action: "done", story: result.story, summary: result.summary };
271
+ return {
272
+ action: "done",
273
+ story: result.story,
274
+ summary: result.summary,
275
+ };
203
276
  case "needs_human":
204
- return { action: "needs_human", step: result.step, message: result.message };
277
+ return {
278
+ action: "needs_human",
279
+ step: result.step,
280
+ message: result.message,
281
+ };
205
282
  case "blocked":
206
- return { action: "blocked", step: result.step, reason: result.reason };
283
+ return {
284
+ action: "blocked",
285
+ step: result.step,
286
+ reason: result.reason,
287
+ };
207
288
  case "already_running":
208
- return { action: "already_running", step: result.step, elapsed_min: result.elapsed_min };
289
+ return {
290
+ action: "already_running",
291
+ step: result.step,
292
+ elapsed_min: result.elapsed_min,
293
+ };
209
294
  case "timeout":
210
- return { action: "timeout", step: result.step, elapsed_min: result.elapsed_min };
295
+ return {
296
+ action: "timeout",
297
+ step: result.step,
298
+ elapsed_min: result.elapsed_min,
299
+ };
211
300
  }
212
301
  }
302
+ //# sourceMappingURL=auto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto.js","sourceRoot":"","sources":["../src/auto.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts CHANGED
@@ -7,9 +7,11 @@
7
7
  * start-story <project-root> <story-id> Begin a new User Story (micro-waterfall)
8
8
  * start-custom <project-root> <instruction> Begin a custom ad-hoc task
9
9
  * dispatch <project-root> Dispatch next step (prints prompt)
10
+ * peek <project-root> [FIX P1] Read-only dispatch preview
10
11
  * apply-handoff <project-root> Parse HANDOFF.md → update STATE
11
12
  * approve <project-root> [note] Approve review step
12
13
  * reject <project-root> <reason> [note] Reject review step
13
14
  * status <project-root> Print current STATE.json
14
15
  */
15
16
  export {};
17
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;GAaG"}