import { promises as fs } from 'node:fs'; import { dirname, isAbsolute, join, resolve } from 'node:path'; /** Resolve an ACP path against the agent worktree and read a slice of lines. */ export async function readWorktreeTextFile( worktreePath: string, filePath: string, line?: number | null, limit?: number | null, ): Promise { const absolute = isAbsolute(filePath) ? filePath : resolve(worktreePath, filePath); if (!absolute.startsWith(resolve(worktreePath))) { throw new Error(`path escapes worktree: ${filePath}`); } const raw = await fs.readFile(absolute, 'utf8'); if (!line && !limit) return raw; const lines = raw.split(/\r?\n/); const start = Math.max((line ?? 1) - 1, 0); const end = limit ? start + limit : undefined; return lines.slice(start, end).join('\n'); } /** Write a file inside the worktree (creates parent dirs). */ export async function writeWorktreeTextFile( worktreePath: string, filePath: string, content: string, ): Promise { const absolute = isAbsolute(filePath) ? filePath : resolve(worktreePath, filePath); if (!absolute.startsWith(resolve(worktreePath))) { throw new Error(`path escapes worktree: ${filePath}`); } await fs.mkdir(dirname(absolute), { recursive: true }); await fs.writeFile(absolute, content, 'utf8'); }