@kenkaiiii/ggcoder 4.3.230 → 4.3.231

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 (182) hide show
  1. package/dist/core/goal-controller.d.ts +27 -6
  2. package/dist/core/goal-controller.d.ts.map +1 -1
  3. package/dist/core/goal-controller.js +246 -141
  4. package/dist/core/goal-controller.js.map +1 -1
  5. package/dist/core/goal-controller.test.js +210 -79
  6. package/dist/core/goal-controller.test.js.map +1 -1
  7. package/dist/core/goal-engine.d.ts +61 -0
  8. package/dist/core/goal-engine.d.ts.map +1 -0
  9. package/dist/core/goal-engine.js +123 -0
  10. package/dist/core/goal-engine.js.map +1 -0
  11. package/dist/core/goal-engine.test.d.ts +2 -0
  12. package/dist/core/goal-engine.test.d.ts.map +1 -0
  13. package/dist/core/goal-engine.test.js +295 -0
  14. package/dist/core/goal-engine.test.js.map +1 -0
  15. package/dist/core/goal-integration.d.ts +80 -0
  16. package/dist/core/goal-integration.d.ts.map +1 -0
  17. package/dist/core/goal-integration.js +296 -0
  18. package/dist/core/goal-integration.js.map +1 -0
  19. package/dist/core/goal-integration.test.d.ts +2 -0
  20. package/dist/core/goal-integration.test.d.ts.map +1 -0
  21. package/dist/core/goal-integration.test.js +369 -0
  22. package/dist/core/goal-integration.test.js.map +1 -0
  23. package/dist/core/goal-prerequisites.test.js +37 -1
  24. package/dist/core/goal-prerequisites.test.js.map +1 -1
  25. package/dist/core/goal-store.d.ts +80 -1
  26. package/dist/core/goal-store.d.ts.map +1 -1
  27. package/dist/core/goal-store.js +232 -65
  28. package/dist/core/goal-store.js.map +1 -1
  29. package/dist/core/goal-store.test.js +111 -2
  30. package/dist/core/goal-store.test.js.map +1 -1
  31. package/dist/core/goal-worker.d.ts.map +1 -1
  32. package/dist/core/goal-worker.js +55 -4
  33. package/dist/core/goal-worker.js.map +1 -1
  34. package/dist/core/goal-worker.test.js +75 -6
  35. package/dist/core/goal-worker.test.js.map +1 -1
  36. package/dist/core/goal-worktree.d.ts +55 -1
  37. package/dist/core/goal-worktree.d.ts.map +1 -1
  38. package/dist/core/goal-worktree.js +164 -1
  39. package/dist/core/goal-worktree.js.map +1 -1
  40. package/dist/core/goal-worktree.test.js +226 -4
  41. package/dist/core/goal-worktree.test.js.map +1 -1
  42. package/dist/system-prompt.d.ts.map +1 -1
  43. package/dist/system-prompt.js +9 -6
  44. package/dist/system-prompt.js.map +1 -1
  45. package/dist/system-prompt.test.js +1 -1
  46. package/dist/system-prompt.test.js.map +1 -1
  47. package/dist/tools/edit-diff.d.ts +17 -4
  48. package/dist/tools/edit-diff.d.ts.map +1 -1
  49. package/dist/tools/edit-diff.js +78 -16
  50. package/dist/tools/edit-diff.js.map +1 -1
  51. package/dist/tools/edit-diff.test.js +31 -1
  52. package/dist/tools/edit-diff.test.js.map +1 -1
  53. package/dist/tools/edit-robustness.test.d.ts +2 -0
  54. package/dist/tools/edit-robustness.test.d.ts.map +1 -0
  55. package/dist/tools/edit-robustness.test.js +415 -0
  56. package/dist/tools/edit-robustness.test.js.map +1 -0
  57. package/dist/tools/edit.d.ts.map +1 -1
  58. package/dist/tools/edit.js +15 -16
  59. package/dist/tools/edit.js.map +1 -1
  60. package/dist/tools/edit.test.js +23 -12
  61. package/dist/tools/edit.test.js.map +1 -1
  62. package/dist/tools/goals.d.ts +9 -1
  63. package/dist/tools/goals.d.ts.map +1 -1
  64. package/dist/tools/goals.js +78 -25
  65. package/dist/tools/goals.js.map +1 -1
  66. package/dist/tools/goals.test.js +142 -11
  67. package/dist/tools/goals.test.js.map +1 -1
  68. package/dist/ui/App.d.ts +9 -1
  69. package/dist/ui/App.d.ts.map +1 -1
  70. package/dist/ui/App.js +78 -16
  71. package/dist/ui/App.js.map +1 -1
  72. package/dist/ui/components/ChatLayout.d.ts +8 -1
  73. package/dist/ui/components/ChatLayout.d.ts.map +1 -1
  74. package/dist/ui/components/ChatLayout.js +4 -1
  75. package/dist/ui/components/ChatLayout.js.map +1 -1
  76. package/dist/ui/components/ChatScreen.d.ts +14 -1
  77. package/dist/ui/components/ChatScreen.d.ts.map +1 -1
  78. package/dist/ui/components/ChatScreen.js +3 -2
  79. package/dist/ui/components/ChatScreen.js.map +1 -1
  80. package/dist/ui/components/InputArea.d.ts +13 -1
  81. package/dist/ui/components/InputArea.d.ts.map +1 -1
  82. package/dist/ui/components/InputArea.js +96 -12
  83. package/dist/ui/components/InputArea.js.map +1 -1
  84. package/dist/ui/components/TranscriptViewport.d.ts +34 -0
  85. package/dist/ui/components/TranscriptViewport.d.ts.map +1 -0
  86. package/dist/ui/components/TranscriptViewport.js +45 -0
  87. package/dist/ui/components/TranscriptViewport.js.map +1 -0
  88. package/dist/ui/footer-jump-regression.test.d.ts +2 -0
  89. package/dist/ui/footer-jump-regression.test.d.ts.map +1 -0
  90. package/dist/ui/footer-jump-regression.test.js +167 -0
  91. package/dist/ui/footer-jump-regression.test.js.map +1 -0
  92. package/dist/ui/goal-events.d.ts +1 -1
  93. package/dist/ui/goal-events.d.ts.map +1 -1
  94. package/dist/ui/goal-events.js +2 -2
  95. package/dist/ui/goal-events.js.map +1 -1
  96. package/dist/ui/goal-events.test.js +2 -2
  97. package/dist/ui/goal-events.test.js.map +1 -1
  98. package/dist/ui/goal-lifecycle-orchestration.test.js +13 -97
  99. package/dist/ui/goal-lifecycle-orchestration.test.js.map +1 -1
  100. package/dist/ui/goal-progress.d.ts.map +1 -1
  101. package/dist/ui/goal-progress.js +0 -1
  102. package/dist/ui/goal-progress.js.map +1 -1
  103. package/dist/ui/goal-run-helpers.d.ts +0 -4
  104. package/dist/ui/goal-run-helpers.d.ts.map +1 -1
  105. package/dist/ui/goal-run-helpers.js +2 -21
  106. package/dist/ui/goal-run-helpers.js.map +1 -1
  107. package/dist/ui/hooks/useChatLayoutMeasurements.d.ts +8 -0
  108. package/dist/ui/hooks/useChatLayoutMeasurements.d.ts.map +1 -1
  109. package/dist/ui/hooks/useChatLayoutMeasurements.js +2 -0
  110. package/dist/ui/hooks/useChatLayoutMeasurements.js.map +1 -1
  111. package/dist/ui/hooks/useGoalOrchestration.d.ts +2 -1
  112. package/dist/ui/hooks/useGoalOrchestration.d.ts.map +1 -1
  113. package/dist/ui/hooks/useGoalOrchestration.js +198 -80
  114. package/dist/ui/hooks/useGoalOrchestration.js.map +1 -1
  115. package/dist/ui/hooks/useTerminalSize.d.ts +8 -1
  116. package/dist/ui/hooks/useTerminalSize.d.ts.map +1 -1
  117. package/dist/ui/hooks/useTerminalSize.js +12 -2
  118. package/dist/ui/hooks/useTerminalSize.js.map +1 -1
  119. package/dist/ui/hooks/useTranscriptHistory.d.ts +1 -1
  120. package/dist/ui/hooks/useTranscriptHistory.d.ts.map +1 -1
  121. package/dist/ui/hooks/useTranscriptHistory.js +23 -9
  122. package/dist/ui/hooks/useTranscriptHistory.js.map +1 -1
  123. package/dist/ui/hooks/useTranscriptHistory.test.d.ts +2 -0
  124. package/dist/ui/hooks/useTranscriptHistory.test.d.ts.map +1 -0
  125. package/dist/ui/hooks/useTranscriptHistory.test.js +61 -0
  126. package/dist/ui/hooks/useTranscriptHistory.test.js.map +1 -0
  127. package/dist/ui/hooks/useTranscriptScroll.d.ts +30 -0
  128. package/dist/ui/hooks/useTranscriptScroll.d.ts.map +1 -0
  129. package/dist/ui/hooks/useTranscriptScroll.js +44 -0
  130. package/dist/ui/hooks/useTranscriptScroll.js.map +1 -0
  131. package/dist/ui/hooks/useTranscriptScroll.test.d.ts +2 -0
  132. package/dist/ui/hooks/useTranscriptScroll.test.d.ts.map +1 -0
  133. package/dist/ui/hooks/useTranscriptScroll.test.js +119 -0
  134. package/dist/ui/hooks/useTranscriptScroll.test.js.map +1 -0
  135. package/dist/ui/live-area-clamp.test.js +11 -2
  136. package/dist/ui/live-area-clamp.test.js.map +1 -1
  137. package/dist/ui/render.d.ts +8 -0
  138. package/dist/ui/render.d.ts.map +1 -1
  139. package/dist/ui/render.js +69 -7
  140. package/dist/ui/render.js.map +1 -1
  141. package/dist/ui/stores/transcript-scroll-store.d.ts +27 -0
  142. package/dist/ui/stores/transcript-scroll-store.d.ts.map +1 -0
  143. package/dist/ui/stores/transcript-scroll-store.js +73 -0
  144. package/dist/ui/stores/transcript-scroll-store.js.map +1 -0
  145. package/dist/ui/stores/transcript-scroll-store.test.d.ts +2 -0
  146. package/dist/ui/stores/transcript-scroll-store.test.d.ts.map +1 -0
  147. package/dist/ui/stores/transcript-scroll-store.test.js +73 -0
  148. package/dist/ui/stores/transcript-scroll-store.test.js.map +1 -0
  149. package/dist/ui/testing/screen-recorder.d.ts +29 -0
  150. package/dist/ui/testing/screen-recorder.d.ts.map +1 -0
  151. package/dist/ui/testing/screen-recorder.js +179 -0
  152. package/dist/ui/testing/screen-recorder.js.map +1 -0
  153. package/dist/ui/transcript/TranscriptRenderer.d.ts.map +1 -1
  154. package/dist/ui/transcript/TranscriptRenderer.js +1 -1
  155. package/dist/ui/transcript/TranscriptRenderer.js.map +1 -1
  156. package/dist/ui/transcript/spacing.d.ts +1 -0
  157. package/dist/ui/transcript/spacing.d.ts.map +1 -1
  158. package/dist/ui/transcript/spacing.js +7 -0
  159. package/dist/ui/transcript/spacing.js.map +1 -1
  160. package/dist/ui/transcript/spacing.test.js +29 -0
  161. package/dist/ui/transcript/spacing.test.js.map +1 -1
  162. package/dist/ui/transcript/transcript-lines.d.ts +32 -0
  163. package/dist/ui/transcript/transcript-lines.d.ts.map +1 -0
  164. package/dist/ui/transcript/transcript-lines.js +82 -0
  165. package/dist/ui/transcript/transcript-lines.js.map +1 -0
  166. package/dist/ui/transcript/transcript-lines.test.d.ts +2 -0
  167. package/dist/ui/transcript/transcript-lines.test.d.ts.map +1 -0
  168. package/dist/ui/transcript/transcript-lines.test.js +76 -0
  169. package/dist/ui/transcript/transcript-lines.test.js.map +1 -0
  170. package/dist/ui/transcript-viewport-pinning.test.d.ts +2 -0
  171. package/dist/ui/transcript-viewport-pinning.test.d.ts.map +1 -0
  172. package/dist/ui/transcript-viewport-pinning.test.js +148 -0
  173. package/dist/ui/transcript-viewport-pinning.test.js.map +1 -0
  174. package/dist/ui/tui-simulation.test.d.ts +2 -0
  175. package/dist/ui/tui-simulation.test.d.ts.map +1 -0
  176. package/dist/ui/tui-simulation.test.js +138 -0
  177. package/dist/ui/tui-simulation.test.js.map +1 -0
  178. package/dist/ui/tui-terminal-recorder.test.d.ts +2 -0
  179. package/dist/ui/tui-terminal-recorder.test.d.ts.map +1 -0
  180. package/dist/ui/tui-terminal-recorder.test.js +134 -0
  181. package/dist/ui/tui-terminal-recorder.test.js.map +1 -0
  182. package/package.json +5 -5
