sweteam 0.1.0

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 (206) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +587 -0
  3. package/dist/adapters/adapter.d.ts +19 -0
  4. package/dist/adapters/adapter.d.ts.map +1 -0
  5. package/dist/adapters/adapter.js +20 -0
  6. package/dist/adapters/adapter.js.map +1 -0
  7. package/dist/adapters/claude-code.d.ts +13 -0
  8. package/dist/adapters/claude-code.d.ts.map +1 -0
  9. package/dist/adapters/claude-code.js +150 -0
  10. package/dist/adapters/claude-code.js.map +1 -0
  11. package/dist/adapters/codex.d.ts +13 -0
  12. package/dist/adapters/codex.d.ts.map +1 -0
  13. package/dist/adapters/codex.js +100 -0
  14. package/dist/adapters/codex.js.map +1 -0
  15. package/dist/adapters/custom.d.ts +16 -0
  16. package/dist/adapters/custom.d.ts.map +1 -0
  17. package/dist/adapters/custom.js +167 -0
  18. package/dist/adapters/custom.js.map +1 -0
  19. package/dist/adapters/opencode.d.ts +13 -0
  20. package/dist/adapters/opencode.d.ts.map +1 -0
  21. package/dist/adapters/opencode.js +100 -0
  22. package/dist/adapters/opencode.js.map +1 -0
  23. package/dist/adapters/prompt-detection.d.ts +14 -0
  24. package/dist/adapters/prompt-detection.d.ts.map +1 -0
  25. package/dist/adapters/prompt-detection.js +74 -0
  26. package/dist/adapters/prompt-detection.js.map +1 -0
  27. package/dist/commands/create.d.ts +8 -0
  28. package/dist/commands/create.d.ts.map +1 -0
  29. package/dist/commands/create.js +38 -0
  30. package/dist/commands/create.js.map +1 -0
  31. package/dist/commands/delete.d.ts +2 -0
  32. package/dist/commands/delete.d.ts.map +1 -0
  33. package/dist/commands/delete.js +22 -0
  34. package/dist/commands/delete.js.map +1 -0
  35. package/dist/commands/enter.d.ts +19 -0
  36. package/dist/commands/enter.d.ts.map +1 -0
  37. package/dist/commands/enter.js +73 -0
  38. package/dist/commands/enter.js.map +1 -0
  39. package/dist/commands/init.d.ts +14 -0
  40. package/dist/commands/init.d.ts.map +1 -0
  41. package/dist/commands/init.js +52 -0
  42. package/dist/commands/init.js.map +1 -0
  43. package/dist/commands/list.d.ts +8 -0
  44. package/dist/commands/list.d.ts.map +1 -0
  45. package/dist/commands/list.js +98 -0
  46. package/dist/commands/list.js.map +1 -0
  47. package/dist/commands/show.d.ts +33 -0
  48. package/dist/commands/show.d.ts.map +1 -0
  49. package/dist/commands/show.js +142 -0
  50. package/dist/commands/show.js.map +1 -0
  51. package/dist/commands/stop.d.ts +2 -0
  52. package/dist/commands/stop.d.ts.map +1 -0
  53. package/dist/commands/stop.js +10 -0
  54. package/dist/commands/stop.js.map +1 -0
  55. package/dist/config/discovery.d.ts +12 -0
  56. package/dist/config/discovery.d.ts.map +1 -0
  57. package/dist/config/discovery.js +62 -0
  58. package/dist/config/discovery.js.map +1 -0
  59. package/dist/config/gh-auth.d.ts +5 -0
  60. package/dist/config/gh-auth.d.ts.map +1 -0
  61. package/dist/config/gh-auth.js +18 -0
  62. package/dist/config/gh-auth.js.map +1 -0
  63. package/dist/config/loader.d.ts +38 -0
  64. package/dist/config/loader.d.ts.map +1 -0
  65. package/dist/config/loader.js +72 -0
  66. package/dist/config/loader.js.map +1 -0
  67. package/dist/db/client.d.ts +10 -0
  68. package/dist/db/client.d.ts.map +1 -0
  69. package/dist/db/client.js +84 -0
  70. package/dist/db/client.js.map +1 -0
  71. package/dist/db/schema.d.ts +805 -0
  72. package/dist/db/schema.d.ts.map +1 -0
  73. package/dist/db/schema.js +66 -0
  74. package/dist/db/schema.js.map +1 -0
  75. package/dist/git/git.d.ts +29 -0
  76. package/dist/git/git.d.ts.map +1 -0
  77. package/dist/git/git.js +200 -0
  78. package/dist/git/git.js.map +1 -0
  79. package/dist/index.d.ts +3 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +154 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/lifecycle.d.ts +5 -0
  84. package/dist/lifecycle.d.ts.map +1 -0
  85. package/dist/lifecycle.js +63 -0
  86. package/dist/lifecycle.js.map +1 -0
  87. package/dist/orchestrator/build-handler.d.ts +20 -0
  88. package/dist/orchestrator/build-handler.d.ts.map +1 -0
  89. package/dist/orchestrator/build-handler.js +212 -0
  90. package/dist/orchestrator/build-handler.js.map +1 -0
  91. package/dist/orchestrator/dag.d.ts +10 -0
  92. package/dist/orchestrator/dag.d.ts.map +1 -0
  93. package/dist/orchestrator/dag.js +70 -0
  94. package/dist/orchestrator/dag.js.map +1 -0
  95. package/dist/orchestrator/error-handling.d.ts +21 -0
  96. package/dist/orchestrator/error-handling.d.ts.map +1 -0
  97. package/dist/orchestrator/error-handling.js +124 -0
  98. package/dist/orchestrator/error-handling.js.map +1 -0
  99. package/dist/orchestrator/feedback-handler.d.ts +36 -0
  100. package/dist/orchestrator/feedback-handler.d.ts.map +1 -0
  101. package/dist/orchestrator/feedback-handler.js +316 -0
  102. package/dist/orchestrator/feedback-handler.js.map +1 -0
  103. package/dist/orchestrator/orchestrator.d.ts +21 -0
  104. package/dist/orchestrator/orchestrator.d.ts.map +1 -0
  105. package/dist/orchestrator/orchestrator.js +188 -0
  106. package/dist/orchestrator/orchestrator.js.map +1 -0
  107. package/dist/orchestrator/parallel-runner.d.ts +3 -0
  108. package/dist/orchestrator/parallel-runner.d.ts.map +1 -0
  109. package/dist/orchestrator/parallel-runner.js +111 -0
  110. package/dist/orchestrator/parallel-runner.js.map +1 -0
  111. package/dist/orchestrator/reviewer.d.ts +20 -0
  112. package/dist/orchestrator/reviewer.d.ts.map +1 -0
  113. package/dist/orchestrator/reviewer.js +175 -0
  114. package/dist/orchestrator/reviewer.js.map +1 -0
  115. package/dist/orchestrator/task-runner.d.ts +20 -0
  116. package/dist/orchestrator/task-runner.d.ts.map +1 -0
  117. package/dist/orchestrator/task-runner.js +122 -0
  118. package/dist/orchestrator/task-runner.js.map +1 -0
  119. package/dist/orchestrator/test-runner.d.ts +8 -0
  120. package/dist/orchestrator/test-runner.d.ts.map +1 -0
  121. package/dist/orchestrator/test-runner.js +81 -0
  122. package/dist/orchestrator/test-runner.js.map +1 -0
  123. package/dist/planner/plan-parser.d.ts +14 -0
  124. package/dist/planner/plan-parser.d.ts.map +1 -0
  125. package/dist/planner/plan-parser.js +182 -0
  126. package/dist/planner/plan-parser.js.map +1 -0
  127. package/dist/planner/planner.d.ts +9 -0
  128. package/dist/planner/planner.d.ts.map +1 -0
  129. package/dist/planner/planner.js +151 -0
  130. package/dist/planner/planner.js.map +1 -0
  131. package/dist/repl/repl.d.ts +19 -0
  132. package/dist/repl/repl.d.ts.map +1 -0
  133. package/dist/repl/repl.js +505 -0
  134. package/dist/repl/repl.js.map +1 -0
  135. package/dist/session/agent-log.d.ts +35 -0
  136. package/dist/session/agent-log.d.ts.map +1 -0
  137. package/dist/session/agent-log.js +120 -0
  138. package/dist/session/agent-log.js.map +1 -0
  139. package/dist/session/chat.d.ts +38 -0
  140. package/dist/session/chat.d.ts.map +1 -0
  141. package/dist/session/chat.js +106 -0
  142. package/dist/session/chat.js.map +1 -0
  143. package/dist/session/cost-tracker.d.ts +14 -0
  144. package/dist/session/cost-tracker.d.ts.map +1 -0
  145. package/dist/session/cost-tracker.js +61 -0
  146. package/dist/session/cost-tracker.js.map +1 -0
  147. package/dist/session/export.d.ts +2 -0
  148. package/dist/session/export.d.ts.map +1 -0
  149. package/dist/session/export.js +105 -0
  150. package/dist/session/export.js.map +1 -0
  151. package/dist/session/in-session-commands.d.ts +7 -0
  152. package/dist/session/in-session-commands.d.ts.map +1 -0
  153. package/dist/session/in-session-commands.js +227 -0
  154. package/dist/session/in-session-commands.js.map +1 -0
  155. package/dist/session/interactive.d.ts +37 -0
  156. package/dist/session/interactive.d.ts.map +1 -0
  157. package/dist/session/interactive.js +226 -0
  158. package/dist/session/interactive.js.map +1 -0
  159. package/dist/session/manager.d.ts +63 -0
  160. package/dist/session/manager.d.ts.map +1 -0
  161. package/dist/session/manager.js +229 -0
  162. package/dist/session/manager.js.map +1 -0
  163. package/dist/session/resume.d.ts +7 -0
  164. package/dist/session/resume.d.ts.map +1 -0
  165. package/dist/session/resume.js +53 -0
  166. package/dist/session/resume.js.map +1 -0
  167. package/dist/session/state-machine.d.ts +4 -0
  168. package/dist/session/state-machine.d.ts.map +1 -0
  169. package/dist/session/state-machine.js +47 -0
  170. package/dist/session/state-machine.js.map +1 -0
  171. package/dist/tui/chat-ui.d.ts +16 -0
  172. package/dist/tui/chat-ui.d.ts.map +1 -0
  173. package/dist/tui/chat-ui.js +19 -0
  174. package/dist/tui/chat-ui.js.map +1 -0
  175. package/dist/tui/dashboard.d.ts +17 -0
  176. package/dist/tui/dashboard.d.ts.map +1 -0
  177. package/dist/tui/dashboard.js +57 -0
  178. package/dist/tui/dashboard.js.map +1 -0
  179. package/dist/tui/session-list.d.ts +18 -0
  180. package/dist/tui/session-list.d.ts.map +1 -0
  181. package/dist/tui/session-list.js +26 -0
  182. package/dist/tui/session-list.js.map +1 -0
  183. package/dist/ui/agent-panel.d.ts +9 -0
  184. package/dist/ui/agent-panel.d.ts.map +1 -0
  185. package/dist/ui/agent-panel.js +100 -0
  186. package/dist/ui/agent-panel.js.map +1 -0
  187. package/dist/ui/banner.d.ts +10 -0
  188. package/dist/ui/banner.d.ts.map +1 -0
  189. package/dist/ui/banner.js +100 -0
  190. package/dist/ui/banner.js.map +1 -0
  191. package/dist/ui/markdown.d.ts +19 -0
  192. package/dist/ui/markdown.d.ts.map +1 -0
  193. package/dist/ui/markdown.js +174 -0
  194. package/dist/ui/markdown.js.map +1 -0
  195. package/dist/ui/prompt.d.ts +24 -0
  196. package/dist/ui/prompt.d.ts.map +1 -0
  197. package/dist/ui/prompt.js +226 -0
  198. package/dist/ui/prompt.js.map +1 -0
  199. package/dist/utils/time.d.ts +3 -0
  200. package/dist/utils/time.d.ts.map +1 -0
  201. package/dist/utils/time.js +29 -0
  202. package/dist/utils/time.js.map +1 -0
  203. package/drizzle/migrations/0000_naive_human_fly.sql +56 -0
  204. package/drizzle/migrations/meta/0000_snapshot.json +395 -0
  205. package/drizzle/migrations/meta/_journal.json +13 -0
  206. package/package.json +70 -0
