planpong 0.5.7 → 0.6.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 (61) hide show
  1. package/README.md +47 -10
  2. package/dist/bin/planpong.js +3 -0
  3. package/dist/bin/planpong.js.map +1 -1
  4. package/dist/src/cli/commands/init.d.ts +53 -0
  5. package/dist/src/cli/commands/init.js +221 -0
  6. package/dist/src/cli/commands/init.js.map +1 -0
  7. package/dist/src/cli/ui.js +11 -19
  8. package/dist/src/cli/ui.js.map +1 -1
  9. package/dist/src/config/loader.d.ts +5 -0
  10. package/dist/src/config/loader.js +21 -1
  11. package/dist/src/config/loader.js.map +1 -1
  12. package/dist/src/config/mutate.d.ts +26 -0
  13. package/dist/src/config/mutate.js +45 -32
  14. package/dist/src/config/mutate.js.map +1 -1
  15. package/dist/src/core/convergence.js +1 -1
  16. package/dist/src/core/convergence.js.map +1 -1
  17. package/dist/src/core/operations.d.ts +44 -1
  18. package/dist/src/core/operations.js +110 -37
  19. package/dist/src/core/operations.js.map +1 -1
  20. package/dist/src/core/presentation.d.ts +39 -0
  21. package/dist/src/core/presentation.js +132 -0
  22. package/dist/src/core/presentation.js.map +1 -0
  23. package/dist/src/core/round-state.d.ts +15 -0
  24. package/dist/src/core/round-state.js +49 -0
  25. package/dist/src/core/round-state.js.map +1 -0
  26. package/dist/src/core/session.d.ts +1 -0
  27. package/dist/src/core/session.js +60 -1
  28. package/dist/src/core/session.js.map +1 -1
  29. package/dist/src/mcp/server.js +6 -6
  30. package/dist/src/mcp/server.js.map +1 -1
  31. package/dist/src/mcp/tools/get-feedback.d.ts +1 -2
  32. package/dist/src/mcp/tools/get-feedback.js +154 -56
  33. package/dist/src/mcp/tools/get-feedback.js.map +1 -1
  34. package/dist/src/mcp/tools/record-revision.d.ts +0 -6
  35. package/dist/src/mcp/tools/record-revision.js +170 -95
  36. package/dist/src/mcp/tools/record-revision.js.map +1 -1
  37. package/dist/src/mcp/tools/revise.d.ts +1 -7
  38. package/dist/src/mcp/tools/revise.js +126 -90
  39. package/dist/src/mcp/tools/revise.js.map +1 -1
  40. package/dist/src/mcp/tools/status.js +18 -1
  41. package/dist/src/mcp/tools/status.js.map +1 -1
  42. package/dist/src/providers/claude.d.ts +22 -1
  43. package/dist/src/providers/claude.js +10 -10
  44. package/dist/src/providers/claude.js.map +1 -1
  45. package/dist/src/providers/codex.d.ts +12 -1
  46. package/dist/src/providers/codex.js +6 -3
  47. package/dist/src/providers/codex.js.map +1 -1
  48. package/dist/src/providers/gemini.d.ts +58 -0
  49. package/dist/src/providers/gemini.js +169 -0
  50. package/dist/src/providers/gemini.js.map +1 -0
  51. package/dist/src/providers/registry.js +7 -1
  52. package/dist/src/providers/registry.js.map +1 -1
  53. package/dist/src/providers/shared.d.ts +16 -0
  54. package/dist/src/providers/shared.js +22 -0
  55. package/dist/src/providers/shared.js.map +1 -0
  56. package/dist/src/providers/types.d.ts +1 -1
  57. package/dist/src/schemas/metrics.d.ts +14 -14
  58. package/dist/src/schemas/metrics.js +13 -2
  59. package/dist/src/schemas/metrics.js.map +1 -1
  60. package/dist/src/schemas/session.d.ts +2 -2
  61. package/package.json +3 -2
@@ -3,9 +3,11 @@ import { readFileSync, writeFileSync } from "node:fs";
3
3
  import { resolve } from "node:path";
4
4
  import { loadConfig } from "../../config/loader.js";
5
5
  import { getProvider } from "../../providers/registry.js";