@@ -0,0 +1,369 @@
1
+ import { afterEach, describe, expect, it } from "vitest";
2
+ import { execFile } from "node:child_process";
3
+ import fs from "node:fs/promises";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ import { promisify } from "node:util";
7
+ import { confirmAndCommitMainIntegration, integrableWorktreeTasks, discardStagedIntegration, fileMatchesScope, finalizeStagedIntegration, stageGoalIntegration, } from "./goal-integration.js";
8
+ import { commitGoalWorkerCandidate, createGoalWorkerWorktree } from "./goal-worktree.js";
9
+ const execFileAsync = promisify(execFile);
10
+ function goalRun(overrides = {}) {
11
+ return {
12
+ id: "goal-int",
13
+ title: "Integrate candidates",
14
+ goal: "Apply accepted worktree candidates to main deterministically",
15
+ status: "ready",
16
+ createdAt: "2024-01-01T00:00:00.000Z",
17
+ updatedAt: "2024-01-01T00:00:00.000Z",
18
+ projectPath: "/main",
19
+ successCriteria: [],
20
+ prerequisites: [],
21
+ harness: [],
22
+ evidencePlan: [],
23
+ tasks: [],
24
+ evidence: [],
25
+ blockers: [],
26
+ ...overrides,
27
+ };
28
+ }
29
+ function candidateTask(overrides = {}) {
30
+ return {
31
+ id: "task-a",
32
+ title: "Implement core change",
33
+ prompt: "Do work",
34
+ status: "done",
35
+ attempts: 1,
36
+ integration: "candidate",
37
+ expectedChangedScope: ["packages/ggcoder/src/core/**"],
38
+ worktree: {
39
+ baseRef: "base",
40
+ branchName: "goal/goal-int/task-a",
41
+ path: "/wt-a",
42
+ status: "created",
43
+ },
44
+ candidate: {
45
+ baseRef: "base",
46
+ headSha: "cand-sha",
47
+ branchName: "goal/goal-int/task-a",
48
+ changedFiles: ["packages/ggcoder/src/core/foo.ts"],
49
+ committed: true,
50
+ },
51
+ ...overrides,
52
+ };
53
+ }
54
+ function makeRunner(handler) {
55
+ const calls = [];
56
+ const runner = {
57
+ async execFile(_file, args, opts) {
58
+ const call = { cwd: opts.cwd, args: [...args] };
59
+ calls.push(call);
60
+ const out = handler(call);
61
+ if (out instanceof Error)
62
+ throw out;
63
+ return { stdout: out, stderr: "" };
64
+ },
65
+ };
66
+ return { runner, calls };
67
+ }
68
+ describe("goal staged integration", () => {
69
+ afterEach(() => {
70
+ delete process.env.GG_GOAL_AUTO_INTEGRATE;
71
+ });
72
+ it("matches expected_changed_scope globs conservatively", () => {
73
+ expect(fileMatchesScope("packages/ggcoder/src/core/x.ts", ["packages/ggcoder/src/core/**"])).toBe(true);
74
+ expect(fileMatchesScope("packages/ggcoder/src/ui/x.ts", ["packages/ggcoder/src/core/**"])).toBe(false);
75
+ expect(fileMatchesScope("src/a.ts", ["src/*.ts"])).toBe(true);
76
+ expect(fileMatchesScope("src/nested/a.ts", ["src/*.ts"])).toBe(false);
77
+ });
78
+ it("integrates every non-manual worktree candidate", () => {
79
+ const run = goalRun({
80
+ tasks: [
81
+ candidateTask({ id: "after-dep" }),
82
+ candidateTask({ id: "parallel", integration: "candidate" }),
83
+ candidateTask({ id: "serial", integration: "candidate" }),
84
+ candidateTask({ id: "pending", status: "pending" }),
85
+ candidateTask({ id: "manual", integration: "manual" }),
86
+ candidateTask({ id: "no-wt", worktree: undefined }),
87
+ // Read-only task (e.g. audit): worktree but no candidate changes -> excluded.
88
+ candidateTask({ id: "readonly", candidate: undefined }),
89
+ ],
90
+ });
91
+ expect(integrableWorktreeTasks(run)
92
+ .map((t) => t.id)
93
+ .sort()).toEqual(["after-dep", "parallel", "serial"]);
94
+ });
95
+ it("stages an eligible typed candidate on a throwaway branch without touching main", () => {
96
+ const { runner, calls } = makeRunner(({ args }) => {
97
+ if (args[0] === "status")
98
+ return ""; // main clean
99
+ if (args[0] === "rev-parse")
100
+ return "mainbase";
101
+ if (args.includes("cherry-pick"))
102
+ return "";
103
+ return "";
104
+ });
105
+ return stageGoalIntegration({
106
+ projectPath: "/main",
107
+ run: goalRun({ tasks: [candidateTask()] }),
108
+ stagingRoot: "/stage",
109
+ commandRunner: runner,
110
+ }).then((out) => {
111
+ expect(out).toMatchObject({
112
+ status: "staged",
113
+ stagingBranch: "goal/goal-int/integration",
114
+ mainBase: "mainbase",
115
+ integratedTaskIds: ["task-a"],
116
+ changedFiles: ["packages/ggcoder/src/core/foo.ts"],
117
+ });
118
+ // Built a staging worktree and cherry-picked there; main never modified.
119
+ expect(calls.some((c) => c.args[0] === "worktree" && c.args[1] === "add")).toBe(true);
120
+ expect(calls.some((c) => c.args.includes("cherry-pick"))).toBe(true);
121
+ expect(calls.some((c) => c.args[0] === "merge")).toBe(false);
122
+ // No archaeology on the candidate worktree (typed packet used).
123
+ expect(calls.some((c) => c.cwd === "/wt-a")).toBe(false);
124
+ });
125
+ });
126
+ it("falls back when the main checkout is dirty", async () => {
127
+ const { runner, calls } = makeRunner(({ args }) => args[0] === "status" ? " M packages/ggcoder/src/core/foo.ts" : "");
128
+ const out = await stageGoalIntegration({
129
+ projectPath: "/main",
130
+ run: goalRun({ tasks: [candidateTask()] }),
131
+ commandRunner: runner,
132
+ });
133
+ expect(out.status).toBe("fallback");
134
+ expect(calls.some((c) => c.args[0] === "worktree" && c.args[1] === "add")).toBe(false);
135
+ });
136
+ it("falls back when a candidate changes files outside its scope", async () => {
137
+ const { runner } = makeRunner(({ args }) => (args[0] === "rev-parse" ? "mainbase" : ""));
138
+ const out = await stageGoalIntegration({
139
+ projectPath: "/main",
140
+ run: goalRun({
141
+ tasks: [candidateTask({ expectedChangedScope: ["packages/ggcoder/src/ui/**"] })],
142
+ }),
143
+ commandRunner: runner,
144
+ });
145
+ expect(out.status).toBe("fallback");
146
+ expect(out.status === "fallback" && out.reason).toContain("outside expected_changed_scope");
147
+ });
148
+ it("falls back when a candidate has no expected_changed_scope", async () => {
149
+ const { runner } = makeRunner(() => "");
150
+ const out = await stageGoalIntegration({
151
+ projectPath: "/main",
152
+ run: goalRun({ tasks: [candidateTask({ expectedChangedScope: [] })] }),
153
+ commandRunner: runner,
154
+ });
155
+ expect(out.status).toBe("fallback");
156
+ });
157
+ it("falls back when candidates overlap on the same file", async () => {
158
+ const { runner } = makeRunner(({ args }) => (args[0] === "rev-parse" ? "mainbase" : ""));
159
+ const out = await stageGoalIntegration({
160
+ projectPath: "/main",
161
+ run: goalRun({
162
+ tasks: [
163
+ candidateTask({ id: "task-a" }),
164
+ candidateTask({
165
+ id: "task-b",
166
+ worktree: { baseRef: "base", branchName: "b-b", path: "/wt-b", status: "created" },
167
+ candidate: {
168
+ baseRef: "base",
169
+ headSha: "cand-b",
170
+ branchName: "b-b",
171
+ changedFiles: ["packages/ggcoder/src/core/foo.ts"],
172
+ committed: true,
173
+ },
174
+ }),
175
+ ],
176
+ }),
177
+ commandRunner: runner,
178
+ });
179
+ expect(out.status).toBe("fallback");
180
+ expect(out.status === "fallback" && out.reason).toContain("overlap");
181
+ });
182
+ it("aborts and cleans up staging on a cherry-pick conflict", async () => {
183
+ const { runner, calls } = makeRunner(({ args }) => {
184
+ if (args[0] === "status")
185
+ return "";
186
+ if (args[0] === "rev-parse")
187
+ return "mainbase";
188
+ if (args.includes("cherry-pick") && !args.includes("--abort"))
189
+ return new Error("CONFLICT");
190
+ return "";
191
+ });
192
+ const out = await stageGoalIntegration({
193
+ projectPath: "/main",
194
+ run: goalRun({ tasks: [candidateTask()] }),
195
+ stagingRoot: "/stage",
196
+ commandRunner: runner,
197
+ });
198
+ expect(out.status).toBe("fallback");
199
+ expect(calls.some((c) => c.args.includes("cherry-pick") && c.args.includes("--abort"))).toBe(true);
200
+ expect(calls.some((c) => c.args[0] === "worktree" && c.args[1] === "remove")).toBe(true);
201
+ });
202
+ it("is a noop when there are no candidate worktree tasks", async () => {
203
+ const { runner, calls } = makeRunner(() => "");
204
+ const out = await stageGoalIntegration({
205
+ projectPath: "/main",
206
+ run: goalRun({ tasks: [candidateTask({ integration: "manual" })] }),
207
+ commandRunner: runner,
208
+ });
209
+ expect(out.status).toBe("noop");
210
+ expect(calls).toHaveLength(0);
211
+ });
212
+ it("is disabled via GG_GOAL_AUTO_INTEGRATE=0", async () => {
213
+ process.env.GG_GOAL_AUTO_INTEGRATE = "0";
214
+ const { runner, calls } = makeRunner(() => "");
215
+ const out = await stageGoalIntegration({
216
+ projectPath: "/main",
217
+ run: goalRun({ tasks: [candidateTask()] }),
218
+ commandRunner: runner,
219
+ });
220
+ expect(out.status).toBe("fallback");
221
+ expect(out.status === "fallback" && out.reason).toContain("GG_GOAL_AUTO_INTEGRATE=0");
222
+ expect(calls).toHaveLength(0);
223
+ });
224
+ });
225
+ describe("goal staged integration (real git)", () => {
226
+ let tmp;
227
+ let main;
228
+ async function git(cwd, args) {
229
+ const { stdout } = await execFileAsync("git", args, { cwd });
230
+ return stdout.trim();
231
+ }
232
+ async function setupRepoWithCandidate() {
233
+ tmp = await fs.mkdtemp(path.join(os.tmpdir(), "goal-staged-real-"));
234
+ main = path.join(tmp, "main");
235
+ await fs.mkdir(main, { recursive: true });
236
+ await git(main, ["init", "-b", "main"]);
237
+ await git(main, ["config", "user.email", "goal@test.local"]);
238
+ await git(main, ["config", "user.name", "Goal Test"]);
239
+ await fs.mkdir(path.join(main, "src"), { recursive: true });
240
+ await fs.writeFile(path.join(main, "src/app.ts"), "export const v = 1;\n", "utf-8");
241
+ await git(main, ["add", "-A"]);
242
+ await git(main, ["commit", "-m", "base"]);
243
+ const baseRef = await git(main, ["rev-parse", "HEAD"]);
244
+ const worktree = await createGoalWorkerWorktree({
245
+ projectPath: main,
246
+ goalRunId: "goal-real",
247
+ goalTaskId: "task-a",
248
+ workerId: "w1",
249
+ baseRef,
250
+ worktreesRoot: path.join(tmp, "worktrees"),
251
+ });
252
+ await fs.writeFile(path.join(worktree.path, "src/app.ts"), "export const v = 2;\n", "utf-8");
253
+ const candidate = await commitGoalWorkerCandidate({
254
+ worktreePath: worktree.path,
255
+ branchName: worktree.branchName,
256
+ baseRef: worktree.baseRef,
257
+ message: "goal(goal-real): candidate task-a",
258
+ });
259
+ const run = goalRun({
260
+ id: "goal-real",
261
+ projectPath: main,
262
+ tasks: [
263
+ candidateTask({
264
+ id: "task-a",
265
+ expectedChangedScope: ["src/**"],
266
+ worktree: {
267
+ baseRef,
268
+ branchName: worktree.branchName,
269
+ path: worktree.path,
270
+ status: "created",
271
+ },
272
+ ...(candidate ? { candidate } : {}),
273
+ }),
274
+ ],
275
+ });
276
+ const staging = await stageGoalIntegration({
277
+ projectPath: main,
278
+ run,
279
+ stagingRoot: path.join(tmp, "staging"),
280
+ });
281
+ return { baseRef, run, staging };
282
+ }
283
+ afterEach(async () => {
284
+ if (tmp)
285
+ await fs.rm(tmp, { recursive: true, force: true });
286
+ });
287
+ it("stages, verifies-then-fast-forwards main only on success", async () => {
288
+ const { baseRef, staging } = await setupRepoWithCandidate();
289
+ expect(staging.status).toBe("staged");
290
+ // Staging built; main NOT yet advanced.
291
+ expect(await git(main, ["rev-parse", "HEAD"])).toBe(baseRef);
292
+ expect(await fs.readFile(path.join(main, "src/app.ts"), "utf-8")).toBe("export const v = 1;\n");
293
+ if (staging.status !== "staged")
294
+ throw new Error("expected staged");
295
+ const { commitSha } = await finalizeStagedIntegration({ projectPath: main, staging });
296
+ // After a green fast-forward, main holds the verified change.
297
+ expect(await git(main, ["rev-parse", "HEAD"])).toBe(commitSha);
298
+ expect(commitSha).not.toBe(baseRef);
299
+ expect(await fs.readFile(path.join(main, "src/app.ts"), "utf-8")).toBe("export const v = 2;\n");
300
+ // Staging branch is cleaned up.
301
+ expect(await git(main, ["branch", "--list", staging.stagingBranch])).toBe("");
302
+ });
303
+ it("discards the staging and leaves main untouched on failure", async () => {
304
+ const { baseRef, staging } = await setupRepoWithCandidate();
305
+ expect(staging.status).toBe("staged");
306
+ if (staging.status !== "staged")
307
+ throw new Error("expected staged");
308
+ await discardStagedIntegration({ projectPath: main, staging });
309
+ // Main is exactly where it started; no unverified changes leaked in.
310
+ expect(await git(main, ["rev-parse", "HEAD"])).toBe(baseRef);
311
+ expect(await fs.readFile(path.join(main, "src/app.ts"), "utf-8")).toBe("export const v = 1;\n");
312
+ expect(await git(main, ["branch", "--list", staging.stagingBranch])).toBe("");
313
+ });
314
+ async function freshRepo() {
315
+ tmp = await fs.mkdtemp(path.join(os.tmpdir(), "goal-confirm-real-"));
316
+ main = path.join(tmp, "main");
317
+ await fs.mkdir(main, { recursive: true });
318
+ await git(main, ["init", "-b", "main"]);
319
+ await git(main, ["config", "user.email", "e2e@test.local"]);
320
+ await git(main, ["config", "user.name", "E2E"]);
321
+ await fs.writeFile(path.join(main, "a.txt"), "v1\n", "utf-8");
322
+ await git(main, ["add", "-A"]);
323
+ await git(main, ["commit", "-m", "base"]);
324
+ return git(main, ["rev-parse", "HEAD"]);
325
+ }
326
+ it("commits an apply worker's uncommitted changes and confirms main advanced", async () => {
327
+ const baseRef = await freshRepo();
328
+ // Simulate an LLM apply worker that edited main but did NOT commit.
329
+ await fs.writeFile(path.join(main, "a.txt"), "v2\n", "utf-8");
330
+ const result = await confirmAndCommitMainIntegration({
331
+ projectPath: main,
332
+ baseRef,
333
+ message: "goal(g): commit integrated changes",
334
+ });
335
+ expect(result.applied).toBe(true);
336
+ expect(result.committed).toBe(true);
337
+ expect(result.files).toEqual(["a.txt"]);
338
+ expect(result.sha).not.toBe(baseRef);
339
+ // Main is now clean and committed.
340
+ expect(await git(main, ["status", "--porcelain"])).toBe("");
341
+ expect(await git(main, ["rev-parse", "HEAD"])).toBe(result.sha);
342
+ });
343
+ it("confirms applied when the apply worker already committed (nothing to commit)", async () => {
344
+ const baseRef = await freshRepo();
345
+ await fs.writeFile(path.join(main, "a.txt"), "v2\n", "utf-8");
346
+ await git(main, ["add", "-A"]);
347
+ await git(main, ["commit", "-m", "worker already committed"]);
348
+ const result = await confirmAndCommitMainIntegration({
349
+ projectPath: main,
350
+ baseRef,
351
+ message: "goal(g): commit integrated changes",
352
+ });
353
+ expect(result.applied).toBe(true);
354
+ expect(result.committed).toBe(false); // nothing left to commit
355
+ expect(result.files).toEqual(["a.txt"]);
356
+ });
357
+ it("reports not-applied when main is unchanged versus the base", async () => {
358
+ const baseRef = await freshRepo();
359
+ const result = await confirmAndCommitMainIntegration({
360
+ projectPath: main,
361
+ baseRef,
362
+ message: "goal(g): commit integrated changes",
363
+ });
364
+ expect(result.applied).toBe(false);
365
+ expect(result.committed).toBe(false);
366
+ expect(result.files).toEqual([]);
367
+ });
368
+ });
369
+ //# sourceMappingURL=goal-integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goal-integration.test.js","sourceRoot":"","sources":["../../src/core/goal-integration.test.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
2
2
  import fs from "node:fs/promises";
