Skip to content

feat(workspace): add delete primitive (workspace-delete ability + CLI)#65

Merged
chubes4 merged 1 commit into
mainfrom
feat/workspace-delete
Apr 25, 2026
Merged

feat(workspace): add delete primitive (workspace-delete ability + CLI)#65
chubes4 merged 1 commit into
mainfrom
feat/workspace-delete

Conversation

@chubes4
Copy link
Copy Markdown
Member

@chubes4 chubes4 commented Apr 25, 2026

Summary

Closes #64. Fills a gap where agents had to drop out of the workspace API to remove tracked files (the git rm / rm -rf workaround that bypassed containment, sensitive-path, allowlist, and primary-mutation gates).

New ability datamachine/workspace-delete plus a wp datamachine-code workspace delete <repo> <path> CLI subcommand. Tracked paths are removed via git rm so the deletion lands in working tree and index in one shot. Untracked paths are unlinked from disk; directories require --recursive.

What's added

  • Workspace::delete_path() (inc/Workspace/Workspace.php) — sits next to git_add and reuses its existing gate ladder: traversal, sensitive-path, allowlist, primary-mutation. Detects tracked vs untracked via git ls-files --error-unmatch and dispatches to either git rm [-r] or a recursive filesystem unlink.
  • Workspace::remove_directory_recursive() — private helper that walks an untracked directory deepest-first and reports every removed entry.
  • datamachine/workspace-delete ability (inc/Abilities/WorkspaceAbilities.php) — input { repo, path, recursive?, allow_primary_mutation? }, output { success, name, repo, path, deleted[], was_tracked }. Description and category match the existing workspace abilities.
  • wp datamachine-code workspace delete subcommand (inc/Cli/Commands/WorkspaceCommand.php) — same docblock + @subcommand shape as edit/write.

Why a single primitive

Splitting into delete-file + delete-directory doubles the surface for no gain. recursive flag covers directories and makes accidental recursive deletes opt-in (rejecting directories without recursive=true matches POSIX rm semantics).

Verification (live on intelligence-chubes4)

  • Untracked file: delete homeboy@<branch> tmp.txtunlink (1 path removed). ✓
  • Tracked file: created → committed → deletegit status showed staged D entry. ✓
  • Directory without --recursivedirectory_requires_recursive error. ✓
  • Directory with --recursiveunlink (4 paths removed) (file + nested file + subdir + dir). ✓
  • Sensitive path (.env) → sensitive_path error. ✓
  • Path traversal (../escape) → invalid_path error. ✓
  • Absolute path (/abs/path) → invalid_path error. ✓
  • Primary checkout without override → primary_mutation_not_allowed error. ✓
  • Primary checkout with --allow-primary-mutation → succeeds. ✓
  • Path not found → not_found (404) error. ✓

Out of scope

  • No glob/pattern support — agents enumerate paths themselves. Consistent with git_add.
  • No "soft delete" / trash semantics — git history is the undo path.
  • No batch ability workspace-delete-many — agents can call once per path. Add later if it becomes a real need.

AI assistance

  • AI assistance: Yes
  • Tool(s): Claude Code (Sonnet 4.5)
  • Used for: Drafting the gap issue (feat(workspace): add delete primitive (workspace-delete ability + CLI) #64), implementing the ability + CLI by mirroring git_add / workspace edit shapes, and live-smoke-testing every gate path on intelligence-chubes4. Chris reviewed the gap framing and authorized the upstream-first fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(workspace): add delete primitive (workspace-delete ability + CLI)

1 participant