The inner coding agent has been rebranded. Update binary
paths, config directories, install scripts, exported
functions, and environment variables accordingly.
Skip unnecessary rollback when reset never happened, show fallback
notice when AI commit message generation fails, and exit non-zero
when squash produces no changes.
Several ecosystem lockfiles (Nix flake, Gradle, npm-shrinkwrap, Swift PM)
were missing from SKIP_RESOLVE, causing unnecessary conflict resolution
attempts. Empty stderr on failure produced confusing error messages.
Add bun.lockb, mix.lock, Pipfile.lock, Podfile.lock, pubspec.lock, and
uv.lock to SKIP_RESOLVE so generated files from additional ecosystems are
auto-resolved with theirs during rebases. Sort entries alphabetically.
Hoist mainBranch lookup before the new-commits check to avoid a
duplicate call, and report clearly when rollback itself fails so
the user knows to consult git reflog.
Covers all common ecosystem lock files (npm, yarn, pnpm, Go, Ruby,
PHP, Poetry) so merge conflicts in any of them are auto-resolved
with --theirs rather than sent to Claude.
The old squash-merge workflow closed the branch, which made it
impossible to keep working after squashing. Now squash uses
git reset --soft to the merge base, preserving all changes as a
single commit on the current branch. Rolls back to the original
HEAD on failure.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of squash-merging into main, `sandlot squash` now soft-resets
to the merge base and recommits, keeping the branch independent.
This removes the --force flag and all squash-merge logic from
mergeAndClose, which goes back to being a plain merge.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The old `stageFile` call discarded non-zero exit codes, hiding issues
like unresolved conflicts or missing files from the caller.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Removing lock files during conflict resolution caused missing dependencies
after the merge. Checking out theirs and staging preserves a valid lockfile.
Lock files like bun.lock and Cargo.lock contain auto-generated content
that Claude cannot meaningfully merge. Remove them during conflict
resolution so they get regenerated cleanly.
Remove the redundant `repo` field from GlobalSession and compute it
via basename(repoRoot) at render time. Also fix prompt truncation
when terminal is extremely narrow, and simplify backfillPrompts to
avoid an intermediate array allocation.
The global registry (registry.json, locking, scan-and-register) was
unnecessary complexity — we can discover repos by scanning ~/.sandlot/
worktree .git pointers. This also moves the --add/--remove flags off
`list` into a proper `config` subcommand for managing settings like
VM memory.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Correct list truncation logic to avoid eliding prompts that already fit,
and gracefully handle narrow terminals. Sanitize project entries on load,
deduplicate registration through a shared registerPaths helper, and
simplify scanAndRegister by reusing it.
Close TOCTOU window in withGlobalLock by retrying mkdir immediately
after removing a stale lock. Fix off-by-one in scanAndRegister where
maxDepth was exceeded by one level. Export normalizePath to eliminate
duplicate logic in list.ts, use a Set for faster dedup in scan, and
simplify the styles map to a plain object literal.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the repoRoot/branch composite-key workaround with a Map keyed
directly by session objects. Also tighten the global lock to properly
throw on acquisition failure and fix prompt truncation at narrow widths.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove generic helper that obscured a three-line call site, flatten
try/catch nesting in backfillPrompts, and push results directly in
loadAll instead of collecting intermediate objects. Also export
normalizePath for use in actionRemove and drop redundant `acquired`
flag from the lock loop.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Consolidate on state.GlobalSession to eliminate redundant interface,
extract clearStaleReviews for clarity, and fix withGlobalLock to
explicitly throw when the lock cannot be acquired instead of
silently proceeding.
Simplify stale-lock recovery to just retry the loop instead of
nesting a second mkdir, and surface lock failures in actionRemove
rather than letting them propagate as unhandled exceptions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace deprecated fs.exists with stat, wrap git calls in try/catch
to gracefully degrade to "idle" for inaccessible worktrees, and load
all projects concurrently in loadAll. Also fix stale-lock retry in
withGlobalLock to re-attempt mkdir immediately after cleanup.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Re-load state before clearing stale reviews to narrow the race window
with concurrent writers. Also fix missing await on withGlobalLock,
remove redundant mkdir and normalizePath calls, and reuse the existing
load() helper instead of duplicating file-reading logic in loadAll().
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The registry lock could spin silently forever on contention, worktrees
could vanish between runs, and loadAll swallowed errors from projects
whose state files were removed. Also skip symlinks during scan to avoid
cycles.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The separate actionAll function duplicated most of the listing logic.
Merging it simplifies status resolution by removing the key/repoRoot
indirection, fixes stale-review detection inline, and batches
scanAndRegister writes into a single lock acquisition. Also bumps the
stale lock timeout to 5 minutes and fixes normalizePath matching bare ~.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move stale review flag outside the vm-running block so sessions
marked in_review are caught even when the VM is stopped. Extract
shared status-resolution logic into resolveAllStatuses to deduplicate
the list and list-all commands. Add stale lock detection to prevent
deadlocks from crashed processes, and include status in JSON output
for list-all.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Deduplicate status resolution, stale-review cleanup, and prompt
backfill between single-repo and all-repo list paths. Protect
the global registry file with a mkdir-based lock to prevent
concurrent read-modify-write races, and add a max-depth guard
to scanAndRegister.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Keying statuses by branch alone caused collisions when multiple repos
shared branch names. Key by repo/branch instead and auto-clear
in_review when Claude is no longer active. Also extract shared
rendering helpers, batch scanAndRegister writes, normalize paths
in the global registry, and move registerProject to setSession.
The old loadAll() walked ~/.sandlot/ and reverse-engineered repo roots
from .git worktree pointers, which was fragile and slow. A simple
registry (~/.sandlot/state.json) tracks known projects explicitly,
with commands to add, remove, and list across all of them.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>