6
- import { readSessionState, writeSessionState, readInitialPlan, } from "../../core/session.js";
7
- import { runReviewRound, writeStatusLineToPlan, } from "../../core/operations.js";
6
+ import { readSessionState, writeSessionState, readInitialPlan, withSessionLock, } from "../../core/session.js";
7
+ import { runReviewRound, severityFromFeedback, writeStatusLineToPlan, formatPhaseExtras, phaseExtrasFromFeedback, } from "../../core/operations.js";
8
8
  import { getReviewPhase } from "../../prompts/reviewer.js";
9
+ import { formatFeedbackDisplay } from "../../core/presentation.js";
10
+ import { getRoundState } from "../../core/round-state.js";
9
11
  const inputSchema = {
10
12
  session_id: z.string().describe("Session ID from planpong_start_review"),
11
13
  cwd: z
@@ -15,8 +17,8 @@ const inputSchema = {
15
17
  };
16
18
  export async function getFeedbackHandler(input) {
17
19
  const cwd = input.cwd ?? process.cwd();
18
- const session = readSessionState(cwd, input.session_id);
19
- if (!session) {
20
+ const existing = readSessionState(cwd, input.session_id);
21
+ if (!existing) {
20
22
  return {
21
23
  content: [
22
24
  {
@@ -29,76 +31,179 @@ export async function getFeedbackHandler(input) {
29
31
  isError: true,
30
32
  };
31
33
  }
32
- if (session.status !== "in_review") {
33
- return {
34
- content: [
35
- {
36
- type: "text",
37
- text: JSON.stringify({
38
- error: `Session status is '${session.status}', expected 'in_review'`,
39
- }),
40
- },
41
- ],
42
- isError: true,
43
- };
44
- }
45
- // Advance round
46
- session.currentRound++;
47
- writeSessionState(cwd, session);
48
- const config = loadConfig({ cwd });
49
- // Use session-stored provider config
50
- const reviewerProvider = getProvider(session.reviewer.provider);
51
- if (!reviewerProvider) {
52
- return {
53
- content: [
54
- {
55
- type: "text",
56
- text: JSON.stringify({
57
- error: `Reviewer provider not found: ${session.reviewer.provider}`,
58
- }),
59
- },
60
- ],
61
- isError: true,
34
+ return withSessionLock(cwd, input.session_id, async () => {
35
+ const session = readSessionState(cwd, input.session_id);
36
+ if (!session) {
37
+ return {
38
+ content: [
39
+ {
40
+ type: "text",
41
+ text: JSON.stringify({
42
+ error: `Session not found: ${input.session_id}`,
43
+ }),
44
+ },
45
+ ],
46
+ isError: true,
47
+ };
48
+ }
49
+ const config = loadConfig({ cwd });
50
+ const sessionConfig = {
51
+ ...config,
52
+ reviewer: session.reviewer,
53
+ planner: session.planner,
62
54
  };
63
- }
64
- // Build config with session overrides
65
- const sessionConfig = {
66
- ...config,
67
- reviewer: session.reviewer,
68
- planner: session.planner,
55
+ const roundState = getRoundState(cwd, session, sessionConfig.max_rounds);
56
+ if (session.status !== "in_review") {
57
+ return {
58
+ content: [
59
+ {
60
+ type: "text",
61
+ text: JSON.stringify({
62
+ error: `Session status is '${session.status}', expected 'in_review'`,
63
+ }),
64
+ },
65
+ ],
66
+ isError: true,
67
+ };
68
+ }
69
+ if (roundState.inconsistentArtifacts) {
70
+ return {
71
+ content: [
72
+ {
73
+ type: "text",
74
+ text: JSON.stringify({
75
+ error: `Session ${session.id} has round ${session.currentRound} response without feedback`,
76
+ current_round: session.currentRound,
77
+ }),
78
+ },
79
+ ],
80
+ isError: true,
81
+ };
82
+ }
83
+ if (roundState.currentRound > 0 &&
84
+ roundState.latestFeedback &&
85
+ !roundState.latestResponse) {
86
+ return buildFeedbackResponse({
87
+ session,
88
+ cwd,
89
+ config: sessionConfig,
90
+ result: reviewResultFromFeedback(roundState.currentRound, roundState.latestFeedback),
91
+ idempotentReplay: true,
92
+ });
93
+ }
94
+ if (roundState.currentRound > 0 &&
95
+ roundState.latestFeedback &&
96
+ roundState.latestResponse) {
97
+ if (roundState.currentRound >= sessionConfig.max_rounds) {
98
+ const statusLine = writeStatusLineToPlan(session, cwd, sessionConfig, "Max rounds reached");
99
+ return {
100
+ content: [
101
+ { type: "text", text: statusLine },
102
+ {
103
+ type: "text",
104
+ text: JSON.stringify({
105
+ status: "max_rounds",
106
+ round: roundState.currentRound,
107
+ is_converged: false,
108
+ status_line: statusLine,
109
+ idempotent_replay: false,
110
+ }),
111
+ },
112
+ ],
113
+ };
114
+ }
115
+ session.currentRound++;
116
+ writeSessionState(cwd, session);
117
+ }
118
+ else if (roundState.currentRound === 0) {
119
+ session.currentRound = 1;
120
+ writeSessionState(cwd, session);
121
+ }
122
+ // If currentRound > 0 and feedback is missing, this is an incomplete
123
+ // transition from a prior attempt. Retry the same round without
124
+ // incrementing.
125
+ // Use session-stored provider config
126
+ const reviewerProvider = getProvider(session.reviewer.provider);
127
+ if (!reviewerProvider) {
128
+ return {
129
+ content: [
130
+ {
131
+ type: "text",
132
+ text: JSON.stringify({
133
+ error: `Reviewer provider not found: ${session.reviewer.provider}`,
134
+ }),
135
+ },
136
+ ],
137
+ isError: true,
138
+ };
139
+ }
140
+ const result = await runReviewRound(session, cwd, sessionConfig, reviewerProvider);
141
+ return buildFeedbackResponse({
142
+ session,
143
+ cwd,
144
+ config: sessionConfig,
145
+ result,
146
+ idempotentReplay: false,
147
+ resumedIncompleteRound: roundState.incompleteTransition,
148
+ });
149
+ });
150
+ }
151
+ function reviewResultFromFeedback(round, feedback) {
152
+ const phase = getReviewPhase(round);
153
+ const severity = severityFromFeedback(feedback);
154
+ const phaseExtras = phaseExtrasFromFeedback(phase, feedback);
155
+ return {
156
+ round,
157
+ feedback,
158
+ severity,
159
+ converged: feedback.verdict !== "needs_revision",
160
+ phaseExtras,
69
161
  };
70
- const result = await runReviewRound(session, cwd, sessionConfig, reviewerProvider);
71
- // Update status line with review results
162
+ }
163
+ function buildFeedbackResponse(args) {
164
+ const { session, cwd, config, result } = args;
72
165
  const suffix = result.converged
73
166
  ? result.feedback.verdict === "blocked"
74
167
  ? `BLOCKED in ${getReviewPhase(result.round)} phase`
75
168
  : `Approved after ${result.round} rounds`
76
169
  : `Reviewed — ${result.feedback.issues.length} issues`;
77
- const statusLine = writeStatusLineToPlan(session, cwd, sessionConfig, suffix);
170
+ const statusLine = writeStatusLineToPlan(session, cwd, config, suffix, result.phaseExtras);
78
171
  const phase = getReviewPhase(result.round);
172
+ const phaseSignal = formatPhaseExtras(phase, result.phaseExtras);
173
+ const display = formatFeedbackDisplay({
174
+ round: result.round,
175
+ phase,
176
+ verdict: result.feedback.verdict,
177
+ severity: result.severity,
178
+ feedback: result.feedback,
179
+ phaseSignal,
180
+ });
79
181
  const response = {
80
182
  round: result.round,
81
183
  phase,
184
+ phase_label: phase,
82
185
  verdict: result.feedback.verdict,
83
186
  summary: result.feedback.summary,
84
187
  issues: result.feedback.issues,
188
+ issue_rows: display.rows,
85
189
  severity_counts: result.severity,
86
190
  is_converged: result.converged,
87
191
  status_line: statusLine,
192
+ display_markdown: display.markdown,
193
+ idempotent_replay: args.idempotentReplay,
88
194
  };
195
+ if (args.resumedIncompleteRound) {
196
+ response.resumed_incomplete_round = true;
197
+ }
89
198
  if (result.timing) {
90
199
  response.timing = result.timing;
91
200
  }
92
- // Evidence-verification telemetry: surface the post-parse verifier's
93
- // counts so consumers can spot reviewer hallucinations and sustained
94
- // quote-compliance noncompliance without inspecting individual issues.
95
201
  if (result.feedback.unverified_count !== undefined) {
96
202
  response.unverified_count = result.feedback.unverified_count;
97
203
  }
98
204
  if (result.feedback.quote_compliance_warning) {
99
205
  response.quote_compliance_warning = true;
100
206
  }
101
- // Phase-specific lean fields for status line consumption
102
207
  if (result.phaseExtras.is_blocked) {
103
208
  response.is_blocked = true;
104
209
  }
@@ -128,7 +233,6 @@ export async function getFeedbackHandler(input) {
128
233
  writeFileSync(planPath, planContent);
129
234
  }
130
235
  writeSessionState(cwd, session);
131
- // Include initial plan for change summary
132
236
  const initialPlan = readInitialPlan(cwd, session.id);
133
237
  if (initialPlan) {
134
238
  response.initial_plan = initialPlan;
@@ -138,14 +242,8 @@ export async function getFeedbackHandler(input) {
138
242
  }
139
243
  return {
140
244
  content: [
141
- {
142
- type: "text",
143
- text: statusLine,
144
- },
145
- {
146
- type: "text",
147
- text: JSON.stringify(response),
148
- },
245
+ { type: "text", text: statusLine },
246
+ { type: "text", text: JSON.stringify(response) },
149
247
  ],
150
248
  };
151
249
  }
@@ -1 +1 @@
1
- {"version":3,"file":"get-feedback.js","sourceRoot":"","sources":["../../../../src/mcp/tools/get-feedback.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"get-feedback.js","sourceRoot":"","sources":["../../../../src/mcp/tools/get-feedback.ts"],"names":[],"mappings":"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"}
@@ -10,11 +10,5 @@ export declare function recordRevisionHandler(input: {
10
10
  type: "text";
11
11
  text: string;
12
12
  }[];
13
- isError: boolean;
14
- } | {
15
- content: {
16
- type: "text";
17
- text: string;
18
- }[];
19
13
  }>;
20
14
  export declare function registerRecordRevision(server: McpServer): void;
@@ -1,11 +1,12 @@
1
1
  import { z } from "zod";
2
2
  import { readFileSync } from "node:fs";
3
3
  import { resolve } from "node:path";
4
- import { readSessionState, readRoundFeedback, writeRoundMetrics, } from "../../core/session.js";
4
+ import { readSessionState, readRoundFeedback, readRoundResponse, writeRoundMetrics, withSessionLock, } from "../../core/session.js";
5
5
  import { finalizeRevision, writeStatusLineToPlan, } from "../../core/operations.js";
6
6
  import { loadConfig } from "../../config/loader.js";
7
7
  import { getReviewPhase } from "../../prompts/reviewer.js";
8
8
  import { IssueResponseSchema, } from "../../schemas/revision.js";
9
+ import { formatDecisionDisplay } from "../../core/presentation.js";
9
10
  /**
10
11
  * Inline-mode counterpart to `planpong_revise`. The agent that invoked
11
12
  * /pong-review acts as the planner: it edited the plan with its own
@@ -33,110 +34,184 @@ const inputSchema = {
33
34
  };
34
35
  export async function recordRevisionHandler(input) {
35
36
  const cwd = input.cwd ?? process.cwd();
36
- const session = readSessionState(cwd, input.session_id);
37
- if (!session) {
37
+ const existing = readSessionState(cwd, input.session_id);
38
+ if (!existing) {
38
39
  return errorResponse(`Session not found: ${input.session_id}`);
39
40
  }
40
- if (session.status !== "in_review") {
41
- return errorResponse(`Session status is '${session.status}', expected 'in_review'`);
42
- }
43
- if (session.plannerMode !== "inline") {
44
- return errorResponse(`session is in ${session.plannerMode} planner mode — use planpong_revise instead`, { planner_mode: session.plannerMode });
45
- }
46
- if (input.expected_round !== session.currentRound) {
47
- return errorResponse(`round ${input.expected_round} already finalized (current round is ${session.currentRound})`, {
48
- expected_round: input.expected_round,
49
- current_round: session.currentRound,
41
+ return withSessionLock(cwd, input.session_id, async () => {
42
+ const session = readSessionState(cwd, input.session_id);
43
+ if (!session) {
44
+ return errorResponse(`Session not found: ${input.session_id}`);
45
+ }
46
+ if (session.status !== "in_review") {
47
+ return errorResponse(`Session status is '${session.status}', expected 'in_review'`);
48
+ }
49
+ if (session.plannerMode !== "inline") {
50
+ return errorResponse(`session is in ${session.plannerMode} planner mode — use planpong_revise instead`, { planner_mode: session.plannerMode });
51
+ }
52
+ if (input.expected_round !== session.currentRound) {
53
+ const relation = input.expected_round < session.currentRound ? "stale" : "out-of-order";
54
+ const message = relation === "stale"
55
+ ? `stale revision call for round ${input.expected_round}; current round is ${session.currentRound}`
56
+ : `out-of-order revision call for round ${input.expected_round}; call planpong_get_feedback first`;
57
+ return errorResponse(message, {
58
+ expected_round: input.expected_round,
59
+ current_round: session.currentRound,
60
+ });
61
+ }
62
+ const feedback = readRoundFeedback(cwd, session.id, session.currentRound);
63
+ if (!feedback) {
64
+ return errorResponse(`No feedback found for session ${session.id} round ${session.currentRound}. Call planpong_get_feedback first.`);
65
+ }
66
+ const existingResponse = readRoundResponse(cwd, session.id, session.currentRound);
67
+ if (existingResponse &&
68
+ JSON.stringify(existingResponse.responses) ===
69
+ JSON.stringify(input.responses)) {
70
+ const accepted = existingResponse.responses.filter((r) => r.action === "accepted").length;
71
+ const rejected = existingResponse.responses.filter((r) => r.action === "rejected").length;
72
+ const deferred = existingResponse.responses.filter((r) => r.action === "deferred").length;
73
+ const config = loadConfig({ cwd });
74
+ const sessionConfig = {
75
+ ...config,
76
+ planner: session.planner,
77
+ reviewer: session.reviewer,
78
+ };
79
+ const statusLine = writeStatusLineToPlan(session, cwd, sessionConfig, "Revision recorded");
80
+ return buildRecordRevisionResponse({
81
+ round: session.currentRound,
82
+ feedback,
83
+ revision: existingResponse,
84
+ responses: existingResponse.responses,
85
+ accepted,
86
+ rejected,
87
+ deferred,
88
+ unverifiedRejected: countUnverifiedRejected(existingResponse.responses),
89
+ planUpdated: false,
90
+ statusLine,
91
+ idempotentReplay: true,
92
+ });
93
+ }
94
+ if (existingResponse) {
95
+ return errorResponse(`round ${session.currentRound} already finalized with different responses`, {
96
+ current_round: session.currentRound,
97
+ idempotent_replay: false,
98
+ });
99
+ }
100
+ // Validate every issue has a response. Mirrors the planner prompt's
101
+ // "every issue MUST have an entry in responses" constraint so inline
102
+ // mode produces the same shape downstream tools expect.
103
+ const responseIds = new Set(input.responses.map((r) => r.issue_id));
104
+ const missing = feedback.issues
105
+ .map((i) => i.id)
106
+ .filter((id) => !responseIds.has(id));
107
+ if (missing.length > 0) {
108
+ return errorResponse(`responses missing for issue(s): ${missing.join(", ")}. Provide one response per feedback issue.`, { missing_issue_ids: missing });
109
+ }
110
+ const round = session.currentRound;
111
+ const phase = getReviewPhase(round);
112
+ const planPath = resolve(cwd, session.planPath);
113
+ // Hash before finalize so we can detect "agent forgot to edit".
114
+ const planHashBefore = session.planHash;
115
+ // Construct PlannerRevision-shape payload. Direction phase keeps the
116
+ // full-plan shape; risk/detail keep the edits shape (with empty edits[]
117
+ // — the agent applied changes via its own Edit tool rather than
118
+ // declaring them here, so the array is informational-only).
119
+ const planContent = readFileSync(planPath, "utf-8");
120
+ const revision = phase === "direction"
121
+ ? { responses: input.responses, updated_plan: planContent }
122
+ : { responses: input.responses, edits: [] };
123
+ const tally = finalizeRevision({
124
+ session,
125
+ cwd,
126
+ round,
127
+ revision,
128
+ planPath,
129
+ });
130
+ // Plan-hash warn: any accepted issue should correspond to a plan edit.
131
+ // Surface the no-op case but don't gate — sometimes all issues are
132
+ // legitimately rejected and the plan correctly stays unchanged.
133
+ const planUnchanged = session.planHash === planHashBefore;
134
+ const anyAccepted = input.responses.some((r) => r.action === "accepted");
135
+ const planUpdateWarning = planUnchanged && anyAccepted
136
+ ? `Round ${round} has accepted issues but the plan hash is unchanged. Confirm the plan edits were applied.`
137
+ : undefined;
138
+ if (planUnchanged && anyAccepted) {
139
+ process.stderr.write(`[planpong] warn: round ${round} has accepted issues but plan hash is unchanged — did the agent forget to edit?\n`);
140
+ }
141
+ // Write fully valid RoundMetrics so bench/run.ts:226 doesn't drop this
142
+ // round from analysis. Inline revisions have no provider duration —
143
+ // started_at and completed_at are the same instant.
144
+ const ts = new Date().toISOString();
145
+ const metrics = {
146
+ schema_version: 1,
147
+ session_id: session.id,
148
+ round,
149
+ phase,
150
+ role: "revision",
151
+ started_at: ts,
152
+ completed_at: ts,
153
+ total_duration_ms: 0,
154
+ attempts: [],
155
+ planner_mode: "inline",
156
+ };
157
+ writeRoundMetrics(cwd, session.id, round, "revision", metrics);
158
+ // Update plan status line. Use loadConfig for provider labels (the
159
+ // status-line writer needs them). In inline mode the planner provider
160
+ // is informational, not invoked.
161
+ const config = loadConfig({ cwd });
162
+ const sessionConfig = {
163
+ ...config,
164
+ planner: session.planner,
165
+ reviewer: session.reviewer,
166
+ };
167
+ const statusLine = writeStatusLineToPlan(session, cwd, sessionConfig, "Revision recorded");
168
+ // Match planpong_revise's unverified_rejected counter so the slash
169
+ // command can consume either tool's output uniformly.
170
+ return buildRecordRevisionResponse({
171
+ round,
172
+ feedback,
173
+ revision,
174
+ responses: input.responses,
175
+ accepted: tally.accepted,
176
+ rejected: tally.rejected,
177
+ deferred: tally.deferred,
178
+ unverifiedRejected: countUnverifiedRejected(input.responses),
179
+ planUpdated: !planUnchanged,
180
+ statusLine,
181
+ idempotentReplay: !tally.fresh,
182
+ displayWarning: planUpdateWarning,
50
183
  });
51
- }
52
- const feedback = readRoundFeedback(cwd, session.id, session.currentRound);
53
- if (!feedback) {
54
- return errorResponse(`No feedback found for session ${session.id} round ${session.currentRound}. Call planpong_get_feedback first.`);
55
- }
56
- // Validate every issue has a response. Mirrors the planner prompt's
57
- // "every issue MUST have an entry in responses" constraint so inline
58
- // mode produces the same shape downstream tools expect.
59
- const responseIds = new Set(input.responses.map((r) => r.issue_id));
60
- const missing = feedback.issues
61
- .map((i) => i.id)
62
- .filter((id) => !responseIds.has(id));
63
- if (missing.length > 0) {
64
- return errorResponse(`responses missing for issue(s): ${missing.join(", ")}. Provide one response per feedback issue.`, { missing_issue_ids: missing });
65
- }
66
- const round = session.currentRound;
67
- const phase = getReviewPhase(round);
68
- const planPath = resolve(cwd, session.planPath);
69
- // Hash before finalize so we can detect "agent forgot to edit".
70
- const planHashBefore = session.planHash;
71
- // Construct PlannerRevision-shape payload. Direction phase keeps the
72
- // full-plan shape; risk/detail keep the edits shape (with empty edits[]
73
- // — the agent applied changes via its own Edit tool rather than
74
- // declaring them here, so the array is informational-only).
75
- const planContent = readFileSync(planPath, "utf-8");
76
- const revision = phase === "direction"
77
- ? { responses: input.responses, updated_plan: planContent }
78
- : { responses: input.responses, edits: [] };
79
- const tally = finalizeRevision({
80
- session,
81
- cwd,
82
- round,
83
- revision,
84
- planPath,
85
184
  });
86
- // Plan-hash warn: any accepted issue should correspond to a plan edit.
87
- // Surface the no-op case but don't gate — sometimes all issues are
88
- // legitimately rejected and the plan correctly stays unchanged.
89
- const planUnchanged = session.planHash === planHashBefore;
90
- const anyAccepted = input.responses.some((r) => r.action === "accepted");
91
- if (planUnchanged && anyAccepted) {
92
- process.stderr.write(`[planpong] warn: round ${round} has accepted issues but plan hash is unchanged — did the agent forget to edit?\n`);
93
- }
94
- // Write fully valid RoundMetrics so bench/run.ts:226 doesn't drop this
95
- // round from analysis. Inline revisions have no provider duration —
96
- // started_at and completed_at are the same instant.
97
- const ts = new Date().toISOString();
98
- const metrics = {
99
- schema_version: 1,
100
- session_id: session.id,
101
- round,
102
- phase,
103
- role: "revision",
104
- started_at: ts,
105
- completed_at: ts,
106
- total_duration_ms: 0,
107
- attempts: [],
108
- planner_mode: "inline",
109
- };
110
- writeRoundMetrics(cwd, session.id, round, "revision", metrics);
111
- // Update plan status line. Use loadConfig for provider labels (the
112
- // status-line writer needs them). In inline mode the planner provider
113
- // is informational, not invoked.
114
- const config = loadConfig({ cwd });
115
- const sessionConfig = {
116
- ...config,
117
- planner: session.planner,
118
- reviewer: session.reviewer,
119
- };
120
- const statusLine = writeStatusLineToPlan(session, cwd, sessionConfig, "Revision recorded");
121
- // Match planpong_revise's unverified_rejected counter so the slash
122
- // command can consume either tool's output uniformly.
123
- const unverifiedRejected = input.responses.filter((r) => r.action === "rejected" &&
185
+ }
186
+ function countUnverifiedRejected(responses) {
187
+ return responses.filter((r) => r.action === "rejected" &&
124
188
  /unverified\s+evidence/i.test(r.rationale ?? "")).length;
189
+ }
190
+ function buildRecordRevisionResponse(args) {
191
+ const display = formatDecisionDisplay({
192
+ round: args.round,
193
+ feedback: args.feedback,
194
+ revision: args.revision,
195
+ warning: args.displayWarning,
196
+ });
125
197
  const payload = {
126
- round,
127
- responses: input.responses,
128
- accepted: tally.accepted,
129
- rejected: tally.rejected,
130
- deferred: tally.deferred,
131
- unverified_rejected: unverifiedRejected,
132
- plan_updated: !planUnchanged,
133
- status_line: statusLine,
198
+ round: args.round,
199
+ responses: args.responses,
200
+ accepted: args.accepted,
201
+ rejected: args.rejected,
202
+ deferred: args.deferred,
203
+ unverified_rejected: args.unverifiedRejected,
204
+ plan_updated: args.planUpdated,
205
+ status_line: args.statusLine,
134
206
  planner_mode: "inline",
135
- idempotent_replay: !tally.fresh,
207
+ idempotent_replay: args.idempotentReplay,
208
+ decision_rows: display.rows,
209
+ display_markdown: display.markdown,
210
+ ...(display.warnings.length > 0 && { display_warnings: display.warnings }),
136
211
  };
137
212
  return {
138
213
  content: [
139
- { type: "text", text: statusLine },
214
+ { type: "text", text: args.statusLine },
140
215
  { type: "text", text: JSON.stringify(payload) },
141
216
  ],
142
217
  };
@@ -1 +1 @@
1
- {"version":3,"file":"record-revision.js","sourceRoot":"","sources":["../../../../src/mcp/tools/record-revision.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"record-revision.js","sourceRoot":"","sources":["../../../../src/mcp/tools/record-revision.ts"],"names":[],"mappings":"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"}