Skip to content

fix(workspace): land delete_path impl + ability registration missed by #65#66

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

fix(workspace): land delete_path impl + ability registration missed by #65#66
chubes4 merged 1 commit into
mainfrom
fix/workspace-delete-completion

Conversation

@chubes4
Copy link
Copy Markdown
Member

@chubes4 chubes4 commented Apr 25, 2026

Summary

Follow-up to #65, which shipped the wp datamachine-code workspace delete CLI subcommand but only the subcommand. The ability registration in WorkspaceAbilities.php and the delete_path() method in Workspace.php were silently dropped from the original commit.

Without this fix, wp datamachine-code workspace delete <repo> <path> errors with Workspace delete ability not available. because the CLI calls wp_get_ability('datamachine/workspace-delete') which isn't registered.

Root cause

The original git add --rel=A --rel=B --rel=C call against the workspace API only staged the first path silently. The CLI returned "Paths staged successfully" but git diff --cached confirmed only one file was staged. The other two files stayed dirty in the worktree, were never committed, and so never made it into the merged squash.

I'll file a separate DMC issue for the repeatable---rel bug; the workaround for now is one --rel per git add call.

What this PR adds

  • Workspace::delete_path() (~115 LOC) — sits next to git_add and reuses its 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.
  • datamachine/workspace-delete ability registration in WorkspaceAbilities.php — input/output schemas, callback wiring to deletePath, and the deletePath static method.

Verification (live on intelligence-chubes4 — same scenarios as #65)

  • Untracked file → unlink (1 path removed). ✓
  • Tracked file → staged D entry in git status. ✓
  • Directory without --recursivedirectory_requires_recursive error. ✓
  • Directory with --recursive → recursive unlink (N paths removed). ✓
  • Sensitive path (.env) → sensitive_path error. ✓
  • Path traversal (../escape) → invalid_path error. ✓
  • Absolute 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. ✓

AI assistance

  • AI assistance: Yes
  • Tool(s): Claude Code (Sonnet 4.5)
  • Used for: Spotting the missing pieces after pulling main locally to use the new primitive in a downstream homeboy refactor; identifying the --rel repeatable-stage bug as the root cause; reconstructing the dropped commit. Chris reviewed the missing-files framing and authorized the fix-up PR.

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.

1 participant