@@ -0,0 +1,111 @@
1
+ import { eq } from "drizzle-orm";
2
+ import { getDb } from "../db/client.js";
3
+ import { tasks as tasksTable } from "../db/schema.js";
4
+ import { loadConfig } from "../config/loader.js";
5
+ import { addMessage } from "../session/manager.js";
6
+ import { runTask } from "./task-runner.js";
7
+ import { reviewAndMerge } from "./reviewer.js";
8
+ import { buildDag, getReadyTasks } from "./dag.js";
9
+ import { getTasksForSession, displayTaskId } from "./orchestrator.js";
10
+ // Mutex for serializing merge operations
11
+ let merging = false;
12
+ const mergeQueue = [];
13
+ async function withMergeLock(fn) {
14
+ while (merging) {
15
+ await new Promise((resolve) => mergeQueue.push(resolve));
16
+ }
17
+ merging = true;
18
+ try {
19
+ return await fn();
20
+ }
21
+ finally {
22
+ merging = false;
23
+ const next = mergeQueue.shift();
24
+ if (next)
25
+ next();
26
+ }
27
+ }
28
+ async function runSingleTask(task, sessionBranch, repoPath, sessionId, maxReviewCycles) {
29
+ addMessage(sessionId, "system", `Starting task ${displayTaskId(task.id)}: ${task.title}`);
30
+ const result = await runTask(task, sessionBranch, repoPath);
31
+ if (!result.success) {
32
+ return { taskId: task.id, success: false };
33
+ }
34
+ // Reload task from DB
35
+ const updatedTasks = getTasksForSession(sessionId);
36
+ const updatedTask = updatedTasks.find((t) => t.id === task.id);
37
+ // Serialize merge operations
38
+ const reviewResult = await withMergeLock(async () => {
39
+ return reviewAndMerge(updatedTask, sessionBranch, repoPath, maxReviewCycles);
40
+ });
41
+ if (reviewResult.merged) {
42
+ addMessage(sessionId, "system", `Task ${displayTaskId(task.id)} completed and merged`);
43
+ return { taskId: task.id, success: true };
44
+ }
45
+ return { taskId: task.id, success: false };
46
+ }
47
+ export async function runParallelOrchestrator(sessionId, repoPath, sessionBranch) {
48
+ const config = loadConfig();
49
+ const maxParallel = config.execution.max_parallel;
50
+ const maxReviewCycles = config.execution.max_review_cycles;
51
+ const allTasks = getTasksForSession(sessionId);
52
+ const dag = buildDag(allTasks);
53
+ const completed = new Set();
54
+ const failed = new Set();
55
+ const blocked = new Set();
56
+ const running = new Set();
57
+ // Pre-populate from existing statuses
58
+ for (const task of allTasks) {
59
+ if (task.status === "done")
60
+ completed.add(task.id);
61
+ if (task.status === "failed")
62
+ failed.add(task.id);
63
+ if (task.status === "blocked")
64
+ blocked.add(task.id);
65
+ }
66
+ const taskMap = new Map(allTasks.map((t) => [t.id, t]));
67
+ while (true) {
68
+ const ready = getReadyTasks(dag, completed, running, failed, blocked);
69
+ if (ready.length === 0 && running.size === 0) {
70
+ break;
71
+ }
72
+ // Launch tasks up to max_parallel
73
+ const toLaunch = ready.slice(0, maxParallel - running.size);
74
+ if (toLaunch.length === 0 && running.size > 0) {
75
+ // Wait for any running task to complete
76
+ await new Promise((r) => setTimeout(r, 100));
77
+ continue;
78
+ }
79
+ const promises = toLaunch.map(async (taskId) => {
80
+ running.add(taskId);
81
+ const task = taskMap.get(taskId);
82
+ const result = await runSingleTask(task, sessionBranch, repoPath, sessionId, maxReviewCycles);
83
+ running.delete(taskId);
84
+ if (result.success) {
85
+ completed.add(taskId);
86
+ }
87
+ else {
88
+ failed.add(taskId);
89
+ // Block dependents
90
+ const db = getDb();
91
+ const node = dag.get(taskId);
92
+ if (node) {
93
+ for (const depId of node.dependents) {
94
+ blocked.add(depId);
95
+ db.update(tasksTable)
96
+ .set({ status: "blocked", updatedAt: new Date() })
97
+ .where(eq(tasksTable.id, depId))
98
+ .run();
99
+ }
100
+ }
101
+ }
102
+ });
103
+ await Promise.all(promises);
104
+ }
105
+ return {
106
+ completed: [...completed],
107
+ failed: [...failed],
108
+ blocked: [...blocked],
109
+ };
110
+ }
111
+ //# sourceMappingURL=parallel-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallel-runner.js","sourceRoot":"","sources":["../../src/orchestrator/parallel-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { TaskRecord } from "./task-runner.js";
2
+ export interface ReviewResult {
3
+ verdict: "approve" | "request_changes";
4
+ issues: Array<{
5
+ file?: string;
6
+ line?: number;
7
+ severity?: "error" | "warning";
8
+ message: string;
9
+ }>;
10
+ summary: string;
11
+ }
12
+ export declare function buildReviewerPrompt(task: TaskRecord, diff: string): string;
13
+ export declare function parseReviewResponse(output: string): ReviewResult;
14
+ export declare function reviewTask(task: TaskRecord, diff: string, repoPath: string, onOutput?: (chunk: string) => void, onInputNeeded?: (promptText: string) => Promise<string | null>): Promise<ReviewResult>;
15
+ export declare function mergeTask(task: TaskRecord, sessionBranch: string, repoPath: string): void;
16
+ export declare function reviewAndMerge(task: TaskRecord, sessionBranch: string, repoPath: string, maxCycles?: number, onOutput?: (chunk: string) => void, onInputNeeded?: (promptText: string) => Promise<string | null>): Promise<{
17
+ merged: boolean;
18
+ reviewResult: ReviewResult;
19
+ }>;
20
+ //# sourceMappingURL=reviewer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reviewer.d.ts","sourceRoot":"","sources":["../../src/orchestrator/reviewer.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,SAAS,GAAG,iBAAiB,CAAC;IACvC,MAAM,EAAE,KAAK,CAAC;QACZ,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAC/B,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,MAAM,GACX,MAAM,CA6BR;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAoBhE;AAED,wBAAsB,UAAU,CAC9B,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EAClC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAC7D,OAAO,CAAC,YAAY,CAAC,CAevB;AAED,wBAAgB,SAAS,CACvB,IAAI,EAAE,UAAU,EAChB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,IAAI,CAqBN;AAED,wBAAsB,cAAc,CAClC,IAAI,EAAE,UAAU,EAChB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,MAAU,EACrB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EAClC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAC7D,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,YAAY,CAAA;CAAE,CAAC,CA6F1D"}
@@ -0,0 +1,175 @@
1
+ import { eq } from "drizzle-orm";
2
+ import { getDb } from "../db/client.js";
3
+ import { tasks } from "../db/schema.js";
4
+ import { squashMerge, git } from "../git/git.js";
5
+ import { resolveAdapter } from "../adapters/adapter.js";
6
+ import { loadConfig } from "../config/loader.js";
7
+ import { displayTaskId } from "./orchestrator.js";
8
+ export function buildReviewerPrompt(task, diff) {
9
+ const criteria = task.acceptanceCriteria
10
+ ? JSON.parse(task.acceptanceCriteria)
11
+ .map((c) => `- ${c}`)
12
+ .join("\n")
13
+ : "(none specified)";
14
+ return `You are a senior code reviewer. Review this diff for:
15
+ 1. Correctness — does it meet the acceptance criteria?
16
+ 2. Quality — clean code, no obvious bugs, proper error handling
17
+ 3. Scope — only changes what's needed
18
+
19
+ ## Task
20
+ ${task.title}: ${task.description}
21
+
22
+ ## Acceptance Criteria
23
+ ${criteria}
24
+
25
+ ## Diff
26
+ ${diff}
27
+
28
+ Respond with ONLY valid JSON:
29
+ {
30
+ "verdict": "approve" | "request_changes",
31
+ "issues": [
32
+ { "file": "...", "line": 42, "severity": "error|warning", "message": "..." }
33
+ ],
34
+ "summary": "Overall assessment"
35
+ }`;
36
+ }
37
+ export function parseReviewResponse(output) {
38
+ // Try to extract JSON from response
39
+ const jsonMatch = output.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);
40
+ const jsonStr = jsonMatch ? jsonMatch[1] : output;
41
+ try {
42
+ const parsed = JSON.parse(jsonStr.trim());
43
+ return {
44
+ verdict: parsed.verdict === "approve" ? "approve" : "request_changes",
45
+ issues: Array.isArray(parsed.issues) ? parsed.issues : [],
46
+ summary: String(parsed.summary ?? ""),
47
+ };
48
+ }
49
+ catch {
50
+ // If parsing fails, reject — never auto-approve unreviewed code
51
+ return {
52
+ verdict: "request_changes",
53
+ issues: [{ message: "Review response could not be parsed as valid JSON" }],
54
+ summary: "Review response could not be parsed; requesting changes as a safety measure.",
55
+ };
56
+ }
57
+ }
58
+ export async function reviewTask(task, diff, repoPath, onOutput, onInputNeeded) {
59
+ const config = loadConfig();
60
+ const adapter = resolveAdapter(config.roles.reviewer, config);
61
+ const prompt = buildReviewerPrompt(task, diff);
62
+ const result = await adapter.execute({
63
+ prompt,
64
+ cwd: repoPath,
65
+ timeout: 0,
66
+ onOutput,
67
+ onInputNeeded,
68
+ });
69
+ return parseReviewResponse(result.output);
70
+ }
71
+ export function mergeTask(task, sessionBranch, repoPath) {
72
+ const db = getDb();
73
+ if (!task.branchName) {
74
+ throw new Error(`Task ${task.id} has no branch name`);
75
+ }
76
+ squashMerge(task.branchName, sessionBranch, `feat: ${task.title} (#${displayTaskId(task.id)})`, repoPath);
77
+ db.update(tasks)
78
+ .set({
79
+ status: "done",
80
+ updatedAt: new Date(),
81
+ })
82
+ .where(eq(tasks.id, task.id))
83
+ .run();
84
+ }
85
+ export async function reviewAndMerge(task, sessionBranch, repoPath, maxCycles = 3, onOutput, onInputNeeded) {
86
+ const config = loadConfig();
87
+ const db = getDb();
88
+ for (let cycle = 0; cycle < maxCycles; cycle++) {
89
+ // Always get a fresh diff for this review cycle
90
+ const diff = git(["diff", `${sessionBranch}...${task.branchName}`], repoPath);
91
+ const reviewResult = await reviewTask(task, diff, repoPath, onOutput, onInputNeeded);
92
+ // Update review info in DB
93
+ db.update(tasks)
94
+ .set({
95
+ reviewVerdict: reviewResult.verdict,
96
+ reviewIssues: JSON.stringify(reviewResult.issues),
97
+ reviewCycles: cycle + 1,
98
+ updatedAt: new Date(),
99
+ })
100
+ .where(eq(tasks.id, task.id))
101
+ .run();
102
+ if (reviewResult.verdict === "approve") {
103
+ try {
104
+ mergeTask(task, sessionBranch, repoPath);
105
+ }
106
+ catch (mergeErr) {
107
+ const mergeMsg = mergeErr instanceof Error ? mergeErr.message : String(mergeErr);
108
+ // Attempt to abort a failed merge to restore clean state
109
+ try {
110
+ git(["merge", "--abort"], repoPath);
111
+ }
112
+ catch { /* no merge in progress */ }
113
+ db.update(tasks)
114
+ .set({ status: "failed", agentOutput: `Merge failed: ${mergeMsg}`, updatedAt: new Date() })
115
+ .where(eq(tasks.id, task.id))
116
+ .run();
117
+ return { merged: false, reviewResult: { verdict: "request_changes", issues: [{ message: `Merge failed: ${mergeMsg}` }], summary: mergeMsg } };
118
+ }
119
+ return { merged: true, reviewResult };
120
+ }
121
+ // Request changes — feed issues back to coder
122
+ if (cycle < maxCycles - 1) {
123
+ db.update(tasks)
124
+ .set({ status: "fixing", updatedAt: new Date() })
125
+ .where(eq(tasks.id, task.id))
126
+ .run();
127
+ // Ensure we're on the task branch before invoking the coder for fixes
128
+ if (task.branchName) {
129
+ try {
130
+ git(["checkout", task.branchName], repoPath);
131
+ }
132
+ catch { /* may already be on it */ }
133
+ }
134
+ const coderAdapter = resolveAdapter(config.roles.coder, config);
135
+ const fixPrompt = `The reviewer found issues with your implementation. Fix them:
136
+
137
+ ${reviewResult.issues.map((i) => `- ${i.file ?? ""}:${i.line ?? ""} [${i.severity ?? "error"}] ${i.message}`).join("\n")}
138
+
139
+ Summary: ${reviewResult.summary}`;
140
+ await coderAdapter.execute({
141
+ prompt: fixPrompt,
142
+ cwd: repoPath,
143
+ timeout: 0,
144
+ onOutput,
145
+ onInputNeeded,
146
+ });
147
+ // Re-commit fixes
148
+ try {
149
+ git(["add", "-A"], repoPath);
150
+ git(["commit", "-m", `fix(${displayTaskId(task.id)}): address review feedback (cycle ${cycle + 2})`], repoPath);
151
+ }
152
+ catch {
153
+ // No changes to commit
154
+ }
155
+ db.update(tasks)
156
+ .set({ status: "reviewing", updatedAt: new Date() })
157
+ .where(eq(tasks.id, task.id))
158
+ .run();
159
+ }
160
+ }
161
+ // Max cycles exhausted
162
+ db.update(tasks)
163
+ .set({ status: "failed", updatedAt: new Date() })
164
+ .where(eq(tasks.id, task.id))
165
+ .run();
166
+ return {
167
+ merged: false,
168
+ reviewResult: {
169
+ verdict: "request_changes",
170
+ issues: [],
171
+ summary: `Failed after ${maxCycles} review cycles`,
172
+ },
173
+ };
174
+ }
175
+ //# sourceMappingURL=reviewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reviewer.js","sourceRoot":"","sources":["../../src/orchestrator/reviewer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export interface TaskRecord {
2
+ id: string;
3
+ sessionId: string;
4
+ title: string;
5
+ description: string;
6
+ filesLikelyTouched: string | null;
7
+ acceptanceCriteria: string | null;
8
+ dependsOn: string | null;
9
+ branchName: string | null;
10
+ status: string;
11
+ diffPatch?: string | null;
12
+ }
13
+ export declare function buildCoderPrompt(task: TaskRecord, dependencyDiffs: string[]): string;
14
+ export declare function getDependencyDiffs(task: TaskRecord): string[];
15
+ export declare function runTask(task: TaskRecord, sessionBranch: string, repoPath: string, onOutput?: (chunk: string) => void, onInputNeeded?: (promptText: string) => Promise<string | null>): Promise<{
16
+ success: boolean;
17
+ output: string;
18
+ diff: string;
19
+ }>;
20
+ //# sourceMappingURL=task-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-runner.d.ts","sourceRoot":"","sources":["../../src/orchestrator/task-runner.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,UAAU,EAChB,eAAe,EAAE,MAAM,EAAE,GACxB,MAAM,CAmCR;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,EAAE,CAoB7D;AAED,wBAAsB,OAAO,CAC3B,IAAI,EAAE,UAAU,EAChB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EAClC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAC7D,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CA0E7D"}
@@ -0,0 +1,122 @@
1
+ import { eq } from "drizzle-orm";
2
+ import { getDb } from "../db/client.js";
3
+ import { tasks } from "../db/schema.js";
4
+ import { git, createBranch, getDiff, getStagedDiff, commitAll } from "../git/git.js";
5
+ import { resolveAdapter } from "../adapters/adapter.js";
6
+ import { loadConfig } from "../config/loader.js";
7
+ import { displayTaskId } from "./orchestrator.js";
8
+ export function buildCoderPrompt(task, dependencyDiffs) {
9
+ const files = task.filesLikelyTouched
10
+ ? JSON.parse(task.filesLikelyTouched).join("\n")
11
+ : "(not specified)";
12
+ const criteria = task.acceptanceCriteria
13
+ ? JSON.parse(task.acceptanceCriteria)
14
+ .map((c) => `- ${c}`)
15
+ .join("\n")
16
+ : "(none specified)";
17
+ const contextDiffs = dependencyDiffs.length > 0
18
+ ? dependencyDiffs.join("\n\n---\n\n")
19
+ : "(no prior tasks)";
20
+ return `You are implementing a specific task in a larger project.
21
+
22
+ ## Task
23
+ ${task.title}
24
+
25
+ ## Description
26
+ ${task.description}
27
+
28
+ ## Acceptance Criteria
29
+ ${criteria}
30
+
31
+ ## Files You'll Likely Touch
32
+ ${files}
33
+
34
+ ## Context from Completed Tasks
35
+ ${contextDiffs}
36
+
37
+ Implement this task completely. Create or modify files as needed.
38
+ Do not implement anything outside the scope of this task.`;
39
+ }
40
+ export function getDependencyDiffs(task) {
41
+ if (!task.dependsOn)
42
+ return [];
43
+ const db = getDb();
44
+ const depIds = JSON.parse(task.dependsOn);
45
+ const diffs = [];
46
+ for (const depId of depIds) {
47
+ const rows = db
48
+ .select({ diffPatch: tasks.diffPatch })
49
+ .from(tasks)
50
+ .where(eq(tasks.id, depId))
51
+ .all();
52
+ if (rows.length > 0 && rows[0].diffPatch) {
53
+ diffs.push(rows[0].diffPatch);
54
+ }
55
+ }
56
+ return diffs;
57
+ }
58
+ export async function runTask(task, sessionBranch, repoPath, onOutput, onInputNeeded) {
59
+ const config = loadConfig();
60
+ const db = getDb();
61
+ // Create task branch — use dash separator to avoid git ref conflicts.
62
+ // Session branch is "sw/s_ID" so task branch must NOT nest under it
63
+ // (git forbids both refs/heads/sw/X and refs/heads/sw/X/Y).
64
+ // e.g. "s_UclHjgC1:1" → "sw/s_UclHjgC1-1-add-cachetools-dependency"
65
+ const safeBranchId = task.id.replace(/:/g, "-").replace(/[^a-zA-Z0-9/_-]/g, "");
66
+ const branchName = `sw/${safeBranchId}-${task.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").slice(0, 30)}`;
67
+ createBranch(branchName, sessionBranch, repoPath);
68
+ // Update task in DB
69
+ db.update(tasks)
70
+ .set({
71
+ status: "running",
72
+ branchName,
73
+ updatedAt: new Date(),
74
+ })
75
+ .where(eq(tasks.id, task.id))
76
+ .run();
77
+ // Build prompt
78
+ const depDiffs = getDependencyDiffs(task);
79
+ const prompt = buildCoderPrompt(task, depDiffs);
80
+ // Invoke coder agent
81
+ const adapter = resolveAdapter(config.roles.coder, config);
82
+ try {
83
+ const result = await adapter.execute({
84
+ prompt,
85
+ cwd: repoPath,
86
+ timeout: 0,
87
+ onOutput,
88
+ onInputNeeded,
89
+ });
90
+ // Commit any uncommitted changes the coder left behind (staged or unstaged)
91
+ const uncommitted = getDiff(repoPath) || getStagedDiff(repoPath);
92
+ if (uncommitted.length > 0) {
93
+ commitAll(`feat(${displayTaskId(task.id)}): ${task.title}`, repoPath);
94
+ }
95
+ // Capture the full diff of this task branch vs the session branch
96
+ const diff = git(["diff", `${sessionBranch}...HEAD`], repoPath);
97
+ // Update DB with results
98
+ db.update(tasks)
99
+ .set({
100
+ agentOutput: result.output,
101
+ diffPatch: diff || null,
102
+ status: "reviewing",
103
+ updatedAt: new Date(),
104
+ })
105
+ .where(eq(tasks.id, task.id))
106
+ .run();
107
+ return { success: true, output: result.output, diff };
108
+ }
109
+ catch (err) {
110
+ const message = err instanceof Error ? err.message : String(err);
111
+ db.update(tasks)
112
+ .set({
113
+ status: "failed",
114
+ agentOutput: `Error: ${message}`,
115
+ updatedAt: new Date(),
116
+ })
117
+ .where(eq(tasks.id, task.id))
118
+ .run();
119
+ return { success: false, output: message, diff: "" };
120
+ }
121
+ }
122
+ //# sourceMappingURL=task-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-runner.js","sourceRoot":"","sources":["../../src/orchestrator/task-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export interface TestResult {
2
+ passed: boolean;
3
+ output: string;
4
+ command: string;
5
+ }
6
+ export declare function runTests(repoPath: string, sessionId: string): TestResult;
7
+ export declare function parseTestFailures(output: string): string[];
8
+ //# sourceMappingURL=test-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-runner.d.ts","sourceRoot":"","sources":["../../src/orchestrator/test-runner.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAqCD,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,UAAU,CA+BZ;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAoB1D"}
@@ -0,0 +1,81 @@
1
+ import { execFileSync } from "child_process";
2
+ import { existsSync, readFileSync } from "fs";
3
+ import { join } from "path";
4
+ import { addMessage } from "../session/manager.js";
5
+ function detectTestCommand(repoPath) {
6
+ const pkgPath = join(repoPath, "package.json");
7
+ if (existsSync(pkgPath)) {
8
+ try {
9
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
10
+ if (pkg.scripts?.test && pkg.scripts.test !== 'echo "Error: no test specified" && exit 1') {
11
+ return "npm test";
12
+ }
13
+ }
14
+ catch { }
15
+ }
16
+ if (existsSync(join(repoPath, "Cargo.toml"))) {
17
+ return "cargo test";
18
+ }
19
+ if (existsSync(join(repoPath, "go.mod"))) {
20
+ return "go test ./...";
21
+ }
22
+ if (existsSync(join(repoPath, "pyproject.toml")) || existsSync(join(repoPath, "pytest.ini"))) {
23
+ return "pytest";
24
+ }
25
+ if (existsSync(join(repoPath, "Makefile"))) {
26
+ try {
27
+ const makefile = readFileSync(join(repoPath, "Makefile"), "utf-8");
28
+ if (makefile.includes("test:")) {
29
+ return "make test";
30
+ }
31
+ }
32
+ catch { }
33
+ }
34
+ return null;
35
+ }
36
+ export function runTests(repoPath, sessionId) {
37
+ const command = detectTestCommand(repoPath);
38
+ if (!command) {
39
+ return {
40
+ passed: true,
41
+ output: "No test command detected, skipping tests.",
42
+ command: "(none)",
43
+ };
44
+ }
45
+ addMessage(sessionId, "system", `Running tests: ${command}`);
46
+ try {
47
+ const [cmd, ...args] = command.split(" ");
48
+ const output = execFileSync(cmd, args, {
49
+ cwd: repoPath,
50
+ encoding: "utf-8",
51
+ timeout: 120000,
52
+ stdio: ["pipe", "pipe", "pipe"],
53
+ });
54
+ return { passed: true, output, command };
55
+ }
56
+ catch (err) {
57
+ const output = err instanceof Error && "stdout" in err
58
+ ? String(err.stdout)
59
+ : String(err);
60
+ return { passed: false, output, command };
61
+ }
62
+ }
63
+ export function parseTestFailures(output) {
64
+ const failures = [];
65
+ // Common patterns
66
+ const failPatterns = [
67
+ /FAIL\s+(.+)/g,
68
+ /✗\s+(.+)/g,
69
+ /FAILED\s+(.+)/g,
70
+ /Error:\s+(.+)/g,
71
+ /AssertionError:\s+(.+)/g,
72
+ ];
73
+ for (const pattern of failPatterns) {
74
+ let match;
75
+ while ((match = pattern.exec(output)) !== null) {
76
+ failures.push(match[1].trim());
77
+ }
78
+ }
79
+ return failures;
80
+ }
81
+ //# sourceMappingURL=test-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-runner.js","sourceRoot":"","sources":["../../src/orchestrator/test-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface ParsedTask {
2
+ id: string;
3
+ title: string;
4
+ description: string;
5
+ filesLikelyTouched: string[];
6
+ dependsOn: string[];
7
+ acceptanceCriteria: string[];
8
+ }
9
+ export interface ParsedPlan {
10
+ tasks: ParsedTask[];
11
+ raw: string;
12
+ }
13
+ export declare function parsePlan(agentOutput: string): ParsedPlan;
14
+ //# sourceMappingURL=plan-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-parser.d.ts","sourceRoot":"","sources":["../../src/planner/plan-parser.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;CACb;AA4LD,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,CA2BzD"}