From 070143682e9417982d722db8f442906b59c24c2d Mon Sep 17 00:00:00 2001 From: can1357 Date: Wed, 1 Jul 2026 20:47:22 +0200 Subject: [PATCH] fix(agent): keep approved plan readable --- packages/coding-agent/src/modes/interactive-mode.ts | 9 ++++----- .../agent-session-plan-reference-compaction.test.ts | 12 +++++++----- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/coding-agent/src/modes/interactive-mode.ts b/packages/coding-agent/src/modes/interactive-mode.ts index 2662f9e5c..6b825bd40 100644 --- a/packages/coding-agent/src/modes/interactive-mode.ts +++ b/packages/coding-agent/src/modes/interactive-mode.ts @@ -2601,11 +2601,10 @@ export class InteractiveMode implements InteractiveModeContext { this.session.clearPlanInternalAbortPending(); } - // Tool restoration runs on every path — the plan mode tools must be - // retired regardless of whether the synthetic prompt fires. - if (previousTools.length > 0) { - await this.session.setActiveToolsByName(previousTools); - } + // Restore the execution tool set, but force-enable `read`: approved-plan + // prompts now require loading the durable local:// plan file before work. + const executionTools = previousTools.includes("read") ? previousTools : [...previousTools, "read"]; + await this.session.setActiveToolsByName(executionTools); this.session.setPlanReferencePath(options.planFilePath); // Resolve the deferred plan-approval model transition. On the compact path diff --git a/packages/coding-agent/test/agent-session-plan-reference-compaction.test.ts b/packages/coding-agent/test/agent-session-plan-reference-compaction.test.ts index b2ba9df04..00705619d 100644 --- a/packages/coding-agent/test/agent-session-plan-reference-compaction.test.ts +++ b/packages/coding-agent/test/agent-session-plan-reference-compaction.test.ts @@ -228,9 +228,10 @@ describe("AgentSession approved-plan reference re-injection after compaction (is emitHighUsageTurn(session); const continuation = await waitForCall(call => call.messageTexts.some(text => text.includes(CONTINUE_MARKER))); - // The post-compaction continuation MUST carry the plan reference again. - expect(continuation.messageTexts.some(text => text.includes(planMarker))).toBe(true); - expect(continuation.messageTexts.some(text => text.includes(``))).toBe(true); + // The post-compaction continuation MUST carry the durable plan reference again. + expect(continuation.messageTexts.some(text => text.includes(planMarker))).toBe(false); + expect(continuation.messageTexts.some(text => text.includes(planUrl))).toBe(true); + expect(continuation.messageTexts.some(text => text.includes(`MUST read \`${planUrl}\``))).toBe(true); }); it("re-injects the approved plan reference after snapcompact auto-compaction", async () => { @@ -251,8 +252,9 @@ describe("AgentSession approved-plan reference re-injection after compaction (is emitHighUsageTurn(session); const continuation = await waitForCall(call => call.messageTexts.some(text => text.includes(CONTINUE_MARKER))); - expect(continuation.messageTexts.some(text => text.includes(planMarker))).toBe(true); - expect(continuation.messageTexts.some(text => text.includes(``))).toBe(true); + expect(continuation.messageTexts.some(text => text.includes(planMarker))).toBe(false); + expect(continuation.messageTexts.some(text => text.includes(planUrl))).toBe(true); + expect(continuation.messageTexts.some(text => text.includes(`MUST read \`${planUrl}\``))).toBe(true); }); // Blast-radius guard: clearing the flag on every compaction must NOT start