feat: persistent per-chat sessions for code-mode coding agents

- Use a named acpx session (rowboat-<runId>) per chat so follow-up
  coding requests resume the same agent and keep context
- Create the session once at chat start (sessions new --name), then
  prompt with -s <name>; reuse on follow-ups (no re-create)
- Drop the redundant in-chat 'reply yes' confirmation (the executeCommand
  permission card is the confirmation)
- Code-mode output uses plain-text paths (overrides global filepath rule)
- On not-installed/auth errors, point user to Settings -> Code Mode
This commit is contained in:
Gagancreates 2026-05-25 21:13:25 +05:30
parent c0d0c285fe
commit ca35eddce0
2 changed files with 67 additions and 18 deletions

View file

@ -1320,6 +1320,10 @@ Do not announce the work directory unless it's relevant. Just use it.`;
const agentDisplay = codeMode === 'claude' ? 'Claude Code' : 'Codex';
const otherAgent = codeMode === 'claude' ? 'codex' : 'claude';
const otherDisplay = codeMode === 'claude' ? 'Codex' : 'Claude Code';
// Deterministic, per-chat session name so the coding agent keeps
// context across the user's requests within this chat. Reusing the
// same -s <name> resumes the session; the first call creates it.
const sessionName = `rowboat-${runId}`;
instructionsWithDateTime += `\n\n# Code Mode (Active) — Default agent: ${agentDisplay}
The user has turned on **code mode** and the composer chip is set to **${agentDisplay}** (\`${codeMode}\`). Use this as the **default** agent for coding tasks in this turn.
@ -1327,13 +1331,27 @@ The user has turned on **code mode** and the composer chip is set to **${agentDi
1. By toggling the chip in the composer (preferred).
2. By asking you directly in chat ("use codex", "switch to claude", "do this with ${otherDisplay}", etc.). When the user explicitly asks to use a different agent in the current message, honor that use \`${otherAgent}\` instead of \`${codeMode}\` for this turn, and briefly mention they can also toggle it via the chip for stickiness.
When you call \`executeCommand\` to run the coding agent, the command shape is:
**Persistent session for this chat session name: \`${sessionName}\`.** This chat uses one named agent session so the agent keeps context across your requests. The session must be created once before it can be used (\`-s\` only resumes; it does not create).
**1. First coding action in this chat create the session:**
\`\`\`
npx acpx@latest --approve-all --cwd <workdir> <agent> exec "<prompt>"
npx acpx@latest --approve-all --cwd <workdir> <agent> sessions new --name ${sessionName}
\`\`\`
Where \`<agent>\` is either \`claude\` or \`codex\` — pick based on (in priority order): an explicit in-chat override → the chip setting (\`${codeMode}\`).
**2. Then run the prompt:**
\`\`\`
npx acpx@latest --approve-all --cwd <workdir> <agent> -s ${sessionName} "<prompt>"
\`\`\`
**3. Every follow-up coding request in this chat reuse the same session (do NOT create again):**
\`\`\`
npx acpx@latest --approve-all --cwd <workdir> <agent> -s ${sessionName} "<prompt>"
\`\`\`
Where \`<agent>\` is either \`claude\` or \`codex\` — pick based on (in priority order): an explicit in-chat override → the chip setting (\`${codeMode}\`). Use \`${sessionName}\` exactly — do NOT invent a different name, and do NOT use \`exec\` (it is one-shot and forgets).
If the user's message is clearly NOT a coding request (small talk, an unrelated question), answer directly without invoking the coding agent. Code mode signals readiness, not that every message must route through the agent.`;
}

View file

