@@ -51,6 +51,23 @@ public static function projected_tools(): array {
5151 'workspace_read ' => self ::workspace ('datamachine-code/workspace-read ' ),
5252 'workspace_grep ' => self ::workspace ('datamachine-code/workspace-grep ' ),
5353
54+ 'workspace_write ' => self ::workspace_write ('datamachine-code/workspace-write ' ),
55+ 'workspace_edit ' => self ::workspace_write ('datamachine-code/workspace-edit ' ),
56+ 'workspace_apply_patch ' => self ::workspace_write ('datamachine-code/workspace-apply-patch ' ),
57+ 'workspace_delete ' => self ::workspace_write ('datamachine-code/workspace-delete ' ),
58+ 'workspace_git_status ' => self ::workspace_write ('datamachine-code/workspace-git-status ' ),
59+ 'workspace_git_log ' => self ::workspace_write ('datamachine-code/workspace-git-log ' ),
60+ 'workspace_git_diff ' => self ::workspace_write ('datamachine-code/workspace-git-diff ' ),
61+ 'workspace_git_pull ' => self ::workspace_write ('datamachine-code/workspace-git-pull ' ),
62+ 'workspace_git_add ' => self ::workspace_write ('datamachine-code/workspace-git-add ' ),
63+ 'workspace_git_commit ' => self ::workspace_write ('datamachine-code/workspace-git-commit ' ),
64+ 'workspace_git_push ' => self ::workspace_write ('datamachine-code/workspace-git-push ' ),
65+ 'workspace_git_rebase ' => self ::workspace_write ('datamachine-code/workspace-git-rebase ' ),
66+ 'workspace_git_reset ' => self ::workspace_write ('datamachine-code/workspace-git-reset ' ),
67+ 'workspace_worktree_add ' => self ::workspace_write ('datamachine-code/workspace-worktree-add ' ),
68+ 'workspace_pr_status ' => self ::workspace_write ('datamachine-code/workspace-pr-status ' ),
69+ 'workspace_pr_rebase ' => self ::workspace_write ('datamachine-code/workspace-pr-rebase ' ),
70+
5471 'list_github_issues ' => self ::github ('datamachine-code/list-github-issues ' ),
5572 'get_github_issue ' => self ::github ('datamachine-code/get-github-issue ' ),
5673 'list_github_pulls ' => self ::github ('datamachine-code/list-github-pulls ' ),
@@ -80,6 +97,23 @@ private static function workspace( string $ability ): array {
8097 );
8198 }
8299
100+ /**
101+ * Build a mutating workspace projection declaration.
102+ *
103+ * Write/git workspace tools require explicit opt-in (via `allow_only` or an
104+ * allow-mode tool policy) before they are exposed to a model request, so a
105+ * read-only inspection task never receives file-mutating tools by default.
106+ *
107+ * @return array<string,mixed>
108+ */
109+ private static function workspace_write ( string $ ability ): array {
110+ return array (
111+ 'ability ' => $ ability ,
112+ 'modes ' => array ( 'chat ' , 'pipeline ' ),
113+ 'requires_opt_in ' => true ,
114+ );
115+ }
116+
83117 /**
84118 * Build a GitHub projection declaration.
85119 *
0 commit comments