planpong 0.5.7 → 0.6.1

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 (68) hide show
  1. package/README.md +53 -14
  2. package/dist/bin/planpong.js +4 -0
  3. package/dist/bin/planpong.js.map +1 -1
  4. package/dist/src/cli/commands/config.d.ts +10 -0
  5. package/dist/src/cli/commands/config.js +65 -0
  6. package/dist/src/cli/commands/config.js.map +1 -1
  7. package/dist/src/cli/commands/init.d.ts +53 -0
  8. package/dist/src/cli/commands/init.js +221 -0
  9. package/dist/src/cli/commands/init.js.map +1 -0
  10. package/dist/src/cli/commands/plan.js +7 -7
  11. package/dist/src/cli/commands/plan.js.map +1 -1
  12. package/dist/src/cli/commands/review.js +7 -7
  13. package/dist/src/cli/commands/review.js.map +1 -1
  14. package/dist/src/cli/ui.js +11 -19
  15. package/dist/src/cli/ui.js.map +1 -1
  16. package/dist/src/config/loader.d.ts +5 -0
  17. package/dist/src/config/loader.js +21 -1
  18. package/dist/src/config/loader.js.map +1 -1
  19. package/dist/src/config/mutate.d.ts +26 -0
  20. package/dist/src/config/mutate.js +51 -38
  21. package/dist/src/config/mutate.js.map +1 -1
  22. package/dist/src/core/convergence.js +1 -1
  23. package/dist/src/core/convergence.js.map +1 -1
  24. package/dist/src/core/operations.d.ts +44 -1
  25. package/dist/src/core/operations.js +110 -37
  26. package/dist/src/core/operations.js.map +1 -1
  27. package/dist/src/core/presentation.d.ts +39 -0
  28. package/dist/src/core/presentation.js +132 -0
  29. package/dist/src/core/presentation.js.map +1 -0
  30. package/dist/src/core/round-state.d.ts +15 -0
  31. package/dist/src/core/round-state.js +49 -0
  32. package/dist/src/core/round-state.js.map +1 -0
  33. package/dist/src/core/session.d.ts +1 -0
  34. package/dist/src/core/session.js +60 -1
  35. package/dist/src/core/session.js.map +1 -1
  36. package/dist/src/mcp/server.js +6 -6
  37. package/dist/src/mcp/server.js.map +1 -1
  38. package/dist/src/mcp/tools/get-feedback.d.ts +1 -2
  39. package/dist/src/mcp/tools/get-feedback.js +154 -56
  40. package/dist/src/mcp/tools/get-feedback.js.map +1 -1
  41. package/dist/src/mcp/tools/record-revision.d.ts +0 -6
  42. package/dist/src/mcp/tools/record-revision.js +170 -95
  43. package/dist/src/mcp/tools/record-revision.js.map +1 -1
  44. package/dist/src/mcp/tools/revise.d.ts +1 -7
  45. package/dist/src/mcp/tools/revise.js +126 -90
  46. package/dist/src/mcp/tools/revise.js.map +1 -1
  47. package/dist/src/mcp/tools/status.js +18 -1
  48. package/dist/src/mcp/tools/status.js.map +1 -1
  49. package/dist/src/providers/claude.d.ts +22 -1
  50. package/dist/src/providers/claude.js +10 -10
  51. package/dist/src/providers/claude.js.map +1 -1
  52. package/dist/src/providers/codex.d.ts +12 -1
  53. package/dist/src/providers/codex.js +6 -3
  54. package/dist/src/providers/codex.js.map +1 -1
  55. package/dist/src/providers/gemini.d.ts +58 -0
  56. package/dist/src/providers/gemini.js +169 -0
  57. package/dist/src/providers/gemini.js.map +1 -0
  58. package/dist/src/providers/registry.js +8 -2
  59. package/dist/src/providers/registry.js.map +1 -1
  60. package/dist/src/providers/shared.d.ts +16 -0
  61. package/dist/src/providers/shared.js +22 -0
  62. package/dist/src/providers/shared.js.map +1 -0
  63. package/dist/src/providers/types.d.ts +1 -1
  64. package/dist/src/schemas/metrics.d.ts +14 -14
  65. package/dist/src/schemas/metrics.js +13 -2
  66. package/dist/src/schemas/metrics.js.map +1 -1
  67. package/dist/src/schemas/session.d.ts +2 -2
  68. package/package.json +3 -2