3
3
  import os from "node:os";
4
4
  import path from "node:path";
5
+ import { goalHasBlockingPrerequisites, goalHasUnmetLocalPrerequisites, isBlockingGoalPrerequisite, prerequisiteKind, } from "./goal-store.js";
5
6
  import { runGoalPrerequisiteCheckCommand, runGoalPrerequisiteChecks, shouldRunGoalPrerequisiteCheck, validateGoalPrerequisiteCheckCommand, } from "./goal-prerequisites.js";
6
7
  function goalRun(overrides = {}) {
7
8
  return {
@@ -87,12 +88,46 @@ describe("goal prerequisite checks", () => {
87
88
  checkCommand: "true",
88
89
  })).toBe(true);
89
90
  });
91
+ it("infers prerequisite kind and keeps explicit kind", () => {
92
+ expect(prerequisiteKind({ id: "a", label: "a", status: "unknown", checkCommand: "true" })).toBe("local");
93
+ expect(prerequisiteKind({ id: "b", label: "b", status: "unknown" })).toBe("external");
94
+ expect(prerequisiteKind({
95
+ id: "c",
96
+ label: "c",
97
+ status: "unknown",
98
+ kind: "external",
99
+ checkCommand: "true",
100
+ })).toBe("external");
101
+ expect(prerequisiteKind({ id: "d", label: "d", status: "unknown", kind: "local" })).toBe("local");
102
+ });
103
+ it("local unmet prerequisites do not block; external unmet ones do", () => {
104
+ const localPrereq = {
105
+ id: "node",
106
+ label: "Node",
107
+ status: "missing",
108
+ checkCommand: "node --version",
109
+ };
110
+ const externalPrereq = { id: "key", label: "API key", status: "missing" };
111
+ expect(isBlockingGoalPrerequisite(localPrereq)).toBe(false);
112
+ expect(isBlockingGoalPrerequisite(externalPrereq)).toBe(true);
113
+ const localOnly = goalRun({ prerequisites: [localPrereq] });
114
+ expect(goalHasBlockingPrerequisites(localOnly)).toBe(false);
115
+ expect(goalHasUnmetLocalPrerequisites(localOnly)).toBe(true);
116
+ const withExternal = goalRun({ prerequisites: [localPrereq, externalPrereq] });
117
+ expect(goalHasBlockingPrerequisites(withExternal)).toBe(true);
118
+ });
90
119
  it("updates a Goal run with checked prerequisite statuses before workers start", async () => {
91
120
  const tmpProject = await fs.mkdtemp(path.join(os.tmpdir(), "goal-prereq-test-project-"));
92
121
  try {
93
122
  const result = await runGoalPrerequisiteChecks(tmpProject, goalRun({
94
123
  prerequisites: [
95
- { id: "pass", label: "Passing check", status: "unknown", checkCommand: "true" },
124
+ {
125
+ id: "pass",
126
+ label: "Passing check",
127
+ status: "unknown",
128
+ kind: "local",
129
+ checkCommand: "true",
130
+ },
96
131
  { id: "fail", label: "Failing check", status: "unknown", checkCommand: "false" },
97
132
  ],
98
133
  }));
@@ -101,6 +136,7 @@ describe("goal prerequisite checks", () => {
101
136
  expect.objectContaining({
102
137
  id: "pass",
103
138
  status: "met",
139
+ kind: "local",
104
140
  evidence: expect.stringContaining("exited 0"),
105
141
  }),
106
142
  expect.objectContaining({
@@ -1 +1 @@
1
- {"version":3,"file":"goal-prerequisites.test.js","sourceRoot":"","sources":["../../src/core/goal-prerequisites.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"goal-prerequisites.test.js","sourceRoot":"","sources":["../../src/core/goal-prerequisites.test.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,32 @@
1
1
  import type { GoalControllerDecision } from "./goal-controller.js";
2
2
  export type GoalRunStatus = "draft" | "blocked" | "ready" | "running" | "verifying" | "passed" | "failed" | "paused";
3
3
  export type GoalTaskStatus = "pending" | "running" | "verifying" | "done" | "failed" | "blocked";
4
+ /**
5
+ * Whether a task's committed candidate is auto-integrated into main
6
+ * (`candidate`) or left for manual handling (`manual`). Ordering is expressed by
7
+ * `dependsOn`, not this axis.
8
+ */
9
+ export type GoalTaskIntegration = "candidate" | "manual";
10
+ /**
11
+ * @deprecated Legacy four-way axis. Inputs are folded to {@link GoalTaskIntegration}
12
+ * on normalize: `manual` → `manual`; everything else → `candidate`.
13
+ */
4
14
  export type GoalTaskMergeStrategy = "parallel_candidate" | "after_dependencies" | "serial" | "manual";
15
+ export declare function foldGoalTaskIntegration(value: GoalTaskIntegration | GoalTaskMergeStrategy | undefined): GoalTaskIntegration;
16
+ export type GoalIntegrationStatus = "none" | "applied" | "committed";
17
+ export interface GoalIntegrationState {
18
+ status: GoalIntegrationStatus;
19
+ /** main HEAD after integration. */
20
+ headSha?: string;
21
+ /** integration base the candidates branched from. */
22
+ baseRef?: string;
23
+ /** integrated file paths (for the journal/diagnosis). */
24
+ files?: string[];
25
+ /** ISO; injected clock, never Date.now() inline in pure code. */
26
+ updatedAt: string;
27
+ }
5
28
  export type GoalPrerequisiteStatus = "unknown" | "met" | "missing";
29
+ export type GoalPrerequisiteKind = "local" | "external";
6
30
  export type GoalEvidenceKind = "log" | "command" | "screenshot" | "file" | "summary";
7
31
  export type GoalVerificationStatus = "pass" | "fail" | "unknown";
8
32
  export interface GoalVerificationResult {
@@ -24,6 +48,12 @@ export interface GoalPrerequisite {
24
48
  id: string;
25
49
  label: string;
26
50
  status: GoalPrerequisiteStatus;
51
+ /**
52
+ * Whether the agent can satisfy this prerequisite locally ("local") or it
53
+ * genuinely requires user-supplied external input ("external"). When omitted,
54
+ * {@link prerequisiteKind} infers it: a runnable checkCommand implies local.
55
+ */
56
+ kind?: GoalPrerequisiteKind;
27
57
  checkCommand?: string;
28
58
  instructions?: string;
29
59
  evidence?: string;
@@ -66,6 +96,18 @@ export interface GoalTaskWorktree {
66
96
  status: "planned" | "created" | "failed";
67
97
  error?: string;
68
98
  }
99
+ /**
100
+ * Structured, committed candidate packet produced by a worktree worker. Lets
101
+ * integration read exactly what changed (committed commit + changed files)
102
+ * instead of reverse-engineering a dirty worktree.
103
+ */
104
+ export interface GoalTaskCandidate {
105
+ baseRef: string;
106
+ headSha: string;
107
+ branchName: string;
108
+ changedFiles: string[];
109
+ committed: boolean;
110
+ }
69
111
  export interface GoalTask {
70
112
  id: string;
71
113
  title: string;
@@ -76,8 +118,9 @@ export interface GoalTask {
76
118
  dependsOn?: string[];
77
119
  parallelGroup?: string;
78
120
  expectedChangedScope?: string[];
79
- mergeStrategy?: GoalTaskMergeStrategy;
121
+ integration?: GoalTaskIntegration;
80
122
  worktree?: GoalTaskWorktree;
123
+ candidate?: GoalTaskCandidate;
81
124
  verification?: GoalVerificationResult;
82
125
  lastSummary?: string;
83
126
  }
@@ -112,6 +155,13 @@ export interface GoalRun {
112
155
  evidence: GoalEvidence[];
113
156
  verifier?: GoalVerifier;
114
157
  completionAudit?: GoalCompletionAudit;
158
+ integration?: GoalIntegrationState;
159
+ /**
160
+ * ISO time of the most recent NON-audit, NON-integration worker completion.
161
+ * Drives verifier/audit staleness deterministically (replaces the
162
+ * "Worker ... after verifier" evidence scans).
163
+ */
164
+ lastSubstantiveWorkerAt?: string;
115
165
  blockers: string[];
116
166
  activeWorkerId?: string;
117
167
  continueRequestedAt?: string;
@@ -148,6 +198,8 @@ export interface GoalRunInput {
148
198
  evidence?: GoalEvidence[];
149
199
  verifier?: GoalVerifier;
150
200
  completionAudit?: GoalCompletionAudit;
201
+ integration?: GoalIntegrationState;
202
+ lastSubstantiveWorkerAt?: string;
151
203
  blockers?: string[];
152
204
  activeWorkerId?: string;
153
205
  continueRequestedAt?: string;
@@ -162,8 +214,11 @@ export interface GoalTaskInput {
162
214
  dependsOn?: string[];
163
215
  parallelGroup?: string;
164
216
  expectedChangedScope?: string[];
217
+ integration?: GoalTaskIntegration;
218
+ /** @deprecated legacy input; folded to {@link integration} on normalize. */
165
219
  mergeStrategy?: GoalTaskMergeStrategy;
166
220
  worktree?: GoalTaskWorktree;
221
+ candidate?: GoalTaskCandidate;
167
222
  verification?: GoalVerificationResult;
168
223
  lastSummary?: string;
169
224
  }
@@ -198,7 +253,31 @@ export declare function appendGoalDecision(cwd: string, runId: string, decision:
198
253
  }): Promise<GoalRun | null>;
199
254
  export declare function appendGoalEvidence(cwd: string, runId: string, input: GoalEvidenceInput): Promise<GoalRun | null>;
200
255
  export declare function updateGoalTask(cwd: string, runId: string, taskId: string, patch: Partial<GoalTask> | GoalTaskInput): Promise<GoalRun | null>;
256
+ /**
257
+ * Record the typed integration state from code (git truth), so the controller
258
+ * never has to parse evidence labels to know whether candidates reached main.
259
+ */
260
+ export declare function setGoalIntegrationState(cwd: string, runId: string, state: GoalIntegrationState): Promise<GoalRun | null>;
261
+ /**
262
+ * Stamp the most recent substantive (non-audit, non-integration) worker
263
+ * completion time, driving verifier/audit staleness deterministically.
264
+ */
265
+ export declare function recordGoalSubstantiveWorker(cwd: string, runId: string, atIso: string): Promise<GoalRun | null>;
266
+ /**
267
+ * Infer whether a prerequisite is locally resolvable by the agent or genuinely
268
+ * external (user-supplied). An explicit `kind` wins; otherwise a runnable
269
+ * `checkCommand` implies the agent can both check and satisfy it locally.
270
+ */
271
+ export declare function prerequisiteKind(item: GoalPrerequisite): GoalPrerequisiteKind;
272
+ /**
273
+ * Local unmet prerequisites no longer block the Goal — the controller schedules
274
+ * a worker task to resolve them. Only unmet **external** prerequisites (true
275
+ * user-supplied inputs) are blocking.
276
+ */
201
277
  export declare function isBlockingGoalPrerequisite(item: GoalPrerequisite): boolean;
278
+ export declare function isUnmetLocalGoalPrerequisite(item: GoalPrerequisite): boolean;
279
+ export declare function unmetLocalGoalPrerequisites(run: GoalRun): GoalPrerequisite[];
280
+ export declare function goalHasUnmetLocalPrerequisites(run: GoalRun): boolean;
202
281
  export declare function hasBlockingGoalPrerequisites(prerequisites: readonly GoalPrerequisite[]): boolean;
203
282
  export declare function goalHasBlockingPrerequisites(run: GoalRun): boolean;
204
283
  export declare function formatGoalPrerequisiteInstruction(item: GoalPrerequisite): string;