@almightygpt/core 0.2.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 (126) hide show
  1. package/dist/adapters/claude.d.ts +31 -0
  2. package/dist/adapters/claude.d.ts.map +1 -0
  3. package/dist/adapters/claude.js +90 -0
  4. package/dist/adapters/claude.js.map +1 -0
  5. package/dist/adapters/gemini.d.ts +42 -0
  6. package/dist/adapters/gemini.d.ts.map +1 -0
  7. package/dist/adapters/gemini.js +133 -0
  8. package/dist/adapters/gemini.js.map +1 -0
  9. package/dist/adapters/index.d.ts +16 -0
  10. package/dist/adapters/index.d.ts.map +1 -0
  11. package/dist/adapters/index.js +15 -0
  12. package/dist/adapters/index.js.map +1 -0
  13. package/dist/adapters/mock.d.ts +23 -0
  14. package/dist/adapters/mock.d.ts.map +1 -0
  15. package/dist/adapters/mock.js +107 -0
  16. package/dist/adapters/mock.js.map +1 -0
  17. package/dist/adapters/openai.d.ts +38 -0
  18. package/dist/adapters/openai.d.ts.map +1 -0
  19. package/dist/adapters/openai.js +105 -0
  20. package/dist/adapters/openai.js.map +1 -0
  21. package/dist/adapters/types.d.ts +65 -0
  22. package/dist/adapters/types.d.ts.map +1 -0
  23. package/dist/adapters/types.js +26 -0
  24. package/dist/adapters/types.js.map +1 -0
  25. package/dist/config/load.d.ts +15 -0
  26. package/dist/config/load.d.ts.map +1 -0
  27. package/dist/config/load.js +46 -0
  28. package/dist/config/load.js.map +1 -0
  29. package/dist/config/schema.d.ts +260 -0
  30. package/dist/config/schema.d.ts.map +1 -0
  31. package/dist/config/schema.js +58 -0
  32. package/dist/config/schema.js.map +1 -0
  33. package/dist/context/manifest.d.ts +58 -0
  34. package/dist/context/manifest.d.ts.map +1 -0
  35. package/dist/context/manifest.js +49 -0
  36. package/dist/context/manifest.js.map +1 -0
  37. package/dist/context/redact.d.ts +26 -0
  38. package/dist/context/redact.d.ts.map +1 -0
  39. package/dist/context/redact.js +67 -0
  40. package/dist/context/redact.js.map +1 -0
  41. package/dist/git/status.d.ts +48 -0
  42. package/dist/git/status.d.ts.map +1 -0
  43. package/dist/git/status.js +79 -0
  44. package/dist/git/status.js.map +1 -0
  45. package/dist/index.d.ts +33 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +38 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/review/budget.d.ts +46 -0
  50. package/dist/review/budget.d.ts.map +1 -0
  51. package/dist/review/budget.js +83 -0
  52. package/dist/review/budget.js.map +1 -0
  53. package/dist/review/diff.d.ts +21 -0
  54. package/dist/review/diff.d.ts.map +1 -0
  55. package/dist/review/diff.js +55 -0
  56. package/dist/review/diff.js.map +1 -0
  57. package/dist/review/events.d.ts +76 -0
  58. package/dist/review/events.d.ts.map +1 -0
  59. package/dist/review/events.js +13 -0
  60. package/dist/review/events.js.map +1 -0
  61. package/dist/review/memory.d.ts +23 -0
  62. package/dist/review/memory.d.ts.map +1 -0
  63. package/dist/review/memory.js +42 -0
  64. package/dist/review/memory.js.map +1 -0
  65. package/dist/review/prompts.d.ts +34 -0
  66. package/dist/review/prompts.d.ts.map +1 -0
  67. package/dist/review/prompts.js +174 -0
  68. package/dist/review/prompts.js.map +1 -0
  69. package/dist/review/run-diff-review.d.ts +52 -0
  70. package/dist/review/run-diff-review.d.ts.map +1 -0
  71. package/dist/review/run-diff-review.js +258 -0
  72. package/dist/review/run-diff-review.js.map +1 -0
  73. package/dist/review/run-worker-reviewer.d.ts +72 -0
  74. package/dist/review/run-worker-reviewer.d.ts.map +1 -0
  75. package/dist/review/run-worker-reviewer.js +407 -0
  76. package/dist/review/run-worker-reviewer.js.map +1 -0
  77. package/dist/review/write.d.ts +44 -0
  78. package/dist/review/write.d.ts.map +1 -0
  79. package/dist/review/write.js +152 -0
  80. package/dist/review/write.js.map +1 -0
  81. package/dist/runs/decide.d.ts +45 -0
  82. package/dist/runs/decide.d.ts.map +1 -0
  83. package/dist/runs/decide.js +93 -0
  84. package/dist/runs/decide.js.map +1 -0
  85. package/dist/runs/folder.d.ts +42 -0
  86. package/dist/runs/folder.d.ts.map +1 -0
  87. package/dist/runs/folder.js +82 -0
  88. package/dist/runs/folder.js.map +1 -0
  89. package/dist/runs/list.d.ts +58 -0
  90. package/dist/runs/list.d.ts.map +1 -0
  91. package/dist/runs/list.js +117 -0
  92. package/dist/runs/list.js.map +1 -0
  93. package/dist/runs/types.d.ts +96 -0
  94. package/dist/runs/types.d.ts.map +1 -0
  95. package/dist/runs/types.js +13 -0
  96. package/dist/runs/types.js.map +1 -0
  97. package/dist/templates/install.d.ts +49 -0
  98. package/dist/templates/install.d.ts.map +1 -0
  99. package/dist/templates/install.js +154 -0
  100. package/dist/templates/install.js.map +1 -0
  101. package/package.json +34 -0
  102. package/src/adapters/claude.ts +133 -0
  103. package/src/adapters/gemini.ts +183 -0
  104. package/src/adapters/index.ts +21 -0
  105. package/src/adapters/mock.ts +125 -0
  106. package/src/adapters/openai.ts +150 -0
  107. package/src/adapters/types.ts +73 -0
  108. package/src/config/load.ts +61 -0
  109. package/src/config/schema.ts +64 -0
  110. package/src/context/manifest.ts +94 -0
  111. package/src/context/redact.ts +93 -0
  112. package/src/git/status.ts +108 -0
  113. package/src/index.ts +127 -0
  114. package/src/review/budget.ts +116 -0
  115. package/src/review/diff.ts +85 -0
  116. package/src/review/events.ts +86 -0
  117. package/src/review/memory.ts +57 -0
  118. package/src/review/prompts.ts +208 -0
  119. package/src/review/run-diff-review.ts +353 -0
  120. package/src/review/run-worker-reviewer.ts +528 -0
  121. package/src/review/write.ts +208 -0
  122. package/src/runs/decide.ts +153 -0
  123. package/src/runs/folder.ts +137 -0
  124. package/src/runs/list.ts +152 -0
  125. package/src/runs/types.ts +98 -0
  126. package/src/templates/install.ts +198 -0
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Worker / Reviewer two-role review pipeline.
3
+ *
4
+ * This is the headline AlmightyGPT flow: one AI does the work, a different
5
+ * AI critiques it, and the human gets a single artifact with both passes.
6
+ *
7
+ * Pipeline:
8
+ * 1. Load config + create run folder (type: review-worker-reviewer).
9
+ * 2. Resolve Worker adapter (--worker or config.defaults.worker).
10
+ * 3. Resolve Reviewer adapter (--reviewer or config.defaults.reviewer).
11
+ * Same vendor on both sides is allowed but discouraged via a warning.
12
+ * 4. Collect git diff (+ optional range).
13
+ * 5. Redact secrets.
14
+ * 6. Build context manifest, write input.md + context-manifest.json.
15
+ * 7. Pre-flight budget check.
16
+ * 8. Worker stage: assemble Worker memory, run, persist output.
17
+ * 9. Reviewer stage: assemble Reviewer memory, give it the Worker output
18
+ * and the diff, run, persist output.
19
+ * 10. Shallow-review detection on the Reviewer's response.
20
+ * 11. Write the human review file (Worker plan summary lives inside the
21
+ * Reviewer's response per the prompt's required-sections list).
22
+ * 12. Write run.json with both metrics + totals.
23
+ *
24
+ * Events are emitted throughout via the optional onEvent callback so the
25
+ * CLI / future extension can drive progress UIs without polling.
26
+ */
27
+ import type { AgentMetrics } from "../runs/types.js";
28
+ import type { ReviewEventHandler } from "./events.js";
29
+ export interface WorkerReviewerOptions {
30
+ repoRoot: string;
31
+ topic: string;
32
+ /** Worker agent name. Falls back to config.defaults.worker. */
33
+ worker?: string;
34
+ /** Reviewer agent name. Falls back to config.defaults.reviewer. */
35
+ reviewer?: string;
36
+ /** Optional git range like "HEAD~1..HEAD". */
37
+ range?: string;
38
+ /** Bypass the git status safety check / refuse-overwrite check. */
39
+ force?: boolean;
40
+ /** Optional event stream subscriber. */
41
+ onEvent?: ReviewEventHandler;
42
+ }
43
+ export interface WorkerReviewerResult {
44
+ reviewPath: string;
45
+ reviewBytes: number;
46
+ runId: string;
47
+ runFolder: string;
48
+ worker: {
49
+ name: string;
50
+ provider: string;
51
+ model: string;
52
+ };
53
+ reviewer: {
54
+ name: string;
55
+ provider: string;
56
+ model: string;
57
+ };
58
+ metrics: AgentMetrics[];
59
+ totals: {
60
+ tokensIn: number;
61
+ tokensOut: number;
62
+ costUsd: number;
63
+ latencyMs: number;
64
+ };
65
+ filesReviewed: string[];
66
+ redactionsTotal: number;
67
+ shallowWarning?: string;
68
+ sameProviderWarning?: string;
69
+ memoryMissing: string[];
70
+ }
71
+ export declare function runWorkerReviewerReview(opts: WorkerReviewerOptions): Promise<WorkerReviewerResult>;
72
+ //# sourceMappingURL=run-worker-reviewer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-worker-reviewer.d.ts","sourceRoot":"","sources":["../../src/review/run-worker-reviewer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAoBH,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,kBAAkB,CAAC;AAWlE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,wCAAwC;IACxC,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1D,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5D,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,oBAAoB,CAAC,CA0X/B"}
@@ -0,0 +1,407 @@
1
+ /**
2
+ * Worker / Reviewer two-role review pipeline.
3
+ *
4
+ * This is the headline AlmightyGPT flow: one AI does the work, a different
5
+ * AI critiques it, and the human gets a single artifact with both passes.
6
+ *
7
+ * Pipeline:
8
+ * 1. Load config + create run folder (type: review-worker-reviewer).
9
+ * 2. Resolve Worker adapter (--worker or config.defaults.worker).
10
+ * 3. Resolve Reviewer adapter (--reviewer or config.defaults.reviewer).
11
+ * Same vendor on both sides is allowed but discouraged via a warning.
12
+ * 4. Collect git diff (+ optional range).
13
+ * 5. Redact secrets.
14
+ * 6. Build context manifest, write input.md + context-manifest.json.
15
+ * 7. Pre-flight budget check.
16
+ * 8. Worker stage: assemble Worker memory, run, persist output.
17
+ * 9. Reviewer stage: assemble Reviewer memory, give it the Worker output
18
+ * and the diff, run, persist output.
19
+ * 10. Shallow-review detection on the Reviewer's response.
20
+ * 11. Write the human review file (Worker plan summary lives inside the
21
+ * Reviewer's response per the prompt's required-sections list).
22
+ * 12. Write run.json with both metrics + totals.
23
+ *
24
+ * Events are emitted throughout via the optional onEvent callback so the
25
+ * CLI / future extension can drive progress UIs without polling.
26
+ */
27
+ import { AdapterError } from "../adapters/types.js";
28
+ import { MockAdapter } from "../adapters/mock.js";
29
+ import { OpenAIAdapter } from "../adapters/openai.js";
30
+ import { ClaudeAdapter } from "../adapters/claude.js";
31
+ import { GeminiAdapter } from "../adapters/gemini.js";
32
+ import { loadConfig } from "../config/load.js";
33
+ import { redactSecrets } from "../context/redact.js";
34
+ import { buildContextManifest, writeContextManifest, } from "../context/manifest.js";
35
+ import { collectGitContext, createRunFolder, writeAgentOutput, writeRunInput, writeRunMetadata, } from "../runs/folder.js";
36
+ import { collectGitDiff } from "./diff.js";
37
+ import { assembleMemory } from "./memory.js";
38
+ import { buildReviewerSystemFraming, buildReviewerOfWorkerUserMessage, buildWorkerSystemFraming, buildWorkerUserMessage, } from "./prompts.js";
39
+ import { writeHumanReviewFile } from "./write.js";
40
+ import { BudgetTracker, BudgetExceededError } from "./budget.js";
41
+ export async function runWorkerReviewerReview(opts) {
42
+ const emit = opts.onEvent ?? (() => { });
43
+ const config = await loadConfig(opts.repoRoot);
44
+ const workerName = opts.worker ?? config.defaults.worker;
45
+ const reviewerName = opts.reviewer ?? config.defaults.reviewer;
46
+ if (!workerName) {
47
+ throw new Error("No worker specified. Pass --worker <name> or set defaults.worker in .almightygpt/config.yaml.");
48
+ }
49
+ if (!reviewerName) {
50
+ throw new Error("No reviewer specified. Pass --reviewer <name> or set defaults.reviewer in .almightygpt/config.yaml.");
51
+ }
52
+ const workerCfg = config.agents[workerName];
53
+ const reviewerCfg = config.agents[reviewerName];
54
+ if (!workerCfg) {
55
+ throw new Error(`Worker "${workerName}" not found in .almightygpt/config.yaml agents map.`);
56
+ }
57
+ if (!reviewerCfg) {
58
+ throw new Error(`Reviewer "${reviewerName}" not found in .almightygpt/config.yaml agents map.`);
59
+ }
60
+ if (!workerCfg.enabled) {
61
+ throw new Error(`Worker "${workerName}" is disabled in config.`);
62
+ }
63
+ if (!reviewerCfg.enabled) {
64
+ throw new Error(`Reviewer "${reviewerName}" is disabled in config.`);
65
+ }
66
+ const workerAdapter = makeAdapter(workerName, workerCfg.provider);
67
+ const reviewerAdapter = makeAdapter(reviewerName, reviewerCfg.provider);
68
+ if (!(await workerAdapter.isAvailable())) {
69
+ throw new AdapterError(`Worker adapter "${workerName}" (${workerCfg.provider}) is not available. ` +
70
+ envHintFor(workerCfg.provider), workerName);
71
+ }
72
+ if (!(await reviewerAdapter.isAvailable())) {
73
+ throw new AdapterError(`Reviewer adapter "${reviewerName}" (${reviewerCfg.provider}) is not available. ` +
74
+ envHintFor(reviewerCfg.provider), reviewerName);
75
+ }
76
+ const sameProviderWarning = workerCfg.provider === reviewerCfg.provider
77
+ ? `Worker and Reviewer are both ${workerCfg.provider}. Cross-vendor pairing catches more issues.`
78
+ : undefined;
79
+ const runFolder = await createRunFolder({
80
+ repoRoot: opts.repoRoot,
81
+ runsDir: config.runsDir,
82
+ topic: opts.topic,
83
+ type: "review-worker-reviewer",
84
+ });
85
+ emit({
86
+ type: "run_started",
87
+ runId: runFolder.id,
88
+ runType: "review-worker-reviewer",
89
+ topic: opts.topic,
90
+ reviewsDir: config.reviewsDir,
91
+ runFolder: runFolder.relPath,
92
+ });
93
+ const git = await collectGitContext(opts.repoRoot);
94
+ const baseMeta = {
95
+ id: runFolder.id,
96
+ type: "review-worker-reviewer",
97
+ createdAt: new Date().toISOString(),
98
+ workspacePath: opts.repoRoot,
99
+ topic: opts.topic,
100
+ git,
101
+ input: opts.range
102
+ ? { source: "diff-range", range: opts.range }
103
+ : { source: "diff" },
104
+ agents: Object.entries(config.agents).map(([name, a]) => ({
105
+ name,
106
+ role: a.role,
107
+ provider: a.provider,
108
+ enabled: a.enabled,
109
+ })),
110
+ adapterVersions: [
111
+ { adapter: workerAdapter.name, version: "0.0.0" },
112
+ { adapter: reviewerAdapter.name, version: "0.0.0" },
113
+ ],
114
+ status: "running",
115
+ metrics: [],
116
+ totals: { tokensIn: 0, tokensOut: 0, costUsd: 0, latencyMs: 0 },
117
+ budget: config.budget,
118
+ };
119
+ await writeRunMetadata(runFolder.absPath, baseMeta);
120
+ try {
121
+ const diffArgs = {};
122
+ if (opts.range)
123
+ diffArgs.range = opts.range;
124
+ const diffResult = await collectGitDiff(opts.repoRoot, diffArgs);
125
+ if (diffResult.empty && !opts.range) {
126
+ throw new Error("No uncommitted changes. Stage changes, pick a range with --range, or commit something to review.");
127
+ }
128
+ const redaction = config.security.redactSecrets
129
+ ? redactSecrets(diffResult.diff)
130
+ : { text: diffResult.diff, redactions: [], totalCount: 0 };
131
+ emit({
132
+ type: "redaction_complete",
133
+ totalCount: redaction.totalCount,
134
+ byKind: redaction.redactions,
135
+ });
136
+ const manifest = buildContextManifest({
137
+ inputSource: opts.range ? "diff-range" : "diff",
138
+ filesIncluded: diffResult.files.map((p) => ({ path: p, bytes: 0 })),
139
+ filesSkipped: [],
140
+ diffText: redaction.text,
141
+ redaction: {
142
+ enabled: config.security.redactSecrets,
143
+ totalCount: redaction.totalCount,
144
+ byKind: redaction.redactions,
145
+ },
146
+ });
147
+ const manifestRelPath = await writeContextManifest(runFolder.absPath, manifest);
148
+ await writeRunInput(runFolder.absPath, redaction.text);
149
+ const budget = new BudgetTracker(config.budget);
150
+ // ─── Worker stage ───────────────────────────────────────────────
151
+ const workerMemory = await assembleMemory(opts.repoRoot, workerCfg.memoryFile);
152
+ const workerSystem = buildWorkerSystemFraming() + "\n\n" + workerMemory.text;
153
+ const workerUser = buildWorkerUserMessage({
154
+ topic: opts.topic,
155
+ diff: redaction.text,
156
+ files: diffResult.files,
157
+ });
158
+ budget.preflightCheck({
159
+ model: "gpt-4o",
160
+ estimatedTokensIn: Math.ceil((workerSystem.length + workerUser.length) / 4),
161
+ maxOutputTokens: 4096,
162
+ });
163
+ emit({
164
+ type: "agent_started",
165
+ role: "worker",
166
+ agent: workerName,
167
+ provider: workerAdapter.provider,
168
+ });
169
+ const workerOut = await workerAdapter.execute({
170
+ role: "worker",
171
+ systemPrompt: workerSystem,
172
+ userMessage: workerUser,
173
+ });
174
+ budget.record({
175
+ tokensIn: workerOut.tokensIn,
176
+ tokensOut: workerOut.tokensOut,
177
+ costUsd: workerOut.costUsd,
178
+ });
179
+ await writeAgentOutput(runFolder.absPath, "worker", workerOut.content);
180
+ emit({
181
+ type: "agent_completed",
182
+ role: "worker",
183
+ agent: workerName,
184
+ provider: workerAdapter.provider,
185
+ model: workerOut.modelUsed,
186
+ outputPath: `${runFolder.relPath}/outputs/worker.md`,
187
+ tokensIn: workerOut.tokensIn,
188
+ tokensOut: workerOut.tokensOut,
189
+ costUsd: workerOut.costUsd,
190
+ latencyMs: workerOut.latencyMs,
191
+ });
192
+ // ─── Reviewer stage ─────────────────────────────────────────────
193
+ const reviewerMemory = await assembleMemory(opts.repoRoot, reviewerCfg.memoryFile);
194
+ const reviewerSystem = buildReviewerSystemFraming() + "\n\n" + reviewerMemory.text;
195
+ const reviewerUser = buildReviewerOfWorkerUserMessage({
196
+ topic: opts.topic,
197
+ diff: redaction.text,
198
+ files: diffResult.files,
199
+ workerOutput: workerOut.content,
200
+ workerAgent: workerName,
201
+ workerProvider: workerAdapter.provider,
202
+ });
203
+ budget.preflightCheck({
204
+ model: "gpt-4o",
205
+ estimatedTokensIn: Math.ceil((reviewerSystem.length + reviewerUser.length) / 4),
206
+ maxOutputTokens: 4096,
207
+ });
208
+ emit({
209
+ type: "agent_started",
210
+ role: "reviewer",
211
+ agent: reviewerName,
212
+ provider: reviewerAdapter.provider,
213
+ });
214
+ const reviewerOut = await reviewerAdapter.execute({
215
+ role: "reviewer",
216
+ systemPrompt: reviewerSystem,
217
+ userMessage: reviewerUser,
218
+ });
219
+ budget.record({
220
+ tokensIn: reviewerOut.tokensIn,
221
+ tokensOut: reviewerOut.tokensOut,
222
+ costUsd: reviewerOut.costUsd,
223
+ });
224
+ await writeAgentOutput(runFolder.absPath, "reviewer", reviewerOut.content);
225
+ emit({
226
+ type: "agent_completed",
227
+ role: "reviewer",
228
+ agent: reviewerName,
229
+ provider: reviewerAdapter.provider,
230
+ model: reviewerOut.modelUsed,
231
+ outputPath: `${runFolder.relPath}/outputs/reviewer.md`,
232
+ tokensIn: reviewerOut.tokensIn,
233
+ tokensOut: reviewerOut.tokensOut,
234
+ costUsd: reviewerOut.costUsd,
235
+ latencyMs: reviewerOut.latencyMs,
236
+ });
237
+ const shallowWarning = detectShallowReview(reviewerOut.content, config.review.requireConcreteWeaknesses);
238
+ // Write human review file using the Reviewer's response. The Worker
239
+ // plan summary is one of the required sections in the Reviewer's prompt,
240
+ // so it's already embedded in the response.
241
+ const writeOpts = {
242
+ repoRoot: opts.repoRoot,
243
+ reviewsDir: config.reviewsDir,
244
+ topic: opts.topic,
245
+ reviewerName,
246
+ reviewerProvider: reviewerAdapter.provider,
247
+ modelUsed: reviewerOut.modelUsed,
248
+ body: reviewerOut.content,
249
+ metrics: {
250
+ tokensIn: workerOut.tokensIn + reviewerOut.tokensIn,
251
+ tokensOut: workerOut.tokensOut + reviewerOut.tokensOut,
252
+ costUsd: workerOut.costUsd + reviewerOut.costUsd,
253
+ latencyMs: workerOut.latencyMs + reviewerOut.latencyMs,
254
+ },
255
+ runFolder: runFolder.relPath,
256
+ };
257
+ if (shallowWarning)
258
+ writeOpts.shallowWarning = shallowWarning;
259
+ if (opts.force)
260
+ writeOpts.force = opts.force;
261
+ const written = await writeHumanReviewFile(writeOpts);
262
+ const reviewWrittenEvent = {
263
+ type: "review_written",
264
+ reviewPath: written.path,
265
+ bytes: written.bytes,
266
+ };
267
+ if (shallowWarning)
268
+ reviewWrittenEvent.shallowWarning = shallowWarning;
269
+ emit(reviewWrittenEvent);
270
+ const totals = {
271
+ tokensIn: workerOut.tokensIn + reviewerOut.tokensIn,
272
+ tokensOut: workerOut.tokensOut + reviewerOut.tokensOut,
273
+ costUsd: workerOut.costUsd + reviewerOut.costUsd,
274
+ latencyMs: workerOut.latencyMs + reviewerOut.latencyMs,
275
+ };
276
+ const metrics = [
277
+ {
278
+ agent: workerName,
279
+ role: "worker",
280
+ provider: workerAdapter.provider,
281
+ model: workerOut.modelUsed,
282
+ tokensIn: workerOut.tokensIn,
283
+ tokensOut: workerOut.tokensOut,
284
+ costUsd: workerOut.costUsd,
285
+ latencyMs: workerOut.latencyMs,
286
+ },
287
+ {
288
+ agent: reviewerName,
289
+ role: "reviewer",
290
+ provider: reviewerAdapter.provider,
291
+ model: reviewerOut.modelUsed,
292
+ tokensIn: reviewerOut.tokensIn,
293
+ tokensOut: reviewerOut.tokensOut,
294
+ costUsd: reviewerOut.costUsd,
295
+ latencyMs: reviewerOut.latencyMs,
296
+ },
297
+ ];
298
+ const finalMeta = {
299
+ ...baseMeta,
300
+ finishedAt: new Date().toISOString(),
301
+ status: "completed",
302
+ contextManifestPath: manifestRelPath,
303
+ reviewPath: written.path,
304
+ metrics,
305
+ totals,
306
+ };
307
+ await writeRunMetadata(runFolder.absPath, finalMeta);
308
+ emit({
309
+ type: "run_completed",
310
+ runId: runFolder.id,
311
+ reviewPath: written.path,
312
+ runFolder: runFolder.relPath,
313
+ totals,
314
+ });
315
+ const result = {
316
+ reviewPath: written.path,
317
+ reviewBytes: written.bytes,
318
+ runId: runFolder.id,
319
+ runFolder: runFolder.relPath,
320
+ worker: {
321
+ name: workerName,
322
+ provider: workerAdapter.provider,
323
+ model: workerOut.modelUsed,
324
+ },
325
+ reviewer: {
326
+ name: reviewerName,
327
+ provider: reviewerAdapter.provider,
328
+ model: reviewerOut.modelUsed,
329
+ },
330
+ metrics,
331
+ totals,
332
+ filesReviewed: diffResult.files,
333
+ redactionsTotal: redaction.totalCount,
334
+ memoryMissing: [
335
+ ...new Set([...workerMemory.missing, ...reviewerMemory.missing]),
336
+ ],
337
+ };
338
+ if (shallowWarning)
339
+ result.shallowWarning = shallowWarning;
340
+ if (sameProviderWarning)
341
+ result.sameProviderWarning = sameProviderWarning;
342
+ return result;
343
+ }
344
+ catch (err) {
345
+ const failedMeta = {
346
+ ...baseMeta,
347
+ finishedAt: new Date().toISOString(),
348
+ status: err instanceof BudgetExceededError ? "aborted_budget" : "failed",
349
+ error: {
350
+ name: err instanceof Error ? err.name : "Error",
351
+ message: err instanceof Error ? err.message : String(err),
352
+ },
353
+ };
354
+ await writeRunMetadata(runFolder.absPath, failedMeta);
355
+ emit({
356
+ type: "run_failed",
357
+ runId: runFolder.id,
358
+ error: {
359
+ name: err instanceof Error ? err.name : "Error",
360
+ message: err instanceof Error ? err.message : String(err),
361
+ },
362
+ });
363
+ throw err;
364
+ }
365
+ }
366
+ function makeAdapter(name, provider) {
367
+ switch (provider) {
368
+ case "openai":
369
+ return new OpenAIAdapter(name);
370
+ case "anthropic":
371
+ return new ClaudeAdapter(name);
372
+ case "google":
373
+ return new GeminiAdapter(name);
374
+ case "mock":
375
+ return new MockAdapter();
376
+ default:
377
+ throw new Error(`Provider "${provider}" not supported. Use "openai", "anthropic", "google", or "mock".`);
378
+ }
379
+ }
380
+ function envHintFor(provider) {
381
+ switch (provider) {
382
+ case "openai":
383
+ return "Export OPENAI_API_KEY in your environment.";
384
+ case "anthropic":
385
+ return "Export ANTHROPIC_API_KEY in your environment.";
386
+ case "google":
387
+ return "Export GOOGLE_API_KEY (or GEMINI_API_KEY) in your environment.";
388
+ default:
389
+ return "";
390
+ }
391
+ }
392
+ function detectShallowReview(content, minWeaknesses) {
393
+ const fileRefs = content.match(/[\w./_-]+\.(ts|tsx|js|jsx|py|go|rb|md|json|yaml|yml)(?::\d+)?/g);
394
+ const fileRefCount = fileRefs ? fileRefs.length : 0;
395
+ const weaknessSection = content.match(/##\s+Concrete\s+Weaknesses\s*\n([\s\S]*?)(\n##|$)/i);
396
+ const weaknessCount = weaknessSection
397
+ ? (weaknessSection[1].match(/^\s*\d+\.\s+/gm) ?? []).length
398
+ : 0;
399
+ if (fileRefCount === 0) {
400
+ return `Reviewer output contains zero file/line references. Likely shallow.`;
401
+ }
402
+ if (weaknessCount < minWeaknesses) {
403
+ return `Reviewer listed ${weaknessCount} concrete weaknesses; config requires ${minWeaknesses}. Output may be shallow.`;
404
+ }
405
+ return undefined;
406
+ }
407
+ //# sourceMappingURL=run-worker-reviewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-worker-reviewer.js","sourceRoot":"","sources":["../../src/review/run-worker-reviewer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Write the human-facing review file at docs/<reviewer>-reviews/<topic>.md.
3
+ *
4
+ * The topic-named file overwrites on re-run; audit history is preserved by
5
+ * git. Before writing, the path is checked against `git status --short` —
6
+ * if dirty, we refuse to overwrite unless `force` is set.
7
+ *
8
+ * The orchestrator wraps the Reviewer's raw markdown in a small header
9
+ * (metadata) and footer (cost/latency + appendix pointers) so the file is
10
+ * self-contained without depending on the run folder.
11
+ */
12
+ export declare class ReviewFileExistsError extends Error {
13
+ readonly path: string;
14
+ readonly name = "ReviewFileExistsError";
15
+ constructor(message: string, path: string);
16
+ }
17
+ export interface WriteReviewFileOptions {
18
+ repoRoot: string;
19
+ reviewsDir: string;
20
+ topic: string;
21
+ reviewerName: string;
22
+ reviewerProvider: string;
23
+ modelUsed: string;
24
+ /** The Reviewer's raw markdown output. */
25
+ body: string;
26
+ /** Cost/latency to render in the footer. */
27
+ metrics: {
28
+ tokensIn: number;
29
+ tokensOut: number;
30
+ costUsd: number;
31
+ latencyMs: number;
32
+ };
33
+ /** Optional run-folder relative path for the appendix pointer. */
34
+ runFolder?: string;
35
+ /** Optional shallow-review warning to prefix at the top of the file. */
36
+ shallowWarning?: string;
37
+ force?: boolean;
38
+ }
39
+ export interface WrittenReviewFile {
40
+ path: string;
41
+ bytes: number;
42
+ }
43
+ export declare function writeHumanReviewFile(opts: WriteReviewFileOptions): Promise<WrittenReviewFile>;
44
+ //# sourceMappingURL=write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/review/write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,qBAAa,qBAAsB,SAAQ,KAAK;aAED,IAAI,EAAE,MAAM;IADzD,SAAkB,IAAI,2BAA2B;gBACrC,OAAO,EAAE,MAAM,EAAkB,IAAI,EAAE,MAAM;CAG1D;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,OAAO,EAAE;QACP,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CAgC5B"}