fix: register dynamic-cwd write/read/edit tools for worktree support (#72)
The built-in write, read, and edit tools capture process.cwd() once at startup. When /worktree switch calls process.chdir() into a worktree, these tools still resolve relative paths against the original launch directory. This caused GSD auto-mode to write .gsd/ artifacts to the main project instead of the worktree. The bash tool was already patched with a spawnHook for dynamic CWD. Apply the same pattern to write, read, and edit: each execute() call creates a fresh tool instance with the current process.cwd(), so relative paths always resolve against the active working directory.
This commit is contained in:
parent
2b9451dfd4
commit
bf6fefa16e
1 changed files with 54 additions and 1 deletions
|
|
@ -22,7 +22,7 @@ import type {
|
|||
ExtensionAPI,
|
||||
ExtensionContext,
|
||||
} from "@mariozechner/pi-coding-agent";
|
||||
import { createBashTool } from "@mariozechner/pi-coding-agent";
|
||||
import { createBashTool, createWriteTool, createReadTool, createEditTool } from "@mariozechner/pi-coding-agent";
|
||||
|
||||
import { registerGSDCommand } from "./commands.js";
|
||||
import { registerWorktreeCommand, getWorktreeOriginalCwd, getActiveWorktreeName } from "./worktree-command.js";
|
||||
|
|
@ -102,6 +102,59 @@ export default function (pi: ExtensionAPI) {
|
|||
};
|
||||
pi.registerTool(dynamicBash as any);
|
||||
|
||||
// ── Dynamic-cwd file tools (write, read, edit) ────────────────────────
|
||||
// The built-in file tools capture cwd at startup. When process.chdir()
|
||||
// moves us into a worktree, relative paths still resolve against the
|
||||
// original launch directory. These replacements delegate to freshly-
|
||||
// created tools on each call so that process.cwd() is read dynamically.
|
||||
const baseWrite = createWriteTool(process.cwd());
|
||||
const dynamicWrite = {
|
||||
...baseWrite,
|
||||
execute: async (
|
||||
toolCallId: string,
|
||||
params: { path: string; content: string },
|
||||
signal?: AbortSignal,
|
||||
onUpdate?: any,
|
||||
ctx?: any,
|
||||
) => {
|
||||
const fresh = createWriteTool(process.cwd());
|
||||
return fresh.execute(toolCallId, params, signal, onUpdate, ctx);
|
||||
},
|
||||
};
|
||||
pi.registerTool(dynamicWrite as any);
|
||||
|
||||
const baseRead = createReadTool(process.cwd());
|
||||
const dynamicRead = {
|
||||
...baseRead,
|
||||
execute: async (
|
||||
toolCallId: string,
|
||||
params: { path: string; offset?: number; limit?: number },
|
||||
signal?: AbortSignal,
|
||||
onUpdate?: any,
|
||||
ctx?: any,
|
||||
) => {
|
||||
const fresh = createReadTool(process.cwd());
|
||||
return fresh.execute(toolCallId, params, signal, onUpdate, ctx);
|
||||
},
|
||||
};
|
||||
pi.registerTool(dynamicRead as any);
|
||||
|
||||
const baseEdit = createEditTool(process.cwd());
|
||||
const dynamicEdit = {
|
||||
...baseEdit,
|
||||
execute: async (
|
||||
toolCallId: string,
|
||||
params: { path: string; oldText: string; newText: string },
|
||||
signal?: AbortSignal,
|
||||
onUpdate?: any,
|
||||
ctx?: any,
|
||||
) => {
|
||||
const fresh = createEditTool(process.cwd());
|
||||
return fresh.execute(toolCallId, params, signal, onUpdate, ctx);
|
||||
},
|
||||
};
|
||||
pi.registerTool(dynamicEdit as any);
|
||||
|
||||
// ── session_start: render branded GSD header + remote channel status ──
|
||||
pi.on("session_start", async (_event, ctx) => {
|
||||
const theme = ctx.ui.theme;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue