add support for -w,--writable-root to add more writable roots for sandbox (#263)

This adds support for a new flag, `-w,--writable-root`, that can be
specified multiple times to _amend_ the list of folders that should be
configured as "writable roots" by the sandbox used in `full-auto` mode.
Values that are passed as relative paths will be resolved to absolute
paths.

Incidentally, this required updating a number of the `agent*.test.ts`
files: it feels like some of the setup logic across those tests could be
consolidated.

In my testing, it seems that this might be slightly out of distribution
for the model, as I had to explicitly tell it to run `apply_patch` and
that it had the permissions to write those files (initially, it just
showed me a diff and told me to apply it myself). Nevertheless, I think
this is a good starting point.
This commit is contained in:
Michael Bolin
2025-04-17 15:39:26 -07:00
committed by GitHub
parent d5eed65963
commit ae5b1b5cb5
22 changed files with 103 additions and 13 deletions

View File

@@ -37,6 +37,7 @@ type Props = {
prompt?: string;
imagePaths?: Array<string>;
approvalPolicy: ApprovalPolicy;
additionalWritableRoots: ReadonlyArray<string>;
fullStdout: boolean;
};
@@ -122,6 +123,7 @@ export default function TerminalChat({
prompt: _initialPrompt,
imagePaths: _initialImagePaths,
approvalPolicy: initialApprovalPolicy,
additionalWritableRoots,
fullStdout,
}: Props): React.ReactElement {
const [model, setModel] = useState<string>(config.model);
@@ -183,6 +185,7 @@ export default function TerminalChat({
config,
instructions: config.instructions,
approvalPolicy,
additionalWritableRoots,
onLastResponseId: setLastResponseId,
onItem: (item) => {
log(`onItem: ${JSON.stringify(item)}`);
@@ -248,7 +251,13 @@ export default function TerminalChat({
agentRef.current = undefined;
forceUpdate(); // rerender after teardown too
};
}, [model, config, approvalPolicy, requestConfirmation]);
}, [
model,
config,
approvalPolicy,
requestConfirmation,
additionalWritableRoots,
]);
// whenever loading starts/stops, reset or start a timer — but pause the
// timer while a confirmation overlay is displayed so we don't trigger a