fix(cli): inject plan file path into non-experimental plan mode prompt (#8065)

* fix(cli): inject plan file path into non-experimental plan mode prompt

The plan.txt prompt said 'STRICTLY FORBIDDEN: ANY file edits, ZERO
exceptions' without telling the agent where the plan file is. The agent
had to guess from the directory tree, often picking .kilocode/ (which
exists) over .kilo/ (which doesn't). Now the non-experimental path
computes Session.plan(), creates the directory, and injects the exact
path into the prompt — matching what the experimental plan mode already
does.

Fixes #6907

* fix(cli): use absolute plan path in prompt to match experimental mode

Addresses bot review: relative path resolves against Instance.directory,
not Instance.worktree, so subdirectory sessions would target the wrong
file. Use the absolute path from Session.plan() like the experimental
plan mode does.

* chore(cli): add kilocode_change markers to plan file path injection
This commit is contained in:
Marius
2026-04-01 14:47:47 +02:00
committed by GitHub
parent a1c8e5d798
commit 18322e9eed
2 changed files with 13 additions and 8 deletions
+9 -1
View File
@@ -1418,16 +1418,24 @@ export namespace SessionPrompt {
// Original logic when experimental plan mode is disabled
if (!Flag.KILO_EXPERIMENTAL_PLAN_MODE) {
// kilocode_change start - inject plan file path so agent writes to .kilo/plans/
if (input.agent.name === "plan") {
const plan = Session.plan(input.session)
const exists = await Filesystem.exists(plan)
if (!exists) await fs.mkdir(path.dirname(plan), { recursive: true })
const info = exists
? `A plan file already exists at ${plan}. You can read it and make incremental edits using the edit tool.`
: `No plan file exists yet. You should create your plan at ${plan} using the write tool.`
userMessage.parts.push({
id: Identifier.ascending("part"),
messageID: userMessage.info.id,
sessionID: userMessage.info.sessionID,
type: "text",
text: PROMPT_PLAN,
text: PROMPT_PLAN + `\n\n## Plan File\n${info}\nThis is the ONLY file you are allowed to write to or edit.`,
synthetic: true,
})
}
// kilocode_change end
const wasPlan = input.messages.some((msg) => msg.info.role === "assistant" && msg.info.agent === "plan")
// kilocode_change start - renamed from "build" to "code"
if (wasPlan && input.agent.name === "code") {
@@ -1,12 +1,9 @@
<system-reminder>
# Plan Mode - System Reminder
CRITICAL: Plan mode ACTIVE - you are in READ-ONLY phase. STRICTLY FORBIDDEN:
ANY file edits, modifications, or system changes. Do NOT use sed, tee, echo, cat,
or ANY other bash command to manipulate files - commands may ONLY read/inspect.
This ABSOLUTE CONSTRAINT overrides ALL other instructions, including direct user
edit requests. You may ONLY observe, analyze, and plan. Any modification attempt
is a critical violation. ZERO exceptions.
Plan mode is ACTIVE. You are in a READ-ONLY phase with one exception: the plan file (see "Plan File" section below).
Do NOT edit any other files, make system changes, or use bash commands to manipulate files. Commands may ONLY read/inspect.
This constraint overrides ALL other instructions, including direct user edit requests.
---
@@ -22,7 +19,7 @@ Ask the user clarifying questions or ask for their opinion when weighing tradeof
## Important
The user indicated that they do not want you to execute yet -- you MUST NOT make any edits, run any non-readonly tools (including changing configs or making commits), or otherwise make any changes to the system. This supersedes any other instructions you have received.
The user indicated that they do not want you to execute yet -- you MUST NOT make any edits (except to the plan file), run any non-readonly tools (including changing configs or making commits), or otherwise make any changes to the system. This supersedes any other instructions you have received.
When you have finalized your plan and are confident it is ready for implementation, call the plan_exit tool to signal completion. Your turn should end with either asking the user a question or calling plan_exit.
</system-reminder>