@@ -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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"}
@@ -1,18 +1,12 @@
1
1
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  export declare function reviseHandler(input: {
3
3
  session_id: string;
4
+ expected_round: number;
4
5
  cwd?: string;
5
6
  }): Promise<{
6
7
  content: {
7
8
  type: "text";
8
9
  text: string;
9
10
  }[];
10
- isError: boolean;
11
- } | {
12
- content: {
13
- type: "text";
14
- text: string;
15
- }[];
16
- isError?: undefined;
17
11
  }>;
18
12
  export declare function registerRevise(server: McpServer): void;
@@ -1,10 +1,16 @@
1
1
  import { z } from "zod";
2
2
  import { loadConfig } from "../../config/loader.js";
3
3
  import { getProvider } from "../../providers/registry.js";
4
- import { readSessionState } from "../../core/session.js";
4
+ import { readRoundFeedback, readRoundResponse, readSessionState, withSessionLock, } from "../../core/session.js";
5
5
  import { runRevisionRound, writeStatusLineToPlan, } from "../../core/operations.js";
6
+ import { formatDecisionDisplay } from "../../core/presentation.js";
6
7
  const inputSchema = {
7
8
  session_id: z.string().describe("Session ID from planpong_start_review"),
9
+ expected_round: z
10
+ .number()
11
+ .int()
12
+ .positive()
13
+ .describe("The feedback round this revision responds to. Must equal session.currentRound."),
8
14
  cwd: z
9
15
  .string()
10
16
  .optional()
@@ -12,111 +18,141 @@ const inputSchema = {
12
18
  };
13
19
  export async function reviseHandler(input) {
14
20
  const cwd = input.cwd ?? process.cwd();
15
- const session = readSessionState(cwd, input.session_id);
16
- if (!session) {
17
- return {
18
- content: [
19
- {
20
- type: "text",
21
- text: JSON.stringify({
22
- error: `Session not found: ${input.session_id}`,
23
- }),
24
- },
25
- ],
26
- isError: true,
27
- };
28
- }
29
- if (session.status !== "in_review") {
30
- return {
31
- content: [
32
- {
33
- type: "text",
34
- text: JSON.stringify({
35
- error: `Session status is '${session.status}', expected 'in_review'`,
36
- }),
37
- },
38
- ],
39
- isError: true,
40
- };
21
+ const existing = readSessionState(cwd, input.session_id);
22
+ if (!existing) {
23
+ return errorResponse(`Session not found: ${input.session_id}`);
41
24
  }
42
- if (session.plannerMode === "inline") {
43
- return {
44
- content: [
45
- {
46
- type: "text",
47
- text: JSON.stringify({
48
- error: "session is in inline planner mode use planpong_record_revision instead",
49
- planner_mode: "inline",
50
- }),
51
- },
52
- ],
53
- isError: true,
54
- };
55
- }
56
- const config = loadConfig({ cwd });
57
- const plannerProvider = getProvider(session.planner.provider);
58
- if (!plannerProvider) {
59
- return {
60
- content: [
61
- {
62
- type: "text",
63
- text: JSON.stringify({
64
- error: `Planner provider not found: ${session.planner.provider}`,
65
- }),
66
- },
67
- ],
68
- isError: true,
25
+ return withSessionLock(cwd, input.session_id, async () => {
26
+ const session = readSessionState(cwd, input.session_id);
27
+ if (!session) {
28
+ return errorResponse(`Session not found: ${input.session_id}`);
29
+ }
30
+ if (input.expected_round < session.currentRound) {
31
+ return errorResponse(`stale revision call for round ${input.expected_round}; current round is ${session.currentRound}`, {
32
+ expected_round: input.expected_round,
33
+ current_round: session.currentRound,
34
+ });
35
+ }
36
+ if (input.expected_round > session.currentRound) {
37
+ return errorResponse(`out-of-order revision call for round ${input.expected_round}; call planpong_get_feedback first`, {
38
+ expected_round: input.expected_round,
39
+ current_round: session.currentRound,
40
+ });
41
+ }
42
+ if (session.status !== "in_review") {
43
+ return errorResponse(`Session status is '${session.status}', expected 'in_review'`);
44
+ }
45
+ if (session.plannerMode === "inline") {
46
+ return errorResponse("session is in inline planner mode — use planpong_record_revision instead", { planner_mode: "inline" });
47
+ }
48
+ const config = loadConfig({ cwd });
49
+ const sessionConfig = {
50
+ ...config,
51
+ planner: session.planner,
52
+ reviewer: session.reviewer,
69
53
  };
54
+ const feedback = readRoundFeedback(cwd, session.id, input.expected_round);
55
+ if (!feedback) {
56
+ return errorResponse(`No feedback found for session ${session.id} round ${input.expected_round}. Call planpong_get_feedback first.`);
57
+ }
58
+ const existingResponse = readRoundResponse(cwd, session.id, input.expected_round);
59
+ if (existingResponse) {
60
+ const tally = tallyResponses(existingResponse.responses);
61
+ const statusLine = writeStatusLineToPlan(session, cwd, sessionConfig, "Revision submitted");
62
+ return buildRevisionResponse({
63
+ round: input.expected_round,
64
+ revision: existingResponse,
65
+ accepted: tally.accepted,
66
+ rejected: tally.rejected,
67
+ deferred: tally.deferred,
68
+ planUpdated: false,
69
+ statusLine,
70
+ feedback,
71
+ idempotentReplay: true,
72
+ });
73
+ }
74
+ const plannerProvider = getProvider(session.planner.provider);
75
+ if (!plannerProvider) {
76
+ return errorResponse(`Planner provider not found: ${session.planner.provider}`);
77
+ }
78
+ const result = await runRevisionRound(session, cwd, sessionConfig, plannerProvider);
79
+ // Update status line in plan file (planner may have mangled it)
80
+ const statusLine = writeStatusLineToPlan(session, cwd, sessionConfig, "Revision submitted");
81
+ return buildRevisionResponse({
82
+ ...result,
83
+ statusLine,
84
+ feedback,
85
+ idempotentReplay: false,
86
+ });
87
+ });
88
+ }
89
+ function tallyResponses(responses) {
90
+ let accepted = 0;
91
+ let rejected = 0;
92
+ let deferred = 0;
93
+ for (const response of responses) {
94
+ if (response.action === "accepted")
95
+ accepted++;
96
+ else if (response.action === "rejected")
97
+ rejected++;
98
+ else if (response.action === "deferred")
99
+ deferred++;
70
100
  }
71
- const sessionConfig = {
72
- ...config,
73
- planner: session.planner,
74
- reviewer: session.reviewer,
75
- };
76
- const result = await runRevisionRound(session, cwd, sessionConfig, plannerProvider);
77
- // Update status line in plan file (planner may have mangled it)
78
- const statusLine = writeStatusLineToPlan(session, cwd, sessionConfig, "Revision submitted");
79
- // Count rejections whose rationale matches "unverified evidence".
80
- // Free-text matching is intentionally lenient; the planner prompt
81
- // suggests the exact phrase but accepts variants (the plan flags
82
- // this in Limitations & Future Work — a structured enum is a
83
- // follow-up).
84
- const unverifiedRejected = result.revision.responses.filter((r) => r.action === "rejected" &&
101
+ return { accepted, rejected, deferred };
102
+ }
103
+ function buildRevisionResponse(args) {
104
+ const unverifiedRejected = args.revision.responses.filter((r) => r.action === "rejected" &&
85
105
  /unverified\s+evidence/i.test(r.rationale ?? "")).length;
106
+ const display = formatDecisionDisplay({
107
+ round: args.round,
108
+ feedback: args.feedback,
109
+ revision: args.revision,
110
+ });
86
111
  const payload = {
87
- round: result.round,
88
- responses: result.revision.responses,
89
- accepted: result.accepted,
90
- rejected: result.rejected,
91
- deferred: result.deferred,
112
+ round: args.round,
113
+ responses: args.revision.responses,
114
+ accepted: args.accepted,
115
+ rejected: args.rejected,
116
+ deferred: args.deferred,
92
117
  unverified_rejected: unverifiedRejected,
93
- plan_updated: result.planUpdated,
94
- status_line: statusLine,
118
+ plan_updated: args.planUpdated,
119
+ status_line: args.statusLine,
120
+ idempotent_replay: args.idempotentReplay,
121
+ decision_rows: display.rows,
122
+ display_markdown: display.markdown,
95
123
  };
96
- if (result.timing) {
97
- payload.timing = result.timing;
124
+ if (display.warnings.length > 0) {
125
+ payload.display_warnings = display.warnings;
98
126
  }
99
- if (result.edits) {
100
- payload.revision_mode = result.edits.revision_mode;
101
- if (result.edits.revision_mode === "edits") {
102
- payload.edits_attempted = result.edits.edits_attempted;
103
- payload.edits_applied = result.edits.edits_applied;
104
- payload.edits_failed = result.edits.edits_failed;
105
- payload.edits_recovered = result.edits.edits_recovered;
106
- payload.retry_invoked = result.edits.retry_invoked;
127
+ if (args.timing) {
128
+ payload.timing = args.timing;
129
+ }
130
+ if (args.edits) {
131
+ payload.revision_mode = args.edits.revision_mode;
132
+ if (args.edits.revision_mode === "edits") {
133
+ payload.edits_attempted = args.edits.edits_attempted;
134
+ payload.edits_applied = args.edits.edits_applied;
135
+ payload.edits_failed = args.edits.edits_failed;
136
+ payload.edits_recovered = args.edits.edits_recovered;
137
+ payload.retry_invoked = args.edits.retry_invoked;
107
138
  }
108
139
  }
140
+ return {
141
+ content: [
142
+ { type: "text", text: args.statusLine },
143
+ { type: "text", text: JSON.stringify(payload) },
144
+ ],
145
+ };
146
+ }
147
+ function errorResponse(error, extra = {}) {
109
148
  return {
110
149
  content: [
111
150
  {
112
151
  type: "text",
113
- text: statusLine,
114
- },
115
- {
116
- type: "text",
117
- text: JSON.stringify(payload),
152
+ text: JSON.stringify({ error, ...extra }),
118
153
  },
119
154
  ],
155
+ isError: true,
120
156
  };
121
157
  }
122
158
  export function registerRevise(server) {
@@ -1 +1 @@
1
- {"version":3,"file":"revise.js","sourceRoot":"","sources":["../../../../src/mcp/tools/revise.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EACL,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,GAAG;IAClB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;IACxE,GAAG,EAAE,CAAC;SACH,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,+CAA+C,CAAC;CAC7D,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAGnC;IACK,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACvC,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAExD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,KAAK,EAAE,sBAAsB,KAAK,CAAC,UAAU,EAAE;qBAChD,CAAC;iBACH;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QACnC,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,KAAK,EAAE,sBAAsB,OAAO,CAAC,MAAM,yBAAyB;qBACrE,CAAC;iBACH;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;QACrC,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,KAAK,EACH,0EAA0E;wBAC5E,YAAY,EAAE,QAAQ;qBACvB,CAAC;iBACH;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IACnC,MAAM,eAAe,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9D,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,KAAK,EAAE,+BAA+B,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE;qBACjE,CAAC;iBACH;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED,MAAM,aAAa,GAAG;QACpB,GAAG,MAAM;QACT,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,gBAAgB,CACnC,OAAO,EACP,GAAG,EACH,aAAa,EACb,eAAe,CAChB,CAAC;IAEF,gEAAgE;IAChE,MAAM,UAAU,GAAG,qBAAqB,CACtC,OAAO,EACP,GAAG,EACH,aAAa,EACb,oBAAoB,CACrB,CAAC;IAEF,kEAAkE;IAClE,kEAAkE;IAClE,iEAAiE;IACjE,6DAA6D;IAC7D,cAAc;IACd,MAAM,kBAAkB,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,CACzD,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,MAAM,KAAK,UAAU;QACvB,wBAAwB,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,CACnD,CAAC,MAAM,CAAC;IAET,MAAM,OAAO,GAA4B;QACvC,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,SAAS;QACpC,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,mBAAmB,EAAE,kBAAkB;QACvC,YAAY,EAAE,MAAM,CAAC,WAAW;QAChC,WAAW,EAAE,UAAU;KACxB,CAAC;IACF,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IACjC,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO,CAAC,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC;QACnD,IAAI,MAAM,CAAC,KAAK,CAAC,aAAa,KAAK,OAAO,EAAE,CAAC;YAC3C,OAAO,CAAC,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC;YACvD,OAAO,CAAC,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC;YACnD,OAAO,CAAC,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC;YACjD,OAAO,CAAC,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC;YACvD,OAAO,CAAC,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC;QACrD,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,UAAU;aACjB;YACD;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;aAC9B;SACF;KACF,CAAC;AACR,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAiB;IAC9C,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB,+JAA+J,EAC/J,WAAW,EACX,aAAa,CACd,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"revise.js","sourceRoot":"","sources":["../../../../src/mcp/tools/revise.ts"],"names":[],"mappings":"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"}