planpong 0.2.0 → 0.3.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.
package/README.md CHANGED
@@ -2,30 +2,33 @@
2
2
 
3
3
  Adversarial plan review for AI-assisted development. Two AI models play ping-pong with your plan — one critiques, the other revises — until the plan converges or you stop them.
4
4
 
5
- ## How it works
5
+ Plans go through three review phases, each with a different lens:
6
6
 
7
- 1. You write a plan (markdown file)
8
- 2. A **reviewer** model finds issues (P1/P2/P3 severity)
9
- 3. A **planner** model accepts, rejects, or defers each issue and rewrites the plan
10
- 4. Repeat until the reviewer approves or max rounds hit
7
+ | Round | Phase | What the reviewer looks for |
8
+ | ----- | ------------- | ------------------------------------------------------------------------------------------------ |
9
+ | 1 | **Direction** | Is this the right problem? Is the approach sound? Is the scope appropriate? |
10
+ | 2 | **Risk** | Pre-mortem — assume the plan fails. Surface hidden assumptions, dependencies, and failure modes. |
11
+ | 3+ | **Detail** | Implementation completeness — missing steps, edge cases, gaps, verification criteria. |
11
12
 
12
- Default config: Claude revises, Codex reviews. Both are swappable.
13
+ The planner model evaluates each piece of feedback independently — accepting, rejecting, or deferring with rationale — then rewrites the plan. This continues until the reviewer approves or the round limit is reached.
13
14
 
14
15
  ## Prerequisites
15
16
 
16
- You need **two AI CLI tools** installed and authenticated:
17
+ You need at least **one AI CLI** installed and authenticated:
17
18
 
18
- - **Claude Code** — `npm install -g @anthropic-ai/claude-code` (needs Anthropic API key or Max subscription)
19
- - **Codex CLI** — `npm install -g @openai/codex` (needs OpenAI API key)
19
+ - **Claude Code** — `npm install -g @anthropic-ai/claude-code` (Anthropic API key or Max subscription)
20
+ - **Codex CLI** — `npm install -g @openai/codex` (OpenAI API key)
20
21
 
21
- Verify both work:
22
+ If both are installed, planpong uses one for planning and the other for reviewing (configurable). If only one is available, it auto-fallbacks to using that CLI for both roles.
23
+
24
+ Verify your CLI works:
22
25
 
23
26
  ```sh
24
- claude --version
27
+ claude --version # or
25
28
  codex --version
26
29
  ```
27
30
 
28
- Planpong shells out to these CLIs. No API keys are configured in planpong itself.
31
+ Planpong shells out to these CLIs no API keys are configured in planpong itself.
29
32
 
30
33
  ## Install
31
34
 
@@ -35,13 +38,13 @@ npm install -g planpong
35
38
 
36
39
  ## Setup (Claude Code MCP)
37
40
 
38
- Add planpong as an MCP server so Claude Code can use it natively:
41
+ Add planpong as an MCP server so Claude Code can use it as a native tool:
39
42
 
40
43
  ```sh
41
44
  claude mcp add planpong -- planpong-mcp
42
45
  ```
43
46
 
44
- Then allow the tools in your Claude Code settings (`.claude/settings.json`):
47
+ Allow the tools in your Claude Code settings (`.claude/settings.json`):
45
48
 
46
49
  ```json
47
50
  {
@@ -51,7 +54,7 @@ Then allow the tools in your Claude Code settings (`.claude/settings.json`):
51
54
  }
52
55
  ```
53
56
 
54
- Restart Claude Code. You should see `planpong` tools in your tool list.
57
+ Restart Claude Code. The `planpong` tools should appear in your tool list.
55
58
 
56
59
  ## Usage
57
60
 
@@ -66,8 +69,8 @@ Review my plan at docs/plans/my-feature.md using planpong
66
69
  Or use the slash commands (auto-installed with the MCP server):
67
70
 
68
71
  ```
69
- /planpong:review docs/plans/my-feature.md # autonomous — runs to completion
70
- /planpong:review_interactive docs/plans/my-feature.md # pauses between rounds
72
+ /planpong:review docs/plans/my-feature.md # autonomous — runs to completion
73
+ /planpong:review_interactive docs/plans/my-feature.md # pauses between rounds for your input
71
74
  ```
72
75
 
73
76
  ### Via CLI
@@ -95,14 +98,16 @@ plans_dir: docs/plans
95
98
 
96
99
  All fields are optional. Defaults: claude (planner) + codex (reviewer), 10 rounds, `docs/plans/` directory.
97
100
 
98
- ## What it writes
101
+ ## What it produces
99
102
 
100
- Planpong updates your plan file in-place. It adds a status line:
103
+ Planpong updates your plan file in-place and adds a status line tracking the review:
101
104
 
102
105
  ```
103
106
  **planpong:** R3/10 | claude → codex | 2P2 1P3 → 1P3 → 0 | Accepted: 4 | +32/-8 lines | 5m 23s | Approved after 3 rounds
104
107
  ```
105
108
 
