Gate the new tools, matching a move at both ends

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
Muhammad Zakir Ramadhan
2026-09-05 17:28:18 +07:00
co-authored by Sisyphus
parent e8b8b06a4b
commit 551e518711
2 changed files with 16 additions and 1 deletions
+2
View File
@@ -37,6 +37,8 @@ const READ_ONLY = [
'git_log',
'git_show',
'git_blame',
'git_branch',
'git_commit_message',
'task',
'web_fetch',
'todo_write',
+14 -1
View File
@@ -65,9 +65,18 @@ export function subjectOf(tool: string, input: unknown): string | undefined {
case 'write_file':
case 'edit_file':
case 'multi_edit':
case 'delete_file':
case 'list_dir':
case 'git_blame':
return str('path');
case 'move_file': {
// Both ends matter: a rule denying `src/generated/*` must catch a move that
// lands there as well as one that starts there.
const from = str('from');
const to = str('to');
const both = [from, to].filter((p): p is string => p !== undefined);
return both.length > 0 ? both.join(' ') : undefined;
}
case 'web_fetch':
return str('url');
case 'apply_patch': {
@@ -113,7 +122,7 @@ export function subjectOf(tool: string, input: unknown): string | undefined {
* them: denying `*.env` must catch a batch read that includes one, and denying
* `src/generated/*` must catch a patch that touches one among five files.
*/
const MULTI = new Set(['read_many_files', 'apply_patch']);
const MULTI = new Set(['read_many_files', 'apply_patch', 'move_file']);
const subjectsFor = (tool: string, subject: string): string[] =>
MULTI.has(tool) ? subject.split(' ') : [subject];
@@ -170,6 +179,8 @@ export const DEFAULT_PERMISSIONS: PermissionConfig = {
edit_file: 'ask',
multi_edit: 'ask',
apply_patch: 'ask',
move_file: 'ask',
delete_file: 'ask',
bash: 'ask',
web_fetch: 'ask',
};
@@ -192,6 +203,8 @@ const FREE = new Set([
'git_log',
'git_show',
'git_blame',
'git_branch',
'git_commit_message',
]);
export type PermissionOptions = {