Commit Graph

353 Commits

Author SHA1 Message Date
7daf2d87a5 Set max effort level for Claude invocations 2026-03-30 12:50:55 -07:00
6e2b817887 0.0.47 2026-03-25 10:26:45 -07:00
f50d8eb90e Deduplicate repos in loadAll to prevent repeated sessions
Symlinks or multiple entries can resolve to the same repoRoot,
causing duplicate sessions in the returned list.
2026-03-25 10:26:35 -07:00
9f54ec9d51 0.0.46 2026-03-23 21:35:28 -07:00
e71ba84cc0 Sort repositories alphabetically by name in list --all output 2026-03-23 21:35:20 -07:00
d402a3f980 Derive repo name from repoRoot instead of storing it separately
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.
2026-03-23 21:20:44 -07:00
99b0fc0f12 Add config command and replace project registry with filesystem discovery
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>
2026-03-23 18:27:09 -07:00
491c6d7eab Skip clearing stale reviews when VM is not running
Avoids unnecessary cleanup when there is no VM to reconcile against
2026-03-23 18:27:09 -07:00
4574749cde Fix prompt truncation edge case and harden global state handling
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.
2026-03-23 18:27:09 -07:00
da7adc674d Fix lock race condition, scan depth off-by-one, and minor cleanups
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>
2026-03-23 18:27:09 -07:00
965f233245 Simplify session status tracking with identity-keyed Map
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>
2026-03-23 18:27:09 -07:00
3ba27c80b4 Simplify list command and inline resolveAllStatuses
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>
2026-03-23 18:27:09 -07:00
e5f1de4717 Remove ListSession type and harden lock acquisition
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.
2026-03-23 18:27:09 -07:00
3d07643547 Move ListSession interface to module scope and harden error paths
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>
2026-03-23 18:27:09 -07:00
ac168d3019 Harden and parallelize session listing
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>
2026-03-23 18:27:09 -07:00
c46ad53fa3 Inline stale-review cleanup and fix state-loading bugs
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>
2026-03-23 18:27:09 -07:00
7bea6f376b Harden state management against stale and missing entries
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>
2026-03-23 18:27:09 -07:00
3f8a3839f1 Unify list and list --all into a single code path
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>
2026-03-23 18:27:09 -07:00
e2a76a6ad9 Extract resolveAllStatuses helper and fix stale review detection
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>
2026-03-23 18:27:09 -07:00
f0b2a55c9c Extract shared helpers in list command and add file lock for global registry
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>
2026-03-23 18:27:09 -07:00
751b4773c9 Fix status collisions in multi-repo list and clear stale review flags
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.
2026-03-23 18:27:09 -07:00
5893e07530 Replace filesystem-scanning session discovery with an explicit project registry
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>
2026-03-23 18:27:09 -07:00
f504584ce4 0.0.45 2026-03-20 22:12:05 -07:00
1e928e1603 Remove the Stop hook for activity idle tracking
The idle state is now determined by the absence of activity
heartbeats rather than an explicit hook signal, which is more
reliable when the process exits unexpectedly.
2026-03-20 22:10:23 -07:00
befad9b539 0.0.44 2026-03-20 22:04:01 -07:00
2b25170c0c Handle rebase-in-progress detection via state directories and catch rebase errors
REBASE_HEAD can linger after an interrupted rebase, causing false positives.
Checking rebase-merge/ and rebase-apply/ directories matches how git itself
determines rebase state. Also surface rebase failures in the CLI spinner
instead of letting them propagate as unhandled exceptions.
2026-03-20 22:03:47 -07:00
6175d753f0 0.0.43 2026-03-20 11:12:55 -07:00
a992e2b12e Add fish shell completions for config subcommand keys 2026-03-20 11:12:45 -07:00
84845af28b 0.0.42 2026-03-20 11:02:09 -07:00
f7a8ff6a3c Fix config command to pass actual key instead of hardcoded "memory"
The config command already parsed the key but ignored it when calling
set() and printing the result. Also clarify sync vs async convention
in CLAUDE.md and log invalid memory config instead of silently falling
back.
2026-03-20 10:59:37 -07:00
3b3820f95f Derive config keys from DEFAULTS and enforce minimum memory of 512M
The config command previously maintained a separate key list and used a
switch statement that would need updating for each new key. Deriving
VALID_KEYS from config.DEFAULTS keeps them in sync automatically.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 10:40:22 -07:00
fa077ff8f5 Move validateMemory to config module and harden against bad values
The validator is now reusable by both the CLI config command and
the VM startup path, which falls back to the default if the stored
value is invalid. Also lowers the default memory limit to 16G and
makes config.load() resilient to malformed JSON.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 10:36:48 -07:00
ea1b09dc8e Move config defaults to a shared constant in config.ts
Eliminates duplicated default values and simplifies the config
command by replacing the generic key metadata registry with
direct validation functions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 10:30:39 -07:00
e3e4419933 Refactor config command and fix default memory limit
Move defaults and normalization into KEYS metadata, validate config
file shape on load, and lower default container memory from 32G to 16G.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 10:24:57 -07:00
f7d876776b Add per-user config system with sandlot config command
Allow users to configure container memory limit (default 32G) via
`sandlot config memory <value>` instead of hardcoding it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 10:13:20 -07:00
0f568e69de 0.0.41 2026-03-20 10:02:45 -07:00
6f00cc3556 Add sccache as Rust build cache in container environment
Speeds up repeated cargo builds across sessions by caching
compilation artifacts on the persistent mount.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 10:01:23 -07:00
26c5c3c7b0 0.0.40 2026-03-19 11:56:31 -07:00
727920c206 Change review status icon from ⦿ to ⊛
Improve visual distinction from the saved status icon (●)
2026-03-19 11:56:24 -07:00
f9d3428195 0.0.39 2026-03-19 11:29:30 -07:00
2da22b940a Fix list command to skip empty JSON output and batch stale-review cleanup
Collapse redundant empty-session branch so --json falls through to the
normal serialization path instead of printing "[]" separately. Replace
per-branch load/save loop with a single state cycle to avoid racing
concurrent writes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 11:29:22 -07:00
e8e5b850a0 Fix race conditions in state persistence by reading fresh session before writing
Batch-clearing stale flags in list and blindly writing back the session
in review could clobbер concurrent changes. Use per-session get/set
instead of whole-state load/save, and re-read before clearing in_review.
2026-03-19 11:24:18 -07:00
d10adac712 Replace patchSession with setSession to fix concurrent state writes
The fire-and-forget patchSession calls in list could race with each
other, each reading stale state before writing. Collecting stale
branches and doing a single load-modify-save eliminates the race.
Also emits valid JSON (`[]`) when listing with --json and no sessions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 11:17:41 -07:00
9336deed9c Remove state file locking and simplify review cleanup
The mkdir-based lock was unreliable (stale lock recovery was racy) and
added latency. The atomic rename in save() already prevents corruption,
and concurrent writes to different keys are rare enough to not warrant
the complexity. Also inlines stale review self-healing into the map
callback and collapses the review try/catch/finally into just finally.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 11:11:16 -07:00
bd9d481e81 Add file-based locking to state mutations to prevent concurrent write races
Parallel operations (e.g. stale review cleanup in `list`) could
clobber each other via read-modify-write on the shared state file.
Also fix spinner lifecycle in `review` and simplify empty-list output.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 11:04:33 -07:00
69ba73b3c3 Use patchSession to avoid race conditions in review flag updates
The load-modify-save pattern could overwrite concurrent state changes.
patchSession does an atomic read-patch-write, and the list command now
re-checks activity before clearing stale flags to avoid racing with a
review that just started.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 10:56:50 -07:00
ad90c9dcc1 Fix race condition in stale review flag self-healing
Reload fresh state before saving to avoid overwriting concurrent changes
from other processes between the initial load and the heal write.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 10:47:20 -07:00
2f524da292 Fix stale review flag healing and prevent concurrent state overwrites
Use already-loaded state in list command instead of re-reading. In review
command, patch in_review on fresh state to avoid clobbering concurrent
changes, and skip worktree save in print mode. Remove unused white import
and unnecessary nullish coalescing fallback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 23:55:49 -07:00
99f5a378f1 Fix stale in_review self-healing to run in JSON mode and update local objects before state load 2026-03-18 23:48:09 -07:00
a682539db3 Batch stale review-flag writes and fix review cleanup ordering
Move in_review flag set before try block so it is always visible,
and consolidate per-session state writes into a single batch to
avoid repeated disk I/O during list. Also guard against missing
status entries with fallback defaults.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 23:38:02 -07:00