109
+ Reading left to right: round 3 of 10, claude planned / codex reviewed, issue trajectory across rounds, total accepted issues, line delta from original, elapsed time, and outcome.
110
+
106
111
  Session data is stored in `.planpong/sessions/` (add to `.gitignore`).
107
112
 
108
113
  ## Development
@@ -115,9 +120,11 @@ npm run build # compile TypeScript
115
120
  npm run typecheck # type-check without emitting
116
121
  ```
117
122
 
123
+ A pre-commit hook automatically rebuilds `dist/` when TypeScript files are staged.
124
+
118
125
  ### Publishing
119
126
 
120
- Automated via GitHub Actions. No tokens or OTP needed.
127
+ Automated via GitHub Actions with npm trusted publishing (OIDC). No tokens needed.
121
128
 
122
129
  ```sh
123
130
  npm version patch # bumps version + creates git tag
@@ -1,10 +1,17 @@
1
- import { type ReviewFeedback } from "../schemas/feedback.js";
1
+ import { type ReviewFeedback, type PhaseFeedback } from "../schemas/feedback.js";
2
2
  import { type PlannerRevision } from "../schemas/revision.js";
3
+ import type { ReviewPhase } from "../prompts/reviewer.js";
3
4
  /**
4
5
  * Extract JSON from between sentinel tags. Falls back to finding JSON in
5
6
  * code fences, then tries parsing the entire content as JSON.
6
7
  */
7
8
  export declare function extractJSON(content: string, tag: string): string | null;
8
9
  export declare function parseFeedback(content: string): ReviewFeedback;
10
+ /**
11
+ * Phase-aware feedback parser. Tries the phase-specific parser first,
12
+ * falls back to base parser, then applies verdict coercion and blocked
13
+ * rationale validation.
14
+ */
15
+ export declare function parseFeedbackForPhase(content: string, phase: ReviewPhase): PhaseFeedback;
9
16
  export declare function parseRevision(content: string): PlannerRevision;
10
- export declare function isConverged(feedback: ReviewFeedback): boolean;
17
+ export declare function isConverged(feedback: PhaseFeedback): boolean;
@@ -1,4 +1,4 @@
1
- import { ReviewFeedbackSchema, } from "../schemas/feedback.js";
1
+ import { ReviewFeedbackSchema, DirectionFeedbackSchema, RiskFeedbackSchema, } from "../schemas/feedback.js";
2
2
  import { PlannerRevisionSchema, } from "../schemas/revision.js";
