You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As a user,
I want a tool for removing directories,
so that the LLM can manage the filesystem directly from within Tomo without escaping into run_command rm -rf.
Acceptance Criteria
Tool shape
New remove_dir tool registered alongside existing tools at src/tools/remove-dir.ts, follows existing tool patterns (zod schema, Tool interface, colocated test file, registered in src/app.tsx)
Tool description explains: removes a directory, non-recursive by default (fails on non-empty), recursive: true removes the entire tree, recursive removes always prompt regardless of permission state
formatCall returns path for non-recursive removes and path (recursive) for recursive removes so the collapsed tool header shows the mode
New entry in toolsSchema in src/config/schema.ts so the tool can be enabled/disabled (default enabled: true)
Permissions
New permission keys added to permissionsSchema in src/config/schema.ts:
cwdRemoveDir (default false) — allows removing empty directories within the cwd without confirmation
globalRemoveDir (default false) — allows removing empty directories outside the cwd without confirmation
Permission check uses the existing isPathWithinCwd helper from src/tools/permissions.ts
Permissions only apply to non-recursive removes. Recursive removes always prompt regardless of permission state — the permission flag is not authorization for arbitrary tree removal, only for the safe single-empty-dir case.
Confirmation
Non-recursive removes (recursive: false): if the relevant permission is granted, skip the prompt; otherwise prompt with the resolved path (label "Remove directory?")
Recursive removes (recursive: true): always prompt with the resolved path and a label that visibly signals the higher blast radius (e.g. "Remove directory recursively?"). Independent of any permission state.
User denial returns a denied result; flow follows the same pattern as write-file.ts
Validation and behaviour
Errors clearly when the path does not exist
Errors clearly when the path is a file (suggest remove_file)
Non-recursive mode: errors clearly when the directory is not empty, suggesting recursive: true
Recursive mode: removes the entire tree
Errors clearly on permission/IO errors from the OS
On success, returns a plain ok result confirming the path was removed (and notes recursive if applicable)
Tests
Mock the filesystem at the boundary; do not mock internal helpers
Non-recursive behaviour: removes empty dir in cwd, removes empty dir outside cwd, errors on non-empty dir, errors on missing path, errors on file path
Recursive behaviour: removes a populated tree, errors on missing path, errors on file path
Permissions (non-recursive): cwd granted skips confirm, cwd ungranted prompts, denial returns denied; same set for global
Permissions (recursive): cwd granted still prompts, global granted still prompts — recursive always prompts regardless of permission state
Confirmation prompt shape: non-recursive uses standard label, recursive uses a distinct label/detail that signals tree removal
Additional Context
Pairs with #252 (remove_file). Together they cover the destructive filesystem operations the LLM currently has to do via run_command rm / rm -rf, which is awkward (shell quoting, cross-platform inconsistency) and noisy (confirmation per call).
The split between non-recursive and recursive is deliberate. Non-recursive is essentially safe — it fails on non-empty, has single-directory blast radius, and can be permission-gated for cwd-scoped trust the same way file writes are. Recursive is meaningfully destructive — entire tree, easy to point at the wrong path, hard to undo — and so always requires explicit per-call confirmation regardless of permission state. The permission flag is not authorization for "delete anything you want", only for "skip the prompt on the safe single-empty-dir case".
Implementation references:
src/tools/write-file.ts for the permission + confirm flow shape
src/tools/permissions.ts for checkFilePermission and isPathWithinCwd
src/config/schema.ts:19 for the permissions schema where the new keys go
User Story
As a user,
I want a tool for removing directories,
so that the LLM can manage the filesystem directly from within Tomo without escaping into
run_command rm -rf.Acceptance Criteria
Tool shape
remove_dirtool registered alongside existing tools atsrc/tools/remove-dir.ts, follows existing tool patterns (zod schema,Toolinterface, colocated test file, registered insrc/app.tsx)path(required),recursive(optional boolean, defaultfalse)recursive: trueremoves the entire tree, recursive removes always prompt regardless of permission stateformatCallreturnspathfor non-recursive removes andpath (recursive)for recursive removes so the collapsed tool header shows the modetoolsSchemainsrc/config/schema.tsso the tool can be enabled/disabled (defaultenabled: true)Permissions
permissionsSchemainsrc/config/schema.ts:cwdRemoveDir(defaultfalse) — allows removing empty directories within the cwd without confirmationglobalRemoveDir(defaultfalse) — allows removing empty directories outside the cwd without confirmationisPathWithinCwdhelper fromsrc/tools/permissions.tsConfirmation
recursive: false): if the relevant permission is granted, skip the prompt; otherwise prompt with the resolved path (label "Remove directory?")recursive: true): always prompt with the resolved path and a label that visibly signals the higher blast radius (e.g. "Remove directory recursively?"). Independent of any permission state.deniedresult; flow follows the same pattern aswrite-file.tsValidation and behaviour
remove_file)recursive: trueokresult confirming the path was removed (and notes recursive if applicable)Tests
denied; same set for globalAdditional Context
Pairs with #252 (
remove_file). Together they cover the destructive filesystem operations the LLM currently has to do viarun_command rm/rm -rf, which is awkward (shell quoting, cross-platform inconsistency) and noisy (confirmation per call).The split between non-recursive and recursive is deliberate. Non-recursive is essentially safe — it fails on non-empty, has single-directory blast radius, and can be permission-gated for cwd-scoped trust the same way file writes are. Recursive is meaningfully destructive — entire tree, easy to point at the wrong path, hard to undo — and so always requires explicit per-call confirmation regardless of permission state. The permission flag is not authorization for "delete anything you want", only for "skip the prompt on the safe single-empty-dir case".
Implementation references:
src/tools/write-file.tsfor the permission + confirm flow shapesrc/tools/permissions.tsforcheckFilePermissionandisPathWithinCwdsrc/config/schema.ts:19for the permissions schema where the new keys go