@ -46,33 +46,61 @@ This is non-negotiable. The user gets clickable buttons. Free-text "which agent?
2. The path from a "# User Work Directory" block in your context.
3. Ask once in plain text: "Which folder should I work in?"
**Confirm briefly** with the user (one short line):
**State your intent in one line, then execute immediately do NOT wait for a "yes".** The \`executeCommand\` call surfaces a permission card that is itself the user's confirmation, so an extra in-chat "reply yes to proceed" is redundant friction. Say something like:
> I'll use [Claude Code / Codex] to [task description] in \`[folder]\`. Permission requests from the coding agent will be auto-approved. Reply "yes" to proceed.
> Using [Claude Code / Codex] to [task description] in \`[folder]\`.
**Execute** with the chosen agent. Call \`executeCommand\` with this exact shape:
and then immediately make the \`executeCommand\` call in the same turn.
\`\`\`
npx acpx@latest --approve-all --cwd <folder> <agent> exec "<prompt>"
\`\`\`
**Execute** with the chosen agent using a **persistent named session** so follow-up coding requests in this chat resume the same agent and keep context.
Where \`<agent>\` is \`claude\` or \`codex\`, picked by (in priority order):
Pick \`<agent>\` (\`claude\` or \`codex\`) by, in priority order:
- An explicit in-chat override from the user this turn ("use codex", "switch to claude") honor it.
- The agent chosen in Step 1 / the "# Code Mode (Active)" block.
Concrete examples:
Pick \`<session-name>\` — **stable for this whole chat**:
- If the "# Code Mode (Active)" block gives a session name (e.g. \`rowboat-<runId>\`), use that exact name.
- Otherwise pick one short, kebab-case name and **reuse it for every coding call this turn and in follow-ups** never a new name each time.
**\`-s\` resumes an existing session; it does NOT create one.** So create the session once at the start, then prompt:
**1. First coding action in this chat create the session:**
\`\`\`
npx acpx@latest --approve-all --cwd ~/projects/myapp claude exec "fix the off-by-one bug in foo.ts"
npx acpx@latest --approve-all --cwd "G:/4th sem/CN" codex exec "create a C program that divides two numbers with divide-by-zero handling"
npx acpx@latest --approve-all --cwd <folder> <agent> sessions new --name <session-name>
\`\`\`
**2. Then run the prompt:**
\`\`\`
npx acpx@latest --approve-all --cwd <folder> <agent> -s <session-name> "<prompt>"
\`\`\`
**3. Every follow-up coding request in this chat reuse the same session (do NOT create again):**
\`\`\`
npx acpx@latest --approve-all --cwd <folder> <agent> -s <session-name> "<prompt>"
\`\`\`
Do NOT use \`exec\` — it is one-shot and forgets everything.
Concrete example:
\`\`\`
# First coding message in the chat create, then prompt:
npx acpx@latest --approve-all --cwd "G:\\Blogging\\myblog" claude sessions new --name diskspace-check
npx acpx@latest --approve-all --cwd "G:\\Blogging\\myblog" claude -s diskspace-check "Check the system disk space and report total, used, and free space."
# Follow-up in the same chat reuse the session, no create:
npx acpx@latest --approve-all --cwd "G:\\Blogging\\myblog" claude -s diskspace-check "Summarize what we did and the final findings."
\`\`\`
### Critical: flag order
\`--approve-all\` and \`--cwd\` are GLOBAL flags and MUST appear BEFORE the agent name:
\`--approve-all\` and \`--cwd\` are GLOBAL flags and MUST appear BEFORE the agent name. \`sessions new --name <name>\` and \`-s <session-name>\` come AFTER the agent name:
- Correct: \`npx acpx@latest --approve-all --cwd <folder> <agent> exec "<prompt>"\`
- Wrong: \`npx acpx@latest <agent> --approve-all exec "..."\` (will fail)
- Correct: \`npx acpx@latest --approve-all --cwd <folder> <agent> -s <session-name> "<prompt>"\`
- Wrong: \`npx acpx@latest <agent> --approve-all -s <name> "..."\` (will fail)
### Writing good prompts for the agent
@ -86,8 +114,11 @@ npx acpx@latest --approve-all --cwd "G:/4th sem/CN" codex exec "create a C progr
After the command finishes:
- Pass through the coding agent's summary as-is. Do not rewrite.
- Refer to file paths as plain text. Do NOT use \`\`\`file:path\`\`\` reference blocks.
- Only add your own explanation if the command failed (non-zero exit). If exit code is 5, permissions were denied (shouldn't happen with \`--approve-all\` — flag this).
- Refer to file paths as plain text. Do NOT use \`\`\`file:path\`\`\` reference blocks. (This overrides the global "always wrap paths in filepath blocks" rule — for code-mode output, plain text.)
- Only add your own explanation if the command failed (non-zero exit):
- Exit code 5 permissions were denied (shouldn't happen with \`--approve-all\`; flag it).
- Exit code 4 / "No acpx session found" the \`-s <session-name>\` session doesn't exist yet. Create it once with \`npx acpx@latest --cwd <folder> <agent> sessions new --name <session-name>\`, then retry the prompt. (\`-s\` only resumes; it never creates.)
- "command not found" / agent not installed, or an auth/sign-in error the agent isn't set up. Tell the user to install or sign in to the agent via **Settings Code Mode**, where Rowboat shows the install and sign-in status.
---