Skip to content

refactor: extract VersionControlProvider abstraction#548

Open
pfitz wants to merge 23 commits into
mattpocock:mainfrom
pfitz:implement/vcs-abstraction
Open

refactor: extract VersionControlProvider abstraction#548
pfitz wants to merge 23 commits into
mattpocock:mainfrom
pfitz:implement/vcs-abstraction

Conversation

@pfitz
Copy link
Copy Markdown

@pfitz pfitz commented May 5, 2026

Summary

Pure refactor that extracts a VersionControlProvider interface from sandcastle's git-shaped code. Zero behavior change for existing callers.

The change adds an optional vcs option to run(), interactive(), createSandbox(), and createWorktree(), defaulting to a git() implementation that mirrors current behavior. The interface is the seam through which alternative VCS backends (such as Jujutsu, in a follow-up PR) can be implemented.

Motivation

I personally use Jujutsu (jj) for development and would like to use jj workspaces instead of git worktrees with sandcastle. This PR is the foundation refactor; a follow-up PR will add a `JjProvider` for jj-colocated repos. I figured a proper pluggable abstraction would benefit other users of alternative VCS tools too.

What's in this PR

  • `src/VersionControl.ts` — new `VersionControlProvider` interface, one method per logical VCS operation
  • `src/vcs/git.ts` — `git()` factory implementing the interface; methods delegate to existing `WorktreeManager`, `syncIn`/`syncOut` helpers, and `resolveGitMounts`
  • `src/vcs/git.test.ts` — 30 tests covering the provider against real git in temp repos
  • All call sites in `SandboxFactory.ts`, `SandboxLifecycle.ts`, `syncIn.ts`, `syncOut.ts`, `RecoveryMessage.ts`, `Orchestrator.ts`, `createSandbox.ts`, `createWorktree.ts`, `interactive.ts`, `run.ts` updated to dispatch through the new `vcs` option
  • Subpath export: `import { git } from "@ai-hero/sandcastle/vcs/git"`
  • Patch-level changeset

What's NOT in this PR (deferred to PR 2)

  • The `JjProvider` itself
  • jj integration tests / CI changes
  • Interface JSDoc clarifying jj-specific contracts on `headRef`, `currentBranch`, `hasUncommittedChanges`

A design plan with the full feasibility analysis is committed at `docs/superpowers/plans/2026-05-05-vcs-abstraction-pr1-refactor.md`. Happy to drop it from the diff if you'd prefer a smaller PR — let me know.

Notes on the diff size

  • Most new lines are in test code (`src/vcs/git.test.ts` ≈ 480 lines, 30 tests) and the design plan markdown (~910 lines).
  • The actual abstraction is ~250 lines (`VersionControl.ts` + `vcs/git.ts`).
  • Net call-site refactoring is mechanical — replacing direct `WorktreeManager.create(...)`-style calls with `vcs.createCheckout(...)` etc.

Test plan

  • `npm run typecheck` passes (verified locally — clean)
  • `npm test` passes (existing tests unchanged, 30 new tests in `git.test.ts` all pass)
  • `npm run build` produces `dist/vcs/git.{js,d.ts}` and `dist/VersionControl.{js,d.ts}` (verified)
  • Importing `@ai-hero/sandcastle/vcs/git` works after publish

Security note

Several command-builder methods in `git.ts` produce shell command strings that get executed via `handle.exec(...)` inside sandboxes. All user-influenced values are escaped with a POSIX single-quote helper (`shellSingleQuote`) to prevent shell injection. The helper is exported for reuse by future backends.

Friedrich Pfitzmann added 23 commits May 5, 2026 08:01
@vercel
Copy link
Copy Markdown

vercel Bot commented May 5, 2026

Someone is attempting to deploy a commit to the Matt Pocock's projects Team on Vercel.

A member of the Team first needs to authorize it.

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