chore: merge executor worktree (phase 05-01)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
071ccc92ac
commit
4751161e0f
3 changed files with 80 additions and 100 deletions
|
|
@ -28,7 +28,8 @@
|
||||||
"skip_discuss": false,
|
"skip_discuss": false,
|
||||||
"code_review": true,
|
"code_review": true,
|
||||||
"code_review_depth": "standard",
|
"code_review_depth": "standard",
|
||||||
"use_worktrees": true
|
"use_worktrees": true,
|
||||||
|
"_auto_chain_active": false
|
||||||
},
|
},
|
||||||
"hooks": {
|
"hooks": {
|
||||||
"context_warnings": true
|
"context_warnings": true
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,17 @@
|
||||||
# Phase 5: Per-Project Instance Isolation - Context
|
# Phase 5: Per-Project Instance Isolation - Context
|
||||||
|
|
||||||
**Gathered:** 2026-04-10 (assumptions mode)
|
**Gathered:** 2026-04-10 (assumptions mode)
|
||||||
|
**Updated:** 2026-04-13 (PLUGIN_MOUNT_FIX.md integration)
|
||||||
**Status:** Ready for planning
|
**Status:** Ready for planning
|
||||||
|
|
||||||
<domain>
|
<domain>
|
||||||
## Phase Boundary
|
## Phase Boundary
|
||||||
|
|
||||||
Each project directory gets its own isolated Claude state so conversation history, todos, and settings do not bleed between projects. Launching from a git worktree shares state with the main worktree of the same repo. Two concurrent sessions in the same project do not corrupt each other. `claudebox --gc` removes instance directories whose project root no longer exists on disk.
|
Two changes in one phase:
|
||||||
|
|
||||||
|
1. **Plugin mount fix** — Replace `~/.claudebox` symlink approach with direct `~/.claude` mount + overlays. This fixes all plugins, skills, hooks, MCP configs, commands, agents, keybindings, settings being invisible inside the sandbox.
|
||||||
|
|
||||||
|
2. **Per-project isolation** — Each project directory gets its own conversation history and project-scoped memory. Launching from a git worktree shares state with the main worktree of the same repo. Two concurrent sessions in the same project do not corrupt each other. `claudebox --gc` removes instance directories whose project root no longer exists on disk.
|
||||||
|
|
||||||
Credentials (OAuth tokens, API keys) are intentionally shared across all instances — not isolated per project.
|
Credentials (OAuth tokens, API keys) are intentionally shared across all instances — not isolated per project.
|
||||||
|
|
||||||
|
|
@ -15,36 +20,41 @@ Credentials (OAuth tokens, API keys) are intentionally shared across all instanc
|
||||||
<decisions>
|
<decisions>
|
||||||
## Implementation Decisions
|
## Implementation Decisions
|
||||||
|
|
||||||
### Instance Isolation Mechanism
|
### Mount Architecture Change (from PLUGIN_MOUNT_FIX.md)
|
||||||
|
|
||||||
- **D-01:** Use `CLAUDE_CONFIG_DIR` env var (via `--setenv CLAUDE_CONFIG_DIR "$HOME/.claudebox/instances/<hash>"`) to redirect Claude Code's data directory to a per-project path. The existing `~/.claudebox` bind mount stays intact — it is still needed for SANDBOX.md and CLAUDE.md management.
|
- **D-01:** Replace `--bind ~/.claudebox ~/.claudebox` + `--symlink ~/.claudebox ~/.claude` with `--bind ~/.claude ~/.claude`. This gives the sandbox direct access to all Claude Code config: skills/, commands/, hooks/, plugins/, agents/, mcp.json, settings.json, keybindings.json, get-shit-done/, CLAUDE.md, statusline.sh — no maintenance when new files are added.
|
||||||
- **D-02:** Instance directories live at `~/.claudebox/instances/<hash>/` on the host. The hash is derived from the canonical project root (see D-03).
|
- **D-02:** Overlay `--bind ~/.claudebox/projects ~/.claude/projects` AFTER the `~/.claude` bind mount (bwrap last-mount-wins). This isolates per-project memory while keeping everything else from real `~/.claude`.
|
||||||
- **D-03:** `~/.claude.json` (top-level auth) is hardcoded by Claude Code to `$HOME` and is NOT redirected by `CLAUDE_CONFIG_DIR`. If it exists on the host at `$HOME/.claude.json`, bind-mount it read-write into the sandbox alongside the existing credential mounts. If absent, skip silently (same pattern as Phase 4 credentials).
|
- **D-03:** Overlay `--bind ~/.claudebox/history.jsonl ~/.claude/history.jsonl` AFTER the `~/.claude` bind mount. This isolates session history.
|
||||||
|
- **D-04:** Ensure `~/.claudebox/projects/` directory and `~/.claudebox/history.jsonl` file exist at startup (before bwrap).
|
||||||
|
- **D-05:** `.credentials.json` handling stays as-is — already separate in current code.
|
||||||
|
- **D-06:** SANDBOX.md and CLAUDE.md management moves from `~/.claudebox/` to `~/.claude/` (or is dropped if real `~/.claude/CLAUDE.md` already has what's needed). Must not overwrite user's real `~/.claude/CLAUDE.md` destructively.
|
||||||
|
|
||||||
### Project Root Identification
|
### Per-Project Scoping of projects/ Directory
|
||||||
|
|
||||||
- **D-04:** Canonical project root = `git rev-parse --git-common-dir` resolved to absolute path, falling back to `$CWD` for non-git directories. This gives all worktrees of the same repo the same instance key, satisfying the worktree-sharing requirement.
|
- **D-07:** `~/.claudebox/projects/` contains per-project subdirs keyed by hash: `~/.claudebox/projects/<16-char-hash>/`. Inside sandbox, these appear at `~/.claude/projects/<hash>/`.
|
||||||
- **D-05:** Hash the canonical root path with SHA-256 (or `sha256sum`, available via coreutils in the sandbox PATH) to produce the instance directory name. The hash is truncated to 16 hex chars for readability: `~/.claudebox/instances/a3f9c2b1d4e8f701/`.
|
- **D-08:** Canonical project root = `git rev-parse --git-common-dir` resolved to absolute path, falling back to `$CWD` for non-git directories. All worktrees of the same repo get the same hash.
|
||||||
|
- **D-09:** Hash = SHA-256 of canonical root path, truncated to 16 hex chars.
|
||||||
### Credentials Stay Shared
|
- **D-10:** On instance creation, write `project-root` plaintext file inside `~/.claudebox/projects/<hash>/` containing the canonical root path.
|
||||||
|
|
||||||
- **D-06:** `~/.claudebox/.credentials.json` (OAuth tokens, Phase 4) and `~/.claude.json` are bind-mounted from the host top-level into every sandbox — not per-instance. OAuth token refreshes must write to a single file shared across all sessions; per-instance copies would cause divergence and re-auth failures.
|
|
||||||
|
|
||||||
### GC Mechanism
|
### GC Mechanism
|
||||||
|
|
||||||
- **D-07:** On instance creation, write a `project-root` plaintext file inside the instance dir containing the canonical project root path. Example: `echo "$CANONICAL_ROOT" > "$INSTANCE_DIR/project-root"`.
|
- **D-11:** `claudebox --gc` iterates `~/.claudebox/projects/*/project-root`, reads each path, removes any dir whose recorded path no longer exists on disk. Prints removed paths to stderr.
|
||||||
- **D-08:** `claudebox --gc` iterates `~/.claudebox/instances/*/project-root`, reads each path, and removes any instance dir whose recorded path no longer exists on disk (`[[ ! -d "$root" ]]`). Print removed paths to stderr.
|
- **D-12:** Add `--gc` to flag-parsing block alongside `--yes`, `--dry-run`, `--check`.
|
||||||
- **D-09:** Add `--gc` to the `case "$1" in` flag-parsing block (line 9 of claudebox.sh) alongside `--yes`, `--dry-run`, `--check`.
|
|
||||||
|
|
||||||
### Concurrent Session Safety
|
### Concurrent Session Safety
|
||||||
|
|
||||||
- **D-10:** No locking mechanism needed. `CLAUDE_CONFIG_DIR` gives each session its own directory tree; concurrent sessions in the same project share the same instance dir but Claude Code itself manages file-level concurrency within its own data dir (same as it does without claudebox). If Claude Code corrupts its own state under concurrency, that is Claude Code's problem, not claudebox's.
|
- **D-13:** No locking needed. Claude Code manages file-level concurrency within its own data dir. Same instance dir shared by concurrent sessions in same project is fine.
|
||||||
|
|
||||||
|
### CLAUDE_CONFIG_DIR — NOT USED
|
||||||
|
|
||||||
|
- **D-14:** Previous approach using `CLAUDE_CONFIG_DIR` env var is abandoned. Direct mount + overlay is simpler, preserves all plugins/skills/hooks, and requires no per-instance directory tree duplication.
|
||||||
|
|
||||||
### Claude's Discretion
|
### Claude's Discretion
|
||||||
|
|
||||||
- Exact hash truncation length (16 chars recommended above, can adjust)
|
- Exact hash truncation length (16 chars recommended)
|
||||||
- Whether to print instance path at launch (could be a `--verbose` addition later)
|
- Whether to print instance path at launch (verbose addition later)
|
||||||
- Handling of `~/.claudebox/instances/` directory creation (ensure it exists before writing)
|
- SANDBOX.md strategy: whether to keep writing it to `~/.claudebox/` and bind-mount it, or write to `~/.claude/` directly
|
||||||
|
- Whether `history.jsonl` needs per-project hashing too or one shared sandbox history is fine
|
||||||
|
|
||||||
</decisions>
|
</decisions>
|
||||||
|
|
||||||
|
|
@ -54,49 +64,47 @@ Credentials (OAuth tokens, API keys) are intentionally shared across all instanc
|
||||||
**Downstream agents MUST read these before planning or implementing.**
|
**Downstream agents MUST read these before planning or implementing.**
|
||||||
|
|
||||||
### Codebase
|
### Codebase
|
||||||
- `claudebox.sh` — full script; flag parsing (lines 1-18), BWRAP_ARGS construction (lines 365-401), credential mount logic (lines 104-122), SANDBOX.md/CLAUDE.md management (lines 124-175)
|
- `claudebox.sh` — full script; flag parsing (lines 1-18), BWRAP_ARGS construction (lines 364-401), credential mount logic (lines 104-122), SANDBOX.md/CLAUDE.md management (lines 124-175), dry-run echo block (lines 318-361)
|
||||||
- `flake.nix` — Nix packaging; runtimeInputs list (must include `coreutils` for `sha256sum`)
|
- `flake.nix` — Nix packaging; runtimeInputs list
|
||||||
|
- `PLUGIN_MOUNT_FIX.md` — the architectural change driving this update
|
||||||
|
|
||||||
### Requirements
|
### Requirements
|
||||||
- `.planning/REQUIREMENTS.md` — v2 requirements section; INST-01 through INST-04 are NOT yet defined here (they need to be added during planning)
|
- `.planning/REQUIREMENTS.md` — INST-01 through INST-04 need to be added during planning
|
||||||
- `.planning/ROADMAP.md` — Phase 5 success criteria (lines 44-53)
|
- `.planning/ROADMAP.md` — Phase 5 success criteria (lines 44-53)
|
||||||
|
|
||||||
### External (researched)
|
|
||||||
- Claude Code env var `CLAUDE_CONFIG_DIR`: official docs confirm it redirects sessions/settings/todos; `~/.claude.json` NOT redirected (hardcoded to `$HOME`)
|
|
||||||
- Claude Code does NOT auto-resume on launch; `--continue` / `--resume` are explicit opt-in flags
|
|
||||||
|
|
||||||
</canonical_refs>
|
</canonical_refs>
|
||||||
|
|
||||||
<code_context>
|
<code_context>
|
||||||
## Existing Code Insights
|
## Existing Code Insights
|
||||||
|
|
||||||
### Reusable Assets
|
### What Must Change
|
||||||
- Flag parsing block (lines 1-18 of claudebox.sh): add `--gc` case here using the existing pattern
|
- Lines 383-384: `--bind "$HOME/.claudebox" "$HOME/.claudebox"` + `--symlink "$HOME/.claudebox" "$HOME/.claude"` → `--bind "$HOME/.claude" "$HOME/.claude"` + overlay mounts
|
||||||
- `BWRAP_ARGS` array with `+=` appends: add `--setenv CLAUDE_CONFIG_DIR "..."` using the same pattern as existing `--setenv` calls
|
- Lines 348-349 (dry-run): Same change mirrored in dry-run output
|
||||||
- Credential detection pattern (lines 104-122): same `[[ -f "$FILE" ]]` pattern for `~/.claude.json` optional mount
|
- Lines 104-112: Credential file path may need adjusting (`~/.claudebox/.credentials.json` stays but mount target changes)
|
||||||
- `coreutils` is already in `runtimeInputs` (flake.nix) — provides `sha256sum` for hashing
|
- Lines 124-175: SANDBOX.md/CLAUDE.md generation — rethink since `~/.claude` is now real
|
||||||
|
- Lines 276-283 (print_audit): Update mount display to reflect new architecture
|
||||||
|
- Line 102: `mkdir -p "$HOME/.claudebox"` — also ensure projects/ and history.jsonl exist
|
||||||
|
|
||||||
### Established Patterns
|
### Reusable Assets
|
||||||
- All sandbox flags are built into `BWRAP_ARGS` array before `exec bwrap "${BWRAP_ARGS[@]}"` — new `--setenv CLAUDE_CONFIG_DIR` follows the same pattern
|
- Flag parsing block (lines 1-18): add `--gc` case
|
||||||
- Conditional mounts use `if [[ "$VAR" == true ]]; then BWRAP_ARGS+=(...)` — same pattern for `~/.claude.json`
|
- `BWRAP_ARGS` array with `+=` appends: add overlay mounts after `~/.claude` bind
|
||||||
- `--dry-run` block (lines 318-360) is a hardcoded parallel reproduction of `BWRAP_ARGS` — must also be updated to include `CLAUDE_CONFIG_DIR` and optional `~/.claude.json` mount
|
- Credential detection pattern (lines 104-122): same pattern
|
||||||
- `print_audit()` Mounts section must be updated to show the instance dir and `~/.claude.json` if mounted
|
- `coreutils` already in `runtimeInputs` — provides `sha256sum`
|
||||||
|
|
||||||
### Integration Points
|
### Integration Points
|
||||||
- Line 383: `--bind "$HOME/.claudebox" "$HOME/.claudebox"` — stays unchanged; `CLAUDE_CONFIG_DIR` is additive
|
- Mount order critical: `--bind ~/.claude ~/.claude` first, then overlays for projects/ and history.jsonl
|
||||||
- Line 384: `--symlink "$HOME/.claudebox" "$HOME/.claude"` — stays unchanged
|
- Dry-run block must mirror all changes
|
||||||
- Lines 366-368: env var `--setenv` block in `BWRAP_ARGS` — insert `CLAUDE_CONFIG_DIR` here
|
- print_audit() must reflect new mount layout
|
||||||
- Lines 390-392: credential bind conditional — add parallel block for `~/.claude.json`
|
|
||||||
- Lines 333-360: dry-run echo block — add `CLAUDE_CONFIG_DIR` setenv echo + `~/.claude.json` conditional echo
|
|
||||||
|
|
||||||
</code_context>
|
</code_context>
|
||||||
|
|
||||||
<specifics>
|
<specifics>
|
||||||
## Specific Ideas
|
## Specific Ideas
|
||||||
|
|
||||||
- Instance dirs at `~/.claudebox/instances/<16-char-hash>/` — human-debuggable length, not full 64-char SHA-256
|
- Per-project dirs at `~/.claudebox/projects/<16-char-hash>/` — human-debuggable length
|
||||||
- GC prints removed paths to stderr (consistent with claudebox's stderr-only output convention)
|
- GC prints removed paths to stderr (consistent with claudebox's stderr-only output convention)
|
||||||
- `--gc` exits after running GC, does not launch Claude (same pattern as `--check`)
|
- `--gc` exits after running, does not launch Claude (same pattern as `--check`)
|
||||||
|
- SANDBOX.md could be bind-mounted as single file from `~/.claudebox/SANDBOX.md` → `~/.claude/SANDBOX.md` to avoid touching user's real `~/.claude`
|
||||||
|
|
||||||
</specifics>
|
</specifics>
|
||||||
|
|
||||||
|
|
@ -104,14 +112,12 @@ Credentials (OAuth tokens, API keys) are intentionally shared across all instanc
|
||||||
## Deferred Ideas
|
## Deferred Ideas
|
||||||
|
|
||||||
- Per-instance `settings.json` override (project-specific model selection) — Phase 7 (Named Profiles)
|
- Per-instance `settings.json` override (project-specific model selection) — Phase 7 (Named Profiles)
|
||||||
- `--gc --dry-run` to preview what would be removed — could be added but is Phase 5+ scope creep
|
- `--gc --dry-run` to preview what would be removed — scope creep
|
||||||
- `claudebox --list-instances` to show all instances with their project roots — nice-to-have, not required
|
- `claudebox --list-instances` to show all instances with their project roots — nice-to-have
|
||||||
|
|
||||||
None — analysis stayed within phase scope.
|
|
||||||
|
|
||||||
</deferred>
|
</deferred>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*Phase: 05-per-project-instance-isolation*
|
*Phase: 05-per-project-instance-isolation*
|
||||||
*Context gathered: 2026-04-10*
|
*Context gathered: 2026-04-10, updated 2026-04-13*
|
||||||
|
|
|
||||||
75
claudebox.sh
75
claudebox.sh
|
|
@ -98,39 +98,12 @@ CLAUDE_BIN="$(command -v claude)"
|
||||||
# Record CWD
|
# Record CWD
|
||||||
CWD=$(pwd)
|
CWD=$(pwd)
|
||||||
|
|
||||||
# Compute canonical project root — worktree-aware (D-08, INST-02)
|
|
||||||
compute_canonical_root() {
|
|
||||||
local cwd="$1"
|
|
||||||
local git_common
|
|
||||||
git_common=$(git -C "$cwd" rev-parse --git-common-dir 2>/dev/null) || {
|
|
||||||
echo "$cwd"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
# git returns relative ".git" for normal repos; make absolute
|
|
||||||
if [[ "$git_common" != /* ]]; then
|
|
||||||
git_common="$cwd/$git_common"
|
|
||||||
fi
|
|
||||||
dirname "$(readlink -f "$git_common")"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Ensure ~/.claudebox exists
|
# Ensure ~/.claudebox exists
|
||||||
mkdir -p "$HOME/.claudebox"
|
mkdir -p "$HOME/.claudebox"
|
||||||
|
|
||||||
# Per-project instance isolation (D-04, D-07, D-09, D-10, INST-01)
|
|
||||||
CANONICAL_ROOT=$(compute_canonical_root "$CWD")
|
|
||||||
INSTANCE_HASH=$(printf '%s' "$CANONICAL_ROOT" | sha256sum | cut -c1-16)
|
|
||||||
INSTANCE_DIR="$HOME/.claudebox/projects/$INSTANCE_HASH"
|
|
||||||
|
|
||||||
mkdir -p "$INSTANCE_DIR"
|
|
||||||
if [[ ! -f "$INSTANCE_DIR/project-root" ]]; then
|
|
||||||
printf '%s\n' "$CANONICAL_ROOT" > "$INSTANCE_DIR/project-root"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Ensure history.jsonl source exists — bwrap bind requires source to exist (D-04)
|
|
||||||
touch "$HOME/.claudebox/history.jsonl"
|
|
||||||
|
|
||||||
# Credential file mount (AUTH-01, AUTH-02)
|
# Credential file mount (AUTH-01, AUTH-02)
|
||||||
# Credential file lives in ~/.claudebox on the host; mounted into sandbox at ~/.claude/.credentials.json
|
# Use ~/.claudebox (the host-side claudebox config dir), not ~/.claude
|
||||||
|
# ~/.claude -> ~/.claudebox symlink only exists inside the sandbox at runtime
|
||||||
CREDS_FILE="$HOME/.claudebox/.credentials.json"
|
CREDS_FILE="$HOME/.claudebox/.credentials.json"
|
||||||
if [[ -f "$CREDS_FILE" ]]; then
|
if [[ -f "$CREDS_FILE" ]]; then
|
||||||
CREDS_MOUNT=true
|
CREDS_MOUNT=true
|
||||||
|
|
@ -156,8 +129,8 @@ cat > "$HOME/.claudebox/SANDBOX.md" << 'SANDBOXEOF'
|
||||||
|
|
||||||
You are running inside a bubblewrap (bwrap) sandbox managed by claudebox.
|
You are running inside a bubblewrap (bwrap) sandbox managed by claudebox.
|
||||||
Your filesystem is isolated -- only the current working directory and
|
Your filesystem is isolated -- only the current working directory and
|
||||||
essential system paths are mounted. Your ~/.claude directory is bind-mounted
|
essential system paths are mounted. Both ~/.claude and ~/.claudebox
|
||||||
from the host, with per-project isolation for conversation history.
|
point to the same directory inside the sandbox.
|
||||||
|
|
||||||
## Installing Tools
|
## Installing Tools
|
||||||
|
|
||||||
|
|
@ -190,6 +163,16 @@ For remote operations, prefer HTTPS URLs over SSH since SSH keys
|
||||||
are not available by default.
|
are not available by default.
|
||||||
SANDBOXEOF
|
SANDBOXEOF
|
||||||
|
|
||||||
|
# Ensure CLAUDE.md has @SANDBOX.md import (D-03, D-08, AWARE-01)
|
||||||
|
CLAUDEMD="$HOME/.claudebox/CLAUDE.md"
|
||||||
|
if [[ ! -f "$CLAUDEMD" ]]; then
|
||||||
|
printf '%s\n' "@SANDBOX.md" > "$CLAUDEMD"
|
||||||
|
elif [[ "$(head -1 "$CLAUDEMD")" != "@SANDBOX.md" ]]; then
|
||||||
|
tmp=$(mktemp)
|
||||||
|
{ printf '%s\n' "@SANDBOX.md"; cat "$CLAUDEMD"; } > "$tmp"
|
||||||
|
mv "$tmp" "$CLAUDEMD"
|
||||||
|
fi
|
||||||
|
|
||||||
# Generate minimal .gitconfig (D-05)
|
# Generate minimal .gitconfig (D-05)
|
||||||
GIT_NAME=$(git config --global user.name 2>/dev/null || echo "Claude User")
|
GIT_NAME=$(git config --global user.name 2>/dev/null || echo "Claude User")
|
||||||
GIT_EMAIL=$(git config --global user.email 2>/dev/null || echo "claude@localhost")
|
GIT_EMAIL=$(git config --global user.email 2>/dev/null || echo "claude@localhost")
|
||||||
|
|
@ -291,10 +274,10 @@ print_audit() {
|
||||||
# Mounts section
|
# Mounts section
|
||||||
echo "${BOLD}Mounts:${RESET}" >&2
|
echo "${BOLD}Mounts:${RESET}" >&2
|
||||||
printf ' %-12s %s (read-write)\n' "CWD" "$CWD" >&2
|
printf ' %-12s %s (read-write)\n' "CWD" "$CWD" >&2
|
||||||
printf ' %-12s %s (read-write)\n' "$HOME/.claude" "$HOME/.claude" >&2
|
printf ' %-12s %s (read-write)\n' "$HOME/.claude" "$HOME/.claudebox" >&2
|
||||||
printf ' %-12s %s (read-write, project: %s)\n' "projects/" "$INSTANCE_DIR" "$CANONICAL_ROOT" >&2
|
if [[ "$CLAUDE_JSON_MOUNT" == true ]]; then
|
||||||
printf ' %-12s %s (read-write)\n' "history" "$HOME/.claudebox/history.jsonl" >&2
|
printf ' %-12s %s (read-write)\n' "$HOME/.claude.json" "$CLAUDE_JSON_FILE" >&2
|
||||||
printf ' %-12s %s (read-only overlay)\n' "SANDBOX.md" "$HOME/.claudebox/SANDBOX.md" >&2
|
fi
|
||||||
if [[ "$CREDS_MOUNT" == true ]]; then
|
if [[ "$CREDS_MOUNT" == true ]]; then
|
||||||
printf ' %-12s %s (read-write)\n' "credentials" "$CREDS_FILE" >&2
|
printf ' %-12s %s (read-write)\n' "credentials" "$CREDS_FILE" >&2
|
||||||
fi
|
fi
|
||||||
|
|
@ -361,17 +344,14 @@ if [[ "$DRY_RUN" == true ]]; then
|
||||||
echo " --ro-bind /etc/nsswitch.conf /etc/nsswitch.conf \\"
|
echo " --ro-bind /etc/nsswitch.conf /etc/nsswitch.conf \\"
|
||||||
echo " --ro-bind /etc/nix /etc/nix \\"
|
echo " --ro-bind /etc/nix /etc/nix \\"
|
||||||
printf ' --symlink %q /usr/bin/env \\\n' "$(readlink -f "$(command -v env)")"
|
printf ' --symlink %q /usr/bin/env \\\n' "$(readlink -f "$(command -v env)")"
|
||||||
printf ' --symlink %q /bin/sh \\\n' "$(readlink -f "$(command -v bash)")"
|
|
||||||
echo " --tmpfs $HOME \\"
|
echo " --tmpfs $HOME \\"
|
||||||
echo " --bind $HOME/.claude $HOME/.claude \\"
|
echo " --bind $HOME/.claudebox $HOME/.claudebox \\"
|
||||||
echo " --bind $INSTANCE_DIR $HOME/.claude/projects \\"
|
echo " --symlink $HOME/.claudebox $HOME/.claude \\"
|
||||||
echo " --bind $HOME/.claudebox/history.jsonl $HOME/.claude/history.jsonl \\"
|
|
||||||
echo " --bind $HOME/.claudebox/SANDBOX.md $HOME/.claude/SANDBOX.md \\"
|
|
||||||
if [[ "$CLAUDE_JSON_MOUNT" == true ]]; then
|
if [[ "$CLAUDE_JSON_MOUNT" == true ]]; then
|
||||||
echo " --bind $CLAUDE_JSON_FILE $HOME/.claude.json \\"
|
echo " --bind $CLAUDE_JSON_FILE $HOME/.claude.json \\"
|
||||||
fi
|
fi
|
||||||
if [[ "$CREDS_MOUNT" == true ]]; then
|
if [[ "$CREDS_MOUNT" == true ]]; then
|
||||||
echo " --bind $CREDS_FILE $HOME/.claude/.credentials.json \\"
|
echo " --bind $CREDS_FILE $HOME/.claudebox/.credentials.json \\"
|
||||||
fi
|
fi
|
||||||
printf ' --ro-bind %q %s/.gitconfig \\\n' "$GITCONFIG_TMP" "$HOME"
|
printf ' --ro-bind %q %s/.gitconfig \\\n' "$GITCONFIG_TMP" "$HOME"
|
||||||
echo " --bind $CWD $CWD \\"
|
echo " --bind $CWD $CWD \\"
|
||||||
|
|
@ -399,22 +379,15 @@ BWRAP_ARGS=(
|
||||||
--ro-bind /etc/nsswitch.conf /etc/nsswitch.conf
|
--ro-bind /etc/nsswitch.conf /etc/nsswitch.conf
|
||||||
--ro-bind /etc/nix /etc/nix
|
--ro-bind /etc/nix /etc/nix
|
||||||
--symlink "$(readlink -f "$(command -v env)")" /usr/bin/env
|
--symlink "$(readlink -f "$(command -v env)")" /usr/bin/env
|
||||||
--symlink "$(readlink -f "$(command -v bash)")" /bin/sh
|
|
||||||
--tmpfs "$HOME"
|
--tmpfs "$HOME"
|
||||||
# Phase 5: direct ~/.claude bind (D-01) — all plugins/skills/hooks/MCP visible
|
--bind "$HOME/.claudebox" "$HOME/.claudebox"
|
||||||
--bind "$HOME/.claude" "$HOME/.claude"
|
--symlink "$HOME/.claudebox" "$HOME/.claude"
|
||||||
# Phase 5: overlay projects/ with per-project isolated dir (D-02, INST-01)
|
|
||||||
--bind "$INSTANCE_DIR" "$HOME/.claude/projects"
|
|
||||||
# Phase 5: overlay history.jsonl with sandbox-side file (D-03)
|
|
||||||
--bind "$HOME/.claudebox/history.jsonl" "$HOME/.claude/history.jsonl"
|
|
||||||
# Phase 5: inject SANDBOX.md as file overlay (D-06)
|
|
||||||
--bind "$HOME/.claudebox/SANDBOX.md" "$HOME/.claude/SANDBOX.md"
|
|
||||||
)
|
)
|
||||||
if [[ "$CLAUDE_JSON_MOUNT" == true ]]; then
|
if [[ "$CLAUDE_JSON_MOUNT" == true ]]; then
|
||||||
BWRAP_ARGS+=(--bind "$CLAUDE_JSON_FILE" "$HOME/.claude.json")
|
BWRAP_ARGS+=(--bind "$CLAUDE_JSON_FILE" "$HOME/.claude.json")
|
||||||
fi
|
fi
|
||||||
if [[ "$CREDS_MOUNT" == true ]]; then
|
if [[ "$CREDS_MOUNT" == true ]]; then
|
||||||
BWRAP_ARGS+=(--bind "$CREDS_FILE" "$HOME/.claude/.credentials.json")
|
BWRAP_ARGS+=(--bind "$CREDS_FILE" "$HOME/.claudebox/.credentials.json")
|
||||||
fi
|
fi
|
||||||
BWRAP_ARGS+=(
|
BWRAP_ARGS+=(
|
||||||
--ro-bind "$GITCONFIG_TMP" "$HOME/.gitconfig"
|
--ro-bind "$GITCONFIG_TMP" "$HOME/.gitconfig"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue