58 lines
2.3 KiB
Bash
Executable file
58 lines
2.3 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Launch claude under the sandbox allowlist+deny policy in a target dir.
|
|
#
|
|
# Usage:
|
|
# sandbox-claude.sh # target = parent of script dir
|
|
# # (the worktree containing the script)
|
|
# sandbox-claude.sh <dir> # target = <dir>
|
|
# sandbox-claude.sh <dir> <claude-args>...
|
|
# # remaining args pass to claude
|
|
#
|
|
# Behaviour:
|
|
# - cd to <target>
|
|
# - copy <script-dir>/sandbox-settings.json -> <target>/.claude/settings.json
|
|
# fresh on every launch (idempotent — policy evolves in main and
|
|
# propagates on next launch; hand-editing the runtime copy is pointless).
|
|
# - exec claude
|
|
#
|
|
# Safety model (from sandbox-settings.json):
|
|
# - defaultMode=acceptEdits — file edits silent
|
|
# - allow: narrow Bash set — nix build/check/eval, fmt/lint,
|
|
# in-worktree git, basic inspection
|
|
# - ask: rm/mv/cp/chmod/chown — prompt every time
|
|
# - deny: sudo, *-rebuild switch|test|boot, omni-rebuild, nh, git push,
|
|
# git remote, curl/wget/ssh, systemctl, docker/podman, WebFetch,
|
|
# WebSearch — hard reject, cannot be overridden
|
|
# mid-session
|
|
#
|
|
# To loosen the policy, edit sandbox-settings.json in the source checkout
|
|
# and relaunch — the runtime copy in <target>/.claude/ refreshes from it.
|
|
#
|
|
# <target> should have `.claude/` in its .gitignore so the runtime copy
|
|
# doesn't leak into commits. The script warns if it doesn't.
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
|
|
SETTINGS_SRC="$SCRIPT_DIR/sandbox-settings.json"
|
|
|
|
TARGET="$SCRIPT_DIR/.."
|
|
if [[ $# -gt 0 && -d "$1" ]]; then
|
|
TARGET="$1"
|
|
shift
|
|
fi
|
|
TARGET="$(readlink -f "$TARGET")"
|
|
|
|
[[ -d "$TARGET" ]] || { echo "sandbox-claude: target does not exist: $TARGET" >&2; exit 1; }
|
|
[[ -f "$SETTINGS_SRC" ]] || { echo "sandbox-claude: settings file not found: $SETTINGS_SRC" >&2; exit 1; }
|
|
|
|
cd "$TARGET"
|
|
mkdir -p .claude
|
|
cp -f "$SETTINGS_SRC" .claude/settings.json
|
|
|
|
if [[ -f .gitignore ]] && ! grep -qE '(^|/)\.claude/?$' .gitignore; then
|
|
echo "sandbox-claude: note — '.claude/' not found in $TARGET/.gitignore;" >&2
|
|
echo " the runtime settings.json may leak into commits." >&2
|
|
fi
|
|
|
|
exec claude "$@"
|