Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
7a68a98
RT-34: writeJson writes tmp+rename so stores never tear
m4ttheweric Aug 17, 2026
43e0afd
RT-34: worktree registry store (kinds, states, per-repo json)
m4ttheweric Aug 17, 2026
f8fe963
RT-34: async git helpers for the worktree lifecycle (hooks-suppressed…
m4ttheweric Aug 17, 2026
119a6e2
RT-34: drop unused DesktopStashEntry interface from git-async
m4ttheweric Aug 17, 2026
b61db4b
RT-34: name pools + ticket branch derivation (random pick, neutral fa…
m4ttheweric Aug 17, 2026
1b3f45e
RT-34: fix TypeScript errors (noUncheckedIndexedAccess + unused vars)
m4ttheweric Aug 17, 2026
d81b8fd
RT-34: fix slug capping, collision retry, and strengthen tests
m4ttheweric Aug 17, 2026
4111aa3
RT-34: worktree config (repo overlay defaults, install ladder, app-le…
m4ttheweric Aug 17, 2026
c94deee
RT-34: tighten resolveReadySteps dedup to install-step match only
m4ttheweric Aug 17, 2026
ddfbd35
RT-34: ready-step engine (changed-glob triggers, long-timeout runner)
m4ttheweric Aug 17, 2026
c0d7718
RT-34: in-memory per-tree operation locks
m4ttheweric Aug 17, 2026
46d3fb6
RT-34: fix stale-release vulnerability with symbol-based ownership to…
m4ttheweric Aug 17, 2026
3f0e91d
RT-34: cold create (registry-first creating state, scrap-on-failure)
m4ttheweric Aug 17, 2026
dc0266f
RT-34: dispose guard (generated-drift tolerant, MR-sha anchor, lease-…
m4ttheweric Aug 17, 2026
a998795
RT-34: dispose fixes (fail-closed status, sha-absent anchor fallback,…
m4ttheweric Aug 17, 2026
318c5b9
RT-34: registry reconcile pass (ground-truth branches, unmanaged adop…
m4ttheweric Aug 17, 2026
f7ba64b
RT-34: merge reactor (MR-keyed fired store, real retry, auto-return +…
m4ttheweric Aug 17, 2026
60a361b
RT-34: reactor review fixes — vet the auto-return destination before …
m4ttheweric Aug 17, 2026
f076734
RT-34: freshen + replenish/shrink; reconciler kicks detached from cac…
m4ttheweric Aug 17, 2026
4c1bc69
RT-34: revalidate under lock, restore stash fallback, close review round
m4ttheweric Aug 17, 2026
4919df7
RT-34: daemon worktree verbs (provision matrix, owner sweeps, adopt)
m4ttheweric Aug 18, 2026
ba95ab6
RT-34: cover provision branch-state matrix for local branches
m4ttheweric Aug 18, 2026
a815f16
RT-34: tighten provision claim revalidation and surface degraded read…
m4ttheweric Aug 18, 2026
f242049
RT-34: rt worktree CLI (provision/create/dispose/list/freshen/adopt, …
m4ttheweric Aug 18, 2026
1ff927a
RT-34: fix worktree CLI review findings (timeouts, dispose exit code,…
m4ttheweric Aug 18, 2026
8a07cbc
RT-34: delete the parking lot (replaced by the worktree lifecycle)
m4ttheweric Aug 18, 2026
e144347
RT-34: fix e2e picker-identity regression from the rt worktree shell-…
m4ttheweric Aug 18, 2026
ab52489
RT-34: final-review fixes — cross-pass create backoff, merged-MR sha …
m4ttheweric Aug 18, 2026
9bade79
RT-34: PR review fixes — fail-closed worktree listing, tilde roots, t…
m4ttheweric Aug 18, 2026
841b974
RT-34: reconcile epoch check — stale-snapshot save can no longer clob…
m4ttheweric Aug 18, 2026
292739b
RT-34: assert exact epoch increments in the registry test
m4ttheweric Aug 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions commands/cd.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -52,6 +52,12 @@ const SHELL_FUNCTION = [
` elif [ "$1" = "nav" ]; then`,
` local dir`,
` dir="$(COLUMNS=$COLUMNS "$rt_bin" nav "\${@:2}")" && [ -n "$dir" ] && builtin cd "$dir"`,
` elif [ "$1" = "worktree" ] && [ -z "$2" ]; then`,
` # Bare 'rt worktree' is the nav picker (same contract as cd/nav) — jump`,
` # into the selected tree. 'rt worktree <subcommand>' passes straight`,
` # through below.`,
` local dir`,
` dir="$(COLUMNS=$COLUMNS "$rt_bin" worktree)" && [ -n "$dir" ] && builtin cd "$dir"`,
` elif [ "$1" = "x" ]; then`,
` "$rt_bin" "$@"`,
` local rt_cwd`,
Expand DownExpand Up@@ -79,7 +85,13 @@ async function ensureShellFunction(): Promise<void> {
} catch { /* no rc file yet */ }

// Latest version marker: whence -p / type -P PATH-only lookup (fixes FUNCNEST recursion)
if (rcContent.includes('rt() {') && rcContent.includes('whence -p rt') && rcContent.includes('"$rt_bin" nav')) return;
// + bare 'rt worktree' cd-jump support.
if (
rcContent.includes('rt() {') &&
rcContent.includes('whence -p rt') &&
rcContent.includes('"$rt_bin" nav') &&
rcContent.includes('"$1" = "worktree"')
) return;

// Redirect stdout → stderr before showing prompts
const origWrite = process.stdout.write.bind(process.stdout);
Expand All@@ -95,14 +107,18 @@ async function ensureShellFunction(): Promise<void> {
const hasHashCacheBug = rcContent.includes("rt() {") && rcContent.includes("command rt cd") && !rcContent.includes("local rt_bin");
// Uses command -v which returns the function name in zsh, causing infinite recursion
const hasFuncnestBug = rcContent.includes("rt() {") && rcContent.includes("command -v rt") && !rcContent.includes("whence -p rt");
const hasOldFunction = hasLegacyRtcd || hasOldRtWrapper || hasPreRehashWrapper || hasHashCacheBug || hasFuncnestBug;
// Function exists and is otherwise current, but predates bare 'rt worktree' cd-jump support.
const hasNoWorktreeNav = rcContent.includes("rt() {") && rcContent.includes('"$rt_bin" nav') && !rcContent.includes('"$1" = "worktree"');
const hasOldFunction = hasLegacyRtcd || hasOldRtWrapper || hasPreRehashWrapper || hasHashCacheBug || hasFuncnestBug || hasNoWorktreeNav;

if (hasFuncnestBug) {
console.error(`\n ${yellow}Upgrading rt shell wrapper: fix FUNCNEST recursion in zsh${reset}`);
} else if (hasPreRehashWrapper) {
console.error(`\n ${yellow}Upgrading rt shell wrapper: auto-rehash after dev-mode toggle${reset}`);
} else if (hasNoNav) {
console.error(`\n ${yellow}Upgrading rt shell wrapper: adding rt nav cd support${reset}`);
} else if (hasNoWorktreeNav) {
console.error(`\n ${yellow}Upgrading rt shell wrapper: adding rt worktree cd support${reset}`);
} else if (hasHashCacheBug) {
console.error(`\n ${yellow}Upgrading rt shell wrapper: resolve dev-mode binary by absolute path${reset}`);
} else if (hasOldRtWrapper) {
Expand DownExpand Up@@ -131,7 +147,7 @@ async function ensureShellFunction(): Promise<void> {
process.exit(0);
}

if (hasOldRtWrapper || hasPreRehashWrapper || hasNoNav || hasHashCacheBug || hasFuncnestBug) {
if (hasOldRtWrapper || hasPreRehashWrapper || hasNoNav || hasHashCacheBug || hasFuncnestBug || hasNoWorktreeNav) {
rcContent = rcContent
.replace(/\n?# rt — shell wrapper \(enables rt cd to change directory\)\n?/g, "")
.replace(/\n?rt\(\) \{[\s\S]*?\n\}\n?/g, "\n");
Expand Down
12 changes: 6 additions & 6 deletions commands/hooks.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -88,18 +88,18 @@ function generateShims(dataDir: string, discoveredHooks: string[]): void {

const configFile = hooksConfigPath(dataDir);

// Always include pre-commit so the parking-lot guard runs even if the repo
// Always include pre-commit so the on-deck guard runs even if the repo
// has no .husky/pre-commit of its own.
const hookNames = [...new Set(["pre-commit", ...discoveredHooks])];

for (const hookName of hookNames) {
const shimPath = join(hooksDir, hookName);

const parkingLotGuard = hookName === "pre-commit" ? `
# Parking-lot guard: block commits on parking-lot/* branches.
const onDeckGuard = hookName === "pre-commit" ? `
# On-deck guard: block commits on on-deck/* branches.
CURRENT_BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null)
if [[ "$CURRENT_BRANCH" == parking-lot/* ]]; then
echo "rt: commits are not allowed on parking-lot branches (on \\"$CURRENT_BRANCH\\")"
if [[ "$CURRENT_BRANCH" == on-deck/* ]]; then
echo "rt: commits are not allowed on on-deck branches (on \\"$CURRENT_BRANCH\\")"
echo "rt: switch to a feature branch before committing"
exit 1
fi
Expand All@@ -108,7 +108,7 @@ fi
const shim = `#!/bin/bash
# rt hook shim — checks ~/.rt config before running the real hook
# Fail-safe: if config is missing or unreadable, the real hook runs
${parkingLotGuard}
${onDeckGuard}
HOOKS_CONFIG="${configFile}"
HOOK_NAME="${hookName}"

Expand Down
Loading
Loading