3
3
  /**
4
4
  * Extract JSON from between sentinel tags. Falls back to finding JSON in
@@ -36,6 +36,166 @@ export function parseFeedback(content) {
36
36
  }
37
37
  return ReviewFeedbackSchema.parse(parsed);
38
38
  }
39
+ function parseDirectionFeedback(content) {
40
+ const json = extractJSON(content, "planpong-feedback");
41
+ if (!json) {
42
+ throw new Error("Could not extract direction feedback JSON from reviewer output.");
43
+ }
44
+ let parsed;
45
+ try {
46
+ parsed = JSON.parse(json);
47
+ }
48
+ catch {
49
+ throw new Error(`Invalid JSON in reviewer output:\n${json.slice(0, 200)}`);
50
+ }
51
+ return DirectionFeedbackSchema.parse(parsed);
52
+ }
53
+ function parseRiskFeedback(content) {
54
+ const json = extractJSON(content, "planpong-feedback");
55
+ if (!json) {
56
+ throw new Error("Could not extract risk feedback JSON from reviewer output.");
57
+ }
58
+ let parsed;
59
+ try {
60
+ parsed = JSON.parse(json);
61
+ }
62
+ catch {
63
+ throw new Error(`Invalid JSON in reviewer output:\n${json.slice(0, 200)}`);
64
+ }
65
+ return RiskFeedbackSchema.parse(parsed);
66
+ }
67
+ /**
68
+ * Extract a string field value from raw JSON content using the parsed JSON object.
69
+ * Safer than regex — parses the full JSON once and reads the field.
70
+ */
71
+ function extractFieldFromRaw(content, field) {
72
+ const json = extractJSON(content, "planpong-feedback");
73
+ if (!json)
74
+ return null;
75
+ try {
76
+ const parsed = JSON.parse(json);
77
+ if (typeof parsed === "object" && parsed !== null && typeof parsed[field] === "string") {
78
+ return parsed[field];
79
+ }
80
+ }
81
+ catch {
82
+ // fall through
83
+ }
84
+ return null;
85
+ }
86
+ /**
87
+ * Extract an array field from raw JSON content using the parsed JSON object.
88
+ */
89
+ function extractArrayFromRaw(content, field) {
90
+ const json = extractJSON(content, "planpong-feedback");
91
+ if (!json)
92
+ return null;
93
+ try {
94
+ const parsed = JSON.parse(json);
95
+ if (typeof parsed === "object" && parsed !== null && Array.isArray(parsed[field])) {
96
+ return parsed[field];
97
+ }
98
+ }
99
+ catch {
100
+ // fall through
101
+ }
102
+ return null;
103
+ }
104
+ /**
105
+ * Phase-aware feedback parser. Tries the phase-specific parser first,
106
+ * falls back to base parser, then applies verdict coercion and blocked
107
+ * rationale validation.
108
+ */
109
+ export function parseFeedbackForPhase(content, phase) {
110
+ if (phase === "detail") {
111
+ return parseFeedback(content);
112
+ }
113
+ // Try phase-specific parser first
114
+ try {
115
+ if (phase === "direction") {
116
+ const feedback = parseDirectionFeedback(content);
117
+ // Validate blocked rationale
118
+ if (feedback.verdict === "blocked" && !feedback.approach_assessment?.trim()) {
119
+ console.warn("[planpong] Blocked verdict without approach_assessment rationale — coercing to needs_revision");
120
+ return { ...feedback, verdict: "needs_revision" };
121
+ }
122
+ return feedback;
123
+ }
124
+ else {
125
+ const feedback = parseRiskFeedback(content);
126
+ // Validate blocked rationale
127
+ if (feedback.verdict === "blocked" && (!feedback.risks || feedback.risks.length === 0)) {
128
+ console.warn("[planpong] Blocked verdict without risks rationale — coercing to needs_revision");
129
+ return { ...feedback, verdict: "needs_revision" };
130
+ }
131
+ return feedback;
132
+ }
133
+ }
134
+ catch {
135
+ // Phase-specific parse failed — fall back to base schema
136
+ }
137
+ // Fallback: parse with base schema
138
+ const feedback = parseFeedback(content);
139
+ // Determine which phase-specific fields are missing
140
+ const missingFields = [];
141
+ if (phase === "direction") {
142
+ for (const field of ["confidence", "approach_assessment", "alternatives", "assumptions"]) {
143
+ if (!(field in feedback) || feedback[field] === undefined) {
144
+ missingFields.push(field);
145
+ }
146
+ }
147
+ }
148
+ else {
149
+ for (const field of ["risk_level", "risks"]) {
150
+ if (!(field in feedback) || feedback[field] === undefined) {
151
+ missingFields.push(field);
152
+ }
153
+ }
154
+ }
155
+ console.warn(`[planpong] Phase-specific parse failed for ${phase} phase, using fallback. Missing fields: ${missingFields.join(", ")}`);
156
+ // Blocked rationale validation under fallback
157
+ if (feedback.verdict === "blocked") {
158
+ if (phase === "direction") {
159
+ // Try to recover approach_assessment from raw content
160
+ const assessment = extractFieldFromRaw(content, "approach_assessment");
161
+ if (assessment?.trim()) {
162
+ // Preserve blocked, attach recovered rationale
163
+ const result = {
164
+ ...feedback,
165
+ verdict: "blocked",
166
+ fallback_used: true,
167
+ missing_phase_fields: missingFields,
168
+ };
169
+ result.approach_assessment = assessment;
170
+ return result;
171
+ }
172
+ console.warn("[planpong] Blocked verdict under fallback without recoverable rationale — coercing to needs_revision");
173
+ }
174
+ else {
175
+ // Try to recover risks from raw content
176
+ const risks = extractArrayFromRaw(content, "risks");
177
+ if (risks && risks.length > 0) {
178
+ const result = {
179
+ ...feedback,
180
+ verdict: "blocked",
181
+ fallback_used: true,
182
+ missing_phase_fields: missingFields,
183
+ };
184
+ result.risks = risks;
185
+ return result;
186
+ }
187
+ console.warn("[planpong] Blocked verdict under fallback without recoverable risks rationale — coercing to needs_revision");
188
+ }
189
+ }
190
+ // Verdict coercion: direction/risk cannot approve, only needs_revision or blocked
191
+ const coercedVerdict = feedback.verdict === "blocked" ? "needs_revision" : "needs_revision";
192
+ return {
193
+ ...feedback,
194
+ verdict: coercedVerdict,
195
+ fallback_used: true,
196
+ missing_phase_fields: missingFields,
197
+ };
198
+ }
39
199
  export function parseRevision(content) {
40
200
  const json = extractJSON(content, "planpong-revision");
41
201
  if (!json) {
@@ -1 +1 @@
1
- {"version":3,"file":"convergence.js","sourceRoot":"","sources":["../../../src/core/convergence.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,GAErB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,qBAAqB,GAEtB,MAAM,wBAAwB,CAAC;AAEhC;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,GAAW;IACtD,sEAAsE;IACtE,MAAM,UAAU,GAAG,IAAI,MAAM,CAAC,IAAI,GAAG,0BAA0B,GAAG,GAAG,EAAE,GAAG,CAAC,CAAC;IAC5E,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC3C,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC;QAAE,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAE7C,uCAAuC;IACvC,MAAM,YAAY,GAAG,8BAA8B,CAAC;IACpD,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAC/C,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC;QAAE,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAEjD,2CAA2C;IAC3C,MAAM,WAAW,GAAG,aAAa,CAAC;IAClC,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC7C,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAE/C,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;IACvD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CACb,+HAA+H,CAChI,CAAC;IACJ,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,qCAAqC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,OAAO,oBAAoB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;IACvD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CACb,8HAA8H,CAC/H,CAAC;IACJ,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,oCAAoC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,OAAO,qBAAqB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,QAAwB;IAClD,OAAO,QAAQ,CAAC,OAAO,KAAK,gBAAgB,CAAC;AAC/C,CAAC"}
1
+ {"version":3,"file":"convergence.js","sourceRoot":"","sources":["../../../src/core/convergence.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,16 @@
1
1
  import type { Provider } from "../providers/types.js";
2
2
  import type { PlanpongConfig } from "../schemas/config.js";
3
- import type { ReviewFeedback } from "../schemas/feedback.js";
3
+ import type { PhaseFeedback } from "../schemas/feedback.js";
4
4
  import type { PlannerRevision } from "../schemas/revision.js";
5
5
  import { type RoundSeverity } from "./operations.js";
6
6
  export type { RoundSeverity } from "./operations.js";
7
7
  export interface LoopCallbacks {
8
8
  onPlanGenerated(planPath: string, content: string): Promise<void>;
9
9
  onReviewStarting(round: number): void;
10
- onReviewComplete(round: number, feedback: ReviewFeedback): Promise<void>;
10
+ onReviewComplete(round: number, feedback: PhaseFeedback): Promise<void>;
11
11
  onRevisionStarting(round: number): void;
12
12
  onRevisionComplete(round: number, revision: PlannerRevision): Promise<void>;
13
- onConverged(round: number, feedback: ReviewFeedback): void;
13
+ onConverged(round: number, feedback: PhaseFeedback): void;
14
14
  onMaxRoundsReached(round: number): void;
15
15
  onHashMismatch(planPath: string, autonomous: boolean): Promise<"overwrite" | "abort">;
16
16
  /** Return true to continue, false to abort */
@@ -76,7 +76,13 @@ export async function runLoop(options) {
76
76
  await callbacks.onReviewComplete(round, reviewResult.feedback);
77
77
  // Check convergence
78
78
  if (reviewResult.converged) {
79
- finalizeApproved(session, cwd, config, issueTrajectory, totalAccepted, totalRejected, totalDeferred, startTime, initialLineCount);
79
+ if (reviewResult.feedback.verdict === "blocked") {
80
+ session.status = "blocked";
81
+ writeSessionState(cwd, session);
82
+ }
83
+ else {
84
+ finalizeApproved(session, cwd, config, issueTrajectory, totalAccepted, totalRejected, totalDeferred, startTime, initialLineCount);
85
+ }
80
86
  callbacks.onConverged(round, reviewResult.feedback);
81
87
  return;
82
88
  }
@@ -119,7 +125,7 @@ export async function runLoop(options) {
119
125
  const linesAdded = Math.max(0, currentLines - initialLineCount);
120
126
  const linesRemoved = Math.max(0, initialLineCount - currentLines);
121
127
  const elapsed = Date.now() - startTime;
122
- const statusLine = buildStatusLine(session, config, issueTrajectory, totalAccepted, totalRejected, totalDeferred, linesAdded, linesRemoved, elapsed);
128
+ const statusLine = buildStatusLine(session, config, issueTrajectory, totalAccepted, totalRejected, totalDeferred, linesAdded, linesRemoved, elapsed, reviewResult.phaseExtras);
123
129
  planContent = updatePlanStatusLine(planContent, statusLine);
124
130
  writeFileSync(planPath, planContent);
125
131
  session.planHash = hashFile(planPath);
@@ -158,10 +164,16 @@ export async function runReviewLoop(options) {
158
164
  await callbacks.onReviewComplete(round, reviewResult.feedback);
159
165
  // Check convergence
160
166
  if (reviewResult.converged) {
161
- finalizeApproved(session, cwd, config, issueTrajectory, totalAccepted, totalRejected, totalDeferred, startTime, initialLineCount);
167
+ if (reviewResult.feedback.verdict === "blocked") {
168
+ session.status = "blocked";
169
+ writeSessionState(cwd, session);
170
+ }
171
+ else {
172
+ finalizeApproved(session, cwd, config, issueTrajectory, totalAccepted, totalRejected, totalDeferred, startTime, initialLineCount);
173
+ }
162
174
  callbacks.onConverged(round, reviewResult.feedback);
163
175
  return {
164
- status: "approved",
176
+ status: reviewResult.feedback.verdict === "blocked" ? "aborted" : "approved",
165
177
  rounds: round,
166
178
  issueTrajectory,
167
179
  accepted: totalAccepted,
@@ -231,7 +243,7 @@ export async function runReviewLoop(options) {
231
243
  const linesAdded = Math.max(0, currentLines - initialLineCount);
232
244
  const linesRemoved = Math.max(0, initialLineCount - currentLines);
233
245
  const elapsed = Date.now() - startTime;
234
- const statusLine = buildStatusLine(session, config, issueTrajectory, totalAccepted, totalRejected, totalDeferred, linesAdded, linesRemoved, elapsed);
246
+ const statusLine = buildStatusLine(session, config, issueTrajectory, totalAccepted, totalRejected, totalDeferred, linesAdded, linesRemoved, elapsed, reviewResult.phaseExtras);
235
247
  const updatedPlan = updatePlanStatusLine(currentPlan, statusLine);
236
248
  writeFileSync(planPath, updatedPlan);
237
249
  session.planHash = hashFile(planPath);
@@ -1 +1 @@
1
- {"version":3,"file":"loop.js","sourceRoot":"","sources":["../../../src/core/loop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAChF,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAK3C,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EACL,QAAQ,EACR,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,GAEjB,MAAM,iBAAiB,CAAC;AAoDzB,SAAS,eAAe,CAAC,QAAgB,EAAE,IAAa;IACtD,MAAM,IAAI,GACR,IAAI;QACJ,QAAQ,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;IAC7E,IAAI,QAAQ,GAAG,GAAG,IAAI,KAAK,CAAC;IAC5B,IAAI,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACxC,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,OAAO,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,QAAQ,GAAG,GAAG,IAAI,IAAI,OAAO,KAAK,CAAC;QACnC,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACpC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;AACjC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAoB;IAChD,MAAM,EACJ,YAAY,EACZ,GAAG,EACH,MAAM,EACN,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACR,SAAS,GACV,GAAG,OAAO,CAAC;IAEZ,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAC7C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;QAC9C,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,kCAAkC;IAClC,MAAM,UAAU,GAAG,sBAAsB,CAAC,YAAY,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAC1E,MAAM,YAAY,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,UAAU,EAAE;QAC5D,GAAG;QACH,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK;QAC3B,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM;KAC9B,CAAC,CAAC;IAEH,IAAI,YAAY,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CACb,wBAAwB,YAAY,CAAC,QAAQ,OAAO,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CACzF,CAAC;IACJ,CAAC;IAED,6BAA6B;IAC7B,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC1C,MAAM,gBAAgB,GAAG,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAEjD,IAAI,WAAW,GAAG,YAAY,CAAC,OAAO,CAAC;IACvC,MAAM,iBAAiB,GAAG,oBAAoB,MAAM,CAAC,UAAU,MAAM,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,mBAAmB,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IACvK,WAAW,GAAG,oBAAoB,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;IACnE,aAAa,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAErC,MAAM,gBAAgB,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IAEjD,MAAM,OAAO,GAAG,aAAa,CAC3B,GAAG,EACH,gBAAgB,EAChB,MAAM,CAAC,OAAO,EACd,MAAM,CAAC,QAAQ,EACf,QAAQ,CAAC,QAAQ,CAAC,CACnB,CAAC;IACF,OAAO,CAAC,MAAM,GAAG,WAAW,CAAC;IAC7B,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAEhC,MAAM,SAAS,CAAC,eAAe,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAEvD,sBAAsB;IACtB,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;QACzB,MAAM,cAAc,GAAG,MAAM,SAAS,CAAC,eAAe,CACpD,qCAAqC,CACtC,CAAC;QACF,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;YAC3B,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAChC,OAAO;QACT,CAAC;IACH,CAAC;IAED,iBAAiB;IACjB,MAAM,eAAe,GAAoB,EAAE,CAAC;IAC5C,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,aAAa,GAAG,CAAC,CAAC;IAEtB,cAAc;IACd,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,EAAE,CAAC;QACxD,OAAO,CAAC,YAAY,GAAG,KAAK,CAAC;QAC7B,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAEhC,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAEnC,mBAAmB;QACnB,SAAS,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAClC,MAAM,YAAY,GAAG,MAAM,cAAc,CACvC,OAAO,EACP,GAAG,EACH,MAAM,EACN,gBAAgB,CACjB,CAAC;QACF,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,SAAS,CAAC,gBAAgB,CAAC,KAAK,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;QAE/D,oBAAoB;QACpB,IAAI,YAAY,CAAC,SAAS,EAAE,CAAC;YAC3B,gBAAgB,CACd,OAAO,EACP,GAAG,EACH,MAAM,EACN,eAAe,EACf,aAAa,EACb,aAAa,EACb,aAAa,EACb,SAAS,EACT,gBAAgB,CACjB,CAAC;YACF,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;YACpD,OAAO;QACT,CAAC;QAED,cAAc;QACd,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YACzB,MAAM,cAAc,GAAG,MAAM,SAAS,CAAC,eAAe,CACpD,SAAS,KAAK,KAAK,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,sCAAsC,CAC7F,CAAC;YACF,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;gBAC3B,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;gBAChC,OAAO;YACT,CAAC;QACH,CAAC;QAED,+BAA+B;QAC/B,SAAS,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,cAAc,GAAG,MAAM,gBAAgB,CAC3C,OAAO,EACP,GAAG,EACH,MAAM,EACN,eAAe,CAChB,CAAC;QACF,aAAa,IAAI,cAAc,CAAC,QAAQ,CAAC;QACzC,aAAa,IAAI,cAAc,CAAC,QAAQ,CAAC;QACzC,aAAa,IAAI,cAAc,CAAC,QAAQ,CAAC;QACzC,MAAM,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;QAEnE,yDAAyD;QACzD,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACpC,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;gBAC1B,MAAM,UAAU,GAAG,GAAG,QAAQ,QAAQ,KAAK,EAAE,CAAC;gBAC9C,YAAY,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;gBACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,uDAAuD,KAAK,qBAAqB,UAAU,IAAI,CAChG,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,cAAc,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;gBAC/D,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;oBACvB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;oBAC3B,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;oBAChC,OAAO;gBACT,CAAC;YACH,CAAC;QACH,CAAC;QAED,6BAA6B;QAC7B,WAAW,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,YAAY,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;QAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,GAAG,gBAAgB,CAAC,CAAC;QAChE,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,gBAAgB,GAAG,YAAY,CAAC,CAAC;QAClE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAEvC,MAAM,UAAU,GAAG,eAAe,CAChC,OAAO,EACP,MAAM,EACN,eAAe,EACf,aAAa,EACb,aAAa,EACb,aAAa,EACb,UAAU,EACV,YAAY,EACZ,OAAO,CACR,CAAC;QACF,WAAW,GAAG,oBAAoB,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QAC5D,aAAa,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QACrC,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACtC,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,qBAAqB;IACrB,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAChD,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAC3B,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAAsB;IAEtB,MAAM,EACJ,QAAQ,EACR,GAAG,EACH,MAAM,EACN,eAAe,EACf,gBAAgB,EAChB,SAAS,GACV,GAAG,OAAO,CAAC;IAEZ,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,iBAAiB,CAAC,QAAQ,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IAC1E,MAAM,gBAAgB,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IAEjD,MAAM,SAAS,CAAC,eAAe,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAEvD,iBAAiB;IACjB,MAAM,eAAe,GAAoB,EAAE,CAAC;IAC5C,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,aAAa,GAAG,CAAC,CAAC;IAEtB,cAAc;IACd,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,EAAE,CAAC;QACxD,OAAO,CAAC,YAAY,GAAG,KAAK,CAAC;QAC7B,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAEhC,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAEnC,mBAAmB;QACnB,SAAS,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAClC,MAAM,YAAY,GAAG,MAAM,cAAc,CACvC,OAAO,EACP,GAAG,EACH,MAAM,EACN,gBAAgB,CACjB,CAAC;QACF,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,SAAS,CAAC,gBAAgB,CAAC,KAAK,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;QAE/D,oBAAoB;QACpB,IAAI,YAAY,CAAC,SAAS,EAAE,CAAC;YAC3B,gBAAgB,CACd,OAAO,EACP,GAAG,EACH,MAAM,EACN,eAAe,EACf,aAAa,EACb,aAAa,EACb,aAAa,EACb,SAAS,EACT,gBAAgB,CACjB,CAAC;YACF,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;YAEpD,OAAO;gBACL,MAAM,EAAE,UAAU;gBAClB,MAAM,EAAE,KAAK;gBACb,eAAe;gBACf,QAAQ,EAAE,aAAa;gBACvB,QAAQ,EAAE,aAAa;gBACvB,QAAQ,EAAE,aAAa;gBACvB,QAAQ;gBACR,SAAS,EAAE,OAAO,CAAC,EAAE;gBACrB,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;aAChC,CAAC;QACJ,CAAC;QAED,cAAc;QACd,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YACzB,MAAM,cAAc,GAAG,MAAM,SAAS,CAAC,eAAe,CACpD,SAAS,KAAK,KAAK,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,sCAAsC,CAC7F,CAAC;YACF,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;gBAC3B,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;gBAChC,OAAO;oBACL,MAAM,EAAE,SAAS;oBACjB,MAAM,EAAE,KAAK;oBACb,eAAe;oBACf,QAAQ,EAAE,aAAa;oBACvB,QAAQ,EAAE,aAAa;oBACvB,QAAQ,EAAE,aAAa;oBACvB,QAAQ;oBACR,SAAS,EAAE,OAAO,CAAC,EAAE;oBACrB,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;iBAChC,CAAC;YACJ,CAAC;QACH,CAAC;QAED,+BAA+B;QAC/B,SAAS,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,cAAc,GAAG,MAAM,gBAAgB,CAC3C,OAAO,EACP,GAAG,EACH,MAAM,EACN,eAAe,CAChB,CAAC;QACF,aAAa,IAAI,cAAc,CAAC,QAAQ,CAAC;QACzC,aAAa,IAAI,cAAc,CAAC,QAAQ,CAAC;QACzC,aAAa,IAAI,cAAc,CAAC,QAAQ,CAAC;QACzC,MAAM,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;QAEnE,uBAAuB;QACvB,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACpC,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;gBAC1B,MAAM,UAAU,GAAG,GAAG,QAAQ,QAAQ,KAAK,EAAE,CAAC;gBAC9C,YAAY,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;gBACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,uDAAuD,KAAK,qBAAqB,UAAU,IAAI,CAChG,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,cAAc,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;gBAC/D,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;oBACvB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;oBAC3B,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;oBAChC,OAAO;wBACL,MAAM,EAAE,SAAS;wBACjB,MAAM,EAAE,KAAK;wBACb,eAAe;wBACf,QAAQ,EAAE,aAAa;wBACvB,QAAQ,EAAE,aAAa;wBACvB,QAAQ,EAAE,aAAa;wBACvB,QAAQ;wBACR,SAAS,EAAE,OAAO,CAAC,EAAE;wBACrB,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;qBAChC,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAED,6BAA6B;QAC7B,MAAM,WAAW,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACpD,MAAM,YAAY,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;QAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,GAAG,gBAAgB,CAAC,CAAC;QAChE,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,gBAAgB,GAAG,YAAY,CAAC,CAAC;QAClE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAEvC,MAAM,UAAU,GAAG,eAAe,CAChC,OAAO,EACP,MAAM,EACN,eAAe,EACf,aAAa,EACb,aAAa,EACb,aAAa,EACb,UAAU,EACV,YAAY,EACZ,OAAO,CACR,CAAC;QACF,MAAM,WAAW,GAAG,oBAAoB,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QAClE,aAAa,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QACrC,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACtC,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,qBAAqB;IACrB,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAChD,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAC3B,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAEhC,OAAO;QACL,MAAM,EAAE,YAAY;QACpB,MAAM,EAAE,MAAM,CAAC,UAAU;QACzB,eAAe;QACf,QAAQ,EAAE,aAAa;QACvB,QAAQ,EAAE,aAAa;QACvB,QAAQ,EAAE,aAAa;QACvB,QAAQ;QACR,SAAS,EAAE,OAAO,CAAC,EAAE;QACrB,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;KAChC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"loop.js","sourceRoot":"","sources":["../../../src/core/loop.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,27 @@
1
1
  import type { Provider } from "../providers/types.js";
2
2
  import type { PlanpongConfig, ProviderConfig } from "../schemas/config.js";
3
- import type { ReviewFeedback } from "../schemas/feedback.js";
3
+ import type { PhaseFeedback } from "../schemas/feedback.js";
4
4
  import type { PlannerRevision } from "../schemas/revision.js";
5
+ import { getReviewPhase } from "../prompts/reviewer.js";
5
6
  import type { Session } from "../schemas/session.js";
6
7
  export interface RoundSeverity {
7
8
  P1: number;
8
9
  P2: number;
9
10
  P3: number;
10
11
  }
12
+ export interface PhaseExtras {
13
+ confidence?: "high" | "medium" | "low";
14
+ risk_level?: "high" | "medium" | "low";
15
+ risk_count?: number;
16
+ risks_promoted?: number;
17
+ is_blocked?: boolean;
18
+ }
11
19
  export interface ReviewRoundResult {
12
20
  round: number;
13
- feedback: ReviewFeedback;
21
+ feedback: PhaseFeedback;
14
22
  severity: RoundSeverity;
15
23
  converged: boolean;
24
+ phaseExtras: PhaseExtras;
16
25
  }
17
26
  export interface RevisionRoundResult {
18
27
  round: number;
@@ -30,7 +39,7 @@ export interface SessionInit {
30
39
  export declare function hashFile(path: string): string;
31
40
  export declare function formatRoundSeverity(round: RoundSeverity): string;
32
41
  export declare function formatTrajectory(trajectory: RoundSeverity[]): string;
33
- export declare function severityFromFeedback(feedback: ReviewFeedback): RoundSeverity;
42
+ export declare function severityFromFeedback(feedback: PhaseFeedback): RoundSeverity;
34
43
  export declare function formatTallies(accepted: number, rejected: number, deferred: number): string;
35
44
  export declare function formatDuration(ms: number): string;
36
45
  export declare function formatProviderLabel(provider: ProviderConfig): string;
@@ -41,7 +50,8 @@ export interface SessionStats {
41
50
  totalDeferred: number;
42
51
  }
43
52
  export declare function computeSessionStats(cwd: string, sessionId: string, currentRound: number): SessionStats;
44
- export declare function buildStatusLine(session: Session, config: PlanpongConfig, issueTrajectory: RoundSeverity[], accepted: number, rejected: number, deferred: number, linesAdded: number, linesRemoved: number, elapsed: number): string;
53
+ export declare function formatPhaseExtras(phase: ReturnType<typeof getReviewPhase>, extras: PhaseExtras): string;
54
+ export declare function buildStatusLine(session: Session, config: PlanpongConfig, issueTrajectory: RoundSeverity[], accepted: number, rejected: number, deferred: number, linesAdded: number, linesRemoved: number, elapsed: number, phaseExtras?: PhaseExtras): string;
45
55
  /**
46
56
  * Build and write the status line to the plan file.
47
57
  * Used by both CLI and MCP paths after each round.
@@ -3,7 +3,7 @@ import { readFileSync, writeFileSync, existsSync } from "node:fs";
3
3
  import { relative, resolve } from "node:path";
4
4
  import { buildRevisionPrompt } from "../prompts/planner.js";
5
5
  import { buildReviewPrompt, formatPriorDecisions, getReviewPhase, } from "../prompts/reviewer.js";
6
- import { parseFeedback, parseRevision, isConverged } from "./convergence.js";
6
+ import { parseFeedbackForPhase, parseRevision, isConverged, } from "./convergence.js";
7
7
  import { createSession, writeSessionState, writeRoundFeedback, writeRoundResponse, readRoundFeedback, readRoundResponse, writeInitialPlan, } from "./session.js";
8
8
  // --- Utility functions ---
9
9
  export function hashFile(path) {
@@ -97,15 +97,42 @@ export function computeSessionStats(cwd, sessionId, currentRound) {
97
97
  totalDeferred,
98
98
  };
99
99
  }
100
- export function buildStatusLine(session, config, issueTrajectory, accepted, rejected, deferred, linesAdded, linesRemoved, elapsed) {
100
+ export function formatPhaseExtras(phase, extras) {
101
+ if (extras.is_blocked) {
102
+ if (phase === "risk" && extras.risk_count) {
103
+ return `BLOCKED | ${extras.risk_count} unmitigable risks`;
104
+ }
105
+ return "BLOCKED";
106
+ }
107
+ const parts = [];
108
+ if (phase === "direction" && extras.confidence) {
109
+ parts.push(`confidence: ${extras.confidence}`);
110
+ }
111
+ if (phase === "risk") {
112
+ if (extras.risk_level) {
113
+ parts.push(`risk: ${extras.risk_level}`);
114
+ }
115
+ if (extras.risk_count !== undefined && extras.risks_promoted !== undefined) {
116
+ parts.push(`${extras.risk_count} risks (${extras.risks_promoted} promoted)`);
117
+ }
118
+ }
119
+ return parts.join(" | ");
120
+ }
121
+ export function buildStatusLine(session, config, issueTrajectory, accepted, rejected, deferred, linesAdded, linesRemoved, elapsed, phaseExtras) {
101
122
  const plannerLabel = formatProviderLabel(config.planner);
102
123
  const reviewerLabel = formatProviderLabel(config.reviewer);
103
124
  const trajectory = formatTrajectory(issueTrajectory);
104
125
  const tallies = formatTallies(accepted, rejected, deferred);
105
126
  const elapsedStr = formatDuration(elapsed);
127
+ const phase = getReviewPhase(session.currentRound);
128
+ const phaseSignal = phaseExtras
129
+ ? formatPhaseExtras(phase, phaseExtras)
130
+ : "";
106
131
  const parts = [
107
132
  `**planpong:** R${session.currentRound}/${config.max_rounds}`,
108
133
  `${plannerLabel} → ${reviewerLabel}`,
134
+ phase,
135
+ phaseSignal,
109
136
  trajectory,
110
137
  tallies,
111
138
  `+${linesAdded}/-${linesRemoved} lines`,
@@ -217,7 +244,7 @@ export async function runReviewRound(session, cwd, config, reviewerProvider) {
217
244
  // Try to parse even on non-zero exit — CLIs can exit 1 with valid output
218
245
  let feedback;
219
246
  try {
220
- feedback = parseFeedback(reviewResponse.content);
247
+ feedback = parseFeedbackForPhase(reviewResponse.content, phase);
221
248
  }
222
249
  catch (parseError) {
223
250
  // If exit code was also non-zero, the provider genuinely failed
@@ -231,12 +258,30 @@ export async function runReviewRound(session, cwd, config, reviewerProvider) {
231
258
  model: config.reviewer.model,
232
259
  effort: config.reviewer.effort,
233
260
  });
234
- feedback = parseFeedback(retryResponse.content);
261
+ feedback = parseFeedbackForPhase(retryResponse.content, phase);
235
262
  }
236
263
  writeRoundFeedback(cwd, session.id, round, feedback);
237
264
  const severity = severityFromFeedback(feedback);
238
265
  const converged = isConverged(feedback);
239
- return { round, feedback, severity, converged };
266
+ // Extract phase-specific extras for status line
267
+ const phaseExtras = {};
268
+ if (feedback.verdict === "blocked") {
269
+ phaseExtras.is_blocked = true;
270
+ session.status = "blocked";
271
+ writeSessionState(cwd, session);
272
+ }
273
+ if (phase === "direction" && "confidence" in feedback) {
274
+ phaseExtras.confidence = feedback.confidence;
275
+ }
276
+ if (phase === "risk") {
277
+ if ("risk_level" in feedback) {
278
+ const riskFb = feedback;
279
+ phaseExtras.risk_level = riskFb.risk_level;
280
+ phaseExtras.risk_count = riskFb.risks?.length ?? 0;
281
+ phaseExtras.risks_promoted = feedback.issues.length;
282
+ }
283
+ }
284
+ return { round, feedback, severity, converged, phaseExtras };
240
285
  }
241
286
  /**
242
287
  * Run a single revision round: send plan + feedback to the planner for revision.