summaryrefslogtreecommitdiff
path: root/hostnix/mojo
diff options
context:
space:
mode:
Diffstat (limited to 'hostnix/mojo')
-rw-r--r--hostnix/mojo/Makefile7
-rw-r--r--hostnix/mojo/flake.lock66
-rw-r--r--hostnix/mojo/flake.nix53
-rw-r--r--hostnix/mojo/modules/apps.nix41
-rw-r--r--hostnix/mojo/modules/obsidian.nix17
-rw-r--r--hostnix/mojo/modules/sunshine.nix23
-rw-r--r--hostnix/mojo/modules/system.nix28
-rw-r--r--hostnix/mojo/packages/claude-code/claude.sb314
-rw-r--r--hostnix/mojo/packages/claude-code/default.nix21
9 files changed, 570 insertions, 0 deletions
diff --git a/hostnix/mojo/Makefile b/hostnix/mojo/Makefile
new file mode 100644
index 0000000..27bbc67
--- /dev/null
+++ b/hostnix/mojo/Makefile
@@ -0,0 +1,7 @@
+switch:
+ sudo darwin-rebuild switch --flake path:.
+
+update:
+ nix flake update --flake path:.
+
+upgrade: update switch
diff --git a/hostnix/mojo/flake.lock b/hostnix/mojo/flake.lock
new file mode 100644
index 0000000..4a1a0ef
--- /dev/null
+++ b/hostnix/mojo/flake.lock
@@ -0,0 +1,66 @@
+{
+ "nodes": {
+ "nix-darwin": {
+ "inputs": {
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1783744694,
+ "narHash": "sha256-2cp6N3rrwnGYLTx9l6N+NI+kwrCWxvJUbj5WJhvB29A=",
+ "owner": "nix-darwin",
+ "repo": "nix-darwin",
+ "rev": "c3e90c89649b07d1a96e4b9dd6cd0d6e44b91a74",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-darwin",
+ "ref": "nix-darwin-26.05",
+ "repo": "nix-darwin",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1788966248,
+ "narHash": "sha256-F36C+08KdnP1gQ6bu9Ok+UKg50A5EVSZOeGqg+hjoO0=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "104a7c61006cd22d11c0379663afee90c62273ab",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixpkgs-26.05-darwin",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-unstable": {
+ "locked": {
+ "lastModified": 1788922888,
+ "narHash": "sha256-QMX3uerxnW2R5dHcWpIQILHDltOZnon3x3Spq7EzBFI=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "a391f95d4557d685fd8e5dc0d4b1f9271aa2f342",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "nix-darwin": "nix-darwin",
+ "nixpkgs": "nixpkgs",
+ "nixpkgs-unstable": "nixpkgs-unstable"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/hostnix/mojo/flake.nix b/hostnix/mojo/flake.nix
new file mode 100644
index 0000000..9bffbfa
--- /dev/null
+++ b/hostnix/mojo/flake.nix
@@ -0,0 +1,53 @@
+{
+ description = "nix-darwin system flake";
+
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-26.05-darwin";
+ nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
+ nix-darwin.url = "github:nix-darwin/nix-darwin/nix-darwin-26.05";
+ nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
+ };
+
+ outputs =
+ inputs@{
+ self,
+ nix-darwin,
+ nixpkgs,
+ nixpkgs-unstable,
+ }:
+ let
+ configuration =
+ { pkgs, pkgsUnstable, ... }:
+ {
+ nix.settings.experimental-features = "nix-command flakes";
+
+ # Set Git commit hash for darwin-version.
+ system.configurationRevision = self.rev or self.dirtyRev or null;
+
+ # Used for backwards compatibility, please read the changelog before changing.
+ # $ darwin-rebuild changelog
+ system.stateVersion = 6;
+
+ # The platform the configuration will be used on.
+ nixpkgs.hostPlatform = "aarch64-darwin";
+ };
+
+ in
+ {
+ darwinConfigurations.mojo = nix-darwin.lib.darwinSystem {
+ specialArgs = {
+ pkgsUnstable = import nixpkgs-unstable {
+ system = "aarch64-darwin";
+ config.allowUnfree = true;
+ };
+ };
+ modules = [
+ configuration
+ ./modules/apps.nix
+ ./modules/obsidian.nix
+ ./modules/sunshine.nix
+ ./modules/system.nix
+ ];
+ };
+ };
+}
diff --git a/hostnix/mojo/modules/apps.nix b/hostnix/mojo/modules/apps.nix
new file mode 100644
index 0000000..5c10633
--- /dev/null
+++ b/hostnix/mojo/modules/apps.nix
@@ -0,0 +1,41 @@
+{ pkgs, pkgsUnstable, ... }:
+{
+ environment.systemPackages = [
+ pkgs.direnv
+ pkgs.fd
+ pkgs.fzf
+ pkgs.nix-direnv
+ pkgs.nixfmt
+ pkgs.ripgrep
+ pkgs.tmux
+ pkgs.tree
+ pkgs.uv
+
+ (pkgsUnstable.callPackage ../packages/claude-code { })
+ pkgsUnstable.jujutsu
+ pkgsUnstable.llama-cpp
+ ];
+
+ environment.pathsToLink = [ "/share/vim-plugins" ]; # for fzf
+
+ homebrew = {
+ taps = [ "LizardByte/homebrew" ];
+
+ brews = [
+ "mas"
+ "sunshine"
+ ];
+
+ casks = [
+ "karabiner-elements" # modifiers, fn, reverse scroll
+ "linearmouse" # scroll by lines, universal back/forward
+ ];
+
+ masApps = {
+ "Ghostery Privacy Ad Blocker" = 6504861501;
+ "Kagi for Safari" = 1622835804;
+ "KeePassium (KeePass passwords)" = 1435127111;
+ Xcode = 497799835;
+ };
+ };
+}
diff --git a/hostnix/mojo/modules/obsidian.nix b/hostnix/mojo/modules/obsidian.nix
new file mode 100644
index 0000000..0357b0f
--- /dev/null
+++ b/hostnix/mojo/modules/obsidian.nix
@@ -0,0 +1,17 @@
+{ ... }:
+{
+ homebrew.casks = [ "obsidian" ];
+
+ launchd.user.agents.obsidian-auto-sync = {
+ script = ''
+ cd /Users/joe/src/Obsidian
+ ./.obsidian/auto-sync
+ '';
+ serviceConfig = {
+ StartInterval = 300;
+ StandardOutPath = "/Users/joe/Library/Logs/obsidian-auto-sync.log";
+ StandardErrorPath = "/Users/joe/Library/Logs/obsidian-auto-sync.log";
+ RunAtLoad = false;
+ };
+ };
+}
diff --git a/hostnix/mojo/modules/sunshine.nix b/hostnix/mojo/modules/sunshine.nix
new file mode 100644
index 0000000..4f12601
--- /dev/null
+++ b/hostnix/mojo/modules/sunshine.nix
@@ -0,0 +1,23 @@
+{ ... }:
+{
+ homebrew = {
+ taps = [
+ {
+ name = "LizardByte/homebrew";
+ trusted = true;
+ }
+ ];
+ brews = [ "LizardByte/homebrew/sunshine" ];
+ };
+
+ launchd.user.agents.sunshine = {
+ serviceConfig = {
+ Label = "com.lizardbyte.sunshine";
+ ProgramArguments = [ "/opt/homebrew/bin/sunshine" ];
+ RunAtLoad = true;
+ KeepAlive = true;
+ StandardOutPath = "/tmp/sunshine.log";
+ StandardErrorPath = "/tmp/sunshine.err";
+ };
+ };
+}
diff --git a/hostnix/mojo/modules/system.nix b/hostnix/mojo/modules/system.nix
new file mode 100644
index 0000000..b34905f
--- /dev/null
+++ b/hostnix/mojo/modules/system.nix
@@ -0,0 +1,28 @@
+{
+ pkgs,
+ pkgsUnstable,
+ self,
+ ...
+}:
+{
+ nixpkgs.config.allowUnfree = true;
+
+ homebrew = {
+ enable = true;
+ enableBashIntegration = true;
+ caskArgs.require_sha = true;
+ # Error: Refusing to uninstall /opt/homebrew/Cellar/brotli/1.2.0, [...snip...]
+ # because they are required by sunshine, which is currently installed.
+ # onActivation.cleanup = "uninstall";
+ };
+
+ system.primaryUser = "joe";
+
+ security.sudo.extraConfig = ''
+ Defaults!/run/current-system/sw/bin/darwin-rebuild timestamp_timeout=120
+ '';
+
+ # $ chsh -s /run/current-system/sw/bin/bash
+ environment.shells = [ pkgs.bashInteractive ];
+ programs.bash.completion.enable = true;
+}
diff --git a/hostnix/mojo/packages/claude-code/claude.sb b/hostnix/mojo/packages/claude-code/claude.sb
new file mode 100644
index 0000000..8e5dc9c
--- /dev/null
+++ b/hostnix/mojo/packages/claude-code/claude.sb
@@ -0,0 +1,314 @@
+(version 1)
+
+;; Based on Para Sandboxing Profile - Standard - https://github.com/2mawi2/para/blob/218259b6e260be43334f308a74108f31920f7ca4/src/core/sandbox/profiles/standard.sb
+;; Forbids reading HOME_DIR except for cwd (TARGET_DIR)
+;; Forbids writing other than to cwd (TARGET_DIR)
+;; All network is allowed
+
+;; Deny everything by default
+(deny default)
+
+;; Allow network access (required for Claude API)
+(allow network*)
+
+;; Deny reading files anywhere on host (allow rules override this below)
+(deny file-read*)
+
+(deny file-read*
+ (subpath "/")
+ (subpath "/Users")
+ (subpath (param "HOME_DIR"))
+ (subpath (string-append (param "HOME_DIR") "/.ssh"))
+)
+
+;; allow directories required to launch claude-code
+(allow file-read*
+ (subpath "/usr")
+ (subpath "/bin")
+ (subpath "/opt")
+ (subpath "/var")
+ (subpath "/private/var")
+ (subpath "/etc")
+ (subpath "/private/etc")
+ (subpath "/System")
+ (subpath "/nix")
+ )
+
+;; necessary for nix-darwin's `/run/current-system/sw/bin`
+(allow file-read-metadata
+ (subpath "/run"))
+
+;; === IMPORTANT === MODIFY this section to include ALL directories leading to claude workdir ===
+;; for some reason claude-code needs list access to all parent directories of TARGET_DIR
+;; - it doesn't need access to read the contents of directories, only the directories
+;; themselves. Otherwise it will set PATH to "" and disable colored output
+(allow file-read*
+ (literal "/")
+ )
+
+(allow file-read*
+ ;; Git configuration (for commits)
+ (subpath (string-append (param "HOME_DIR") "/.config/git"))
+ (subpath (string-append (param "HOME_DIR") "/.config/jj"))
+ (literal (string-append (param "HOME_DIR") "/.gitconfig"))
+ ;; Nix configuration
+ (subpath (string-append (param "HOME_DIR") "/.config/nix"))
+ (subpath (string-append (param "HOME_DIR") "/.local/share/nix"))
+ ;; Nix profile binaries (symlinks to /nix/store)
+ (subpath (string-append (param "HOME_DIR") "/.nix-profile"))
+ (subpath (string-append (param "HOME_DIR") "/.local/state/nix"))
+ ;; gh CLI
+ (subpath (string-append (param "HOME_DIR") "/.config/gh"))
+)
+
+;; Allow process execution and forking (children inherit policy)
+(allow process-exec)
+(allow process-fork)
+;; Essential permissions - based on Chrome sandbox policy
+;; Process permissions - from https://github.com/anthropic-experimental/sandbox-runtime/blob/1bafa66a2c3ebc52569fc0c1a868e85e778f66a0/src/sandbox/macos-sandbox-utils.ts#L200
+(allow process-info* (target same-sandbox))
+;; Allow signals to all children
+(allow signal (target same-sandbox))
+(allow mach-priv-task-port (target same-sandbox))
+
+;; User preferences - from https://github.com/anthropic-experimental/sandbox-runtime/blob/1bafa66a2c3ebc52569fc0c1a868e85e778f66a0/src/sandbox/macos-sandbox-utils.ts#L200
+;; (allow user-preference-read) ;; doesn't seem to be required by claude-code
+
+;; Allow read access to system information
+;; From Chromium's sandbox policy for macOS
+(allow sysctl-read
+ (sysctl-name "hw.activecpu")
+ (sysctl-name "hw.busfrequency_compat")
+ (sysctl-name "hw.byteorder")
+ (sysctl-name "hw.cacheconfig")
+ (sysctl-name "hw.cachelinesize_compat")
+ (sysctl-name "hw.cpufamily")
+ (sysctl-name "hw.cpufrequency_compat")
+ (sysctl-name "hw.cputype")
+ (sysctl-name "hw.l1dcachesize_compat")
+ (sysctl-name "hw.l1icachesize_compat")
+ (sysctl-name "hw.l2cachesize_compat")
+ (sysctl-name "hw.l3cachesize_compat")
+ (sysctl-name "hw.logicalcpu_max")
+ (sysctl-name "hw.machine")
+ (sysctl-name "hw.memsize")
+ (sysctl-name "hw.ncpu")
+ ;; Needed for Lix
+ (sysctl-name "hw.pagesize")
+ (sysctl-name "hw.pagesize_compat")
+ (sysctl-name "hw.physicalcpu_max")
+ (sysctl-name "hw.tbfrequency_compat")
+ (sysctl-name "kern.hostname")
+ (sysctl-name "kern.maxfilesperproc")
+ (sysctl-name "kern.osproductversion")
+ (sysctl-name "kern.osrelease")
+ (sysctl-name "kern.ostype")
+ (sysctl-name "kern.osversion")
+ (sysctl-name "kern.secure_kernel")
+ (sysctl-name "kern.version")
+)
+
+;; Allow file writes to specific paths only
+;; Note: file-write* does NOT include file-write-create, so we need both
+(allow file-read* file-write* file-write-create file-read-metadata file-ioctl
+ ;; Project directory - primary workspace
+ (subpath (param "TARGET_DIR"))
+
+ ;; Include .git and .jj directories in case the root is above TARGET_DIR.
+ (subpath (param "GIT_DIR"))
+ (subpath (param "JJ_DIR"))
+
+ ;; Temporary directories
+ (subpath (param "TMP_DIR"))
+ (subpath "/tmp")
+ (subpath "/private/tmp")
+ (subpath "/var/folders") ; macOS temp directory root
+ (subpath "/private/var/folders") ; Real path (var is symlink to private/var)
+
+ ;; below is from `para`'s' sandbox.sb, but these rules don't work because sandbox-exec uses GLOB 'regexes'
+ ;; (regex #"^/var/folders/[^/]+/[^/]+/[^/]+/.*") ; macOS temp dirs and subdirs
+ ;; (regex #"^/private/var/folders/[^/]+/[^/]+/[^/]+/.*") ; Real path version
+ ;; (regex #"^/var/folders/.*") ; Allow all subdirectories under /var/folders for broader compatibility
+ ;; (regex #"^/private/var/folders/.*") ; Real path version
+
+ ;; Cache directory
+ (subpath (param "CACHE_DIR"))
+ (subpath (string-append (param "HOME_DIR") "/.cache"))
+
+ ;; Claude configuration
+ (subpath (string-append (param "HOME_DIR") "/.claude"))
+ (literal (string-append (param "HOME_DIR") "/.claude.json"))
+ (literal (string-append (param "HOME_DIR") "/.claude.json.backup"))
+ (subpath (string-append (param "HOME_DIR") "/Library/Caches/claude-cli-nodejs"))
+
+ ;; Gemini configuration
+ (subpath (string-append (param "HOME_DIR") "/.gemini"))
+
+ ;; Standard I/O devices
+ (literal "/dev/stdout")
+ (literal "/dev/stderr")
+ (literal "/dev/null")
+ (literal "/dev/zero")
+ (literal "/dev/tty")
+ (literal "/dev/ptmx")
+ (literal "/dev/urandom")
+ (literal "/dev/random")
+ (regex #"^/dev/tty*")
+ (regex #"^/dev/pty*")
+)
+
+;; File I/O on device files - sandbox-runtime - https://github.com/anthropic-experimental/sandbox-runtime/blob/1bafa66a2c3ebc52569fc0c1a868e85e778f66a0/src/sandbox/macos-sandbox-utils.ts#L200
+(allow file-ioctl file-read-metadata file-read-data file-write-data (literal "/dev/dtracehelper"))
+(allow file-ioctl file-read-metadata file-read-data file-write-data
+ (require-all
+ (literal "/dev/null")
+ (vnode-type CHARACTER-DEVICE)
+ )
+)
+
+;; Gemini-specific permissions
+(allow pseudo-tty)
+
+;; Allow mach lookups for essential services
+(allow mach-lookup
+ (global-name "com.apple.sysmond") ; For process listing
+ (global-name "com.apple.FSEvents") ; For Node.js file watching
+ (global-name "com.apple.SystemConfiguration.DNSConfiguration") ; For DNS resolution in Lix
+)
+
+;; Allow file attribute operations needed for file creation
+;; (allow file-write-setugid)
+;; (allow file-write-mode)
+;; (allow file-write-owner)
+;; (allow file-write-times)
+;; (allow file-write-flags)
+
+(allow mach-lookup
+ (global-name "com.apple.audio.systemsoundserver")
+ (global-name "com.apple.distributed_notifications@Uv3")
+ (global-name "com.apple.FontObjectsServer")
+ (global-name "com.apple.fonts")
+ (global-name "com.apple.logd")
+ (global-name "com.apple.lsd.mapdb")
+ (global-name "com.apple.PowerManagement.control")
+ (global-name "com.apple.system.logger")
+ (global-name "com.apple.system.notification_center")
+ (global-name "com.apple.trustd.agent")
+ (global-name "com.apple.system.opendirectoryd.libinfo")
+ (global-name "com.apple.system.opendirectoryd.membership")
+ (global-name "com.apple.bsd.dirhelper")
+ (global-name "com.apple.securityd.xpc")
+ (global-name "com.apple.coreservices.launchservicesd")
+)
+
+;; The following is required to get Claude API Key from macOS Keychain (if logged in via /login)
+
+;; Specifically allow login keychain
+(allow file-read*
+ (literal (string-append (param "HOME_DIR") "/Library/Keychains/login.keychain-db"))
+)
+
+;; Critical: Allow communication with securityd (keychain daemon)
+(allow mach-lookup
+ (global-name "com.apple.SecurityServer")
+ (global-name "com.apple.securityd")
+ (global-name "com.apple.securityd.xpc")
+)
+
+;; Java/Scala development permissions
+
+;; Java-specific services
+(allow mach-lookup
+ (global-name "com.apple.diagnosticd")
+ (global-name "com.apple.SystemConfiguration.configd")
+)
+
+;; Java-specific sysctl reads
+(allow sysctl-read
+ (sysctl-name "security.mac.lockdown_mode_state")
+ (sysctl-name "kern.bootargs")
+ (sysctl-name "kern.osvariant_status")
+ (sysctl-name "kern.argmax")
+ (sysctl-name "hw.ephemeral_storage")
+ (sysctl-name "hw.optional.armv8_crc32")
+ (sysctl-name "hw.optional.arm.FEAT_LSE")
+ (sysctl-name "hw.optional.armv8_1_atomics")
+ (sysctl-name "hw.optional.arm.FEAT_SHA512")
+ (sysctl-name "hw.optional.armv8_2_sha512")
+ (sysctl-name "hw.optional.arm.FEAT_SHA3")
+ (sysctl-name "hw.optional.armv8_2_sha3")
+ (sysctl-name "net.routetable.0.0.3.0")
+)
+
+;; Java needs to read dtracehelper
+(allow file-read-data (literal "/dev/dtracehelper"))
+
+;: ;; Java needs IPC shared memory for notification center
+;; (allow ipc-posix-shm-read-data
+;; (ipc-posix-name "apple.shm.notification_center")
+;; )
+
+;; Java needs system sockets (domain:32 is AF_NDRV for network device raw access)
+(allow system-socket)
+
+;; Java needs to read metadata on certain directories
+(allow file-read-metadata
+ (literal "/dev")
+ (literal "/private")
+ (literal "/Library")
+ (literal (string-append (param "HOME_DIR") "/Library"))
+ (literal (string-append (param "HOME_DIR") "/Library/Caches"))
+)
+
+(allow file-read-data
+ (literal "/dev")
+)
+
+;; Java needs to read various preference files
+(allow file-read*
+ (literal "/Library/Preferences/Logging/com.apple.diagnosticd.filter.plist")
+ (literal "/Library/Preferences/.GlobalPreferences.plist")
+ (literal "/Library/Preferences/com.apple.networkd.plist")
+ (literal (string-append (param "HOME_DIR") "/Library/Preferences/.GlobalPreferences.plist"))
+ (literal (string-append (param "HOME_DIR") "/Library/Preferences/.GlobalPreferences_m.plist"))
+ (regex (string-append "^" (param "HOME_DIR") "/Library/Preferences/ByHost/\\.GlobalPreferences\\..*\\.plist$"))
+)
+
+;; read/write ~/.sbt, coursier and bloop caches
+(allow file-read* file-write*
+ (subpath (string-append (param "HOME_DIR") "/.sbt"))
+ (subpath (string-append (param "HOME_DIR") "/.ivy2"))
+ (subpath (string-append (param "HOME_DIR") "/.m2"))
+ (subpath (string-append (param "HOME_DIR") "/.jgit"))
+ (subpath (string-append (param "HOME_DIR") "/.config/jgit"))
+ (subpath (string-append (param "HOME_DIR") "/Library/Caches/Coursier"))
+ (subpath (string-append (param "HOME_DIR") "/Library/Caches/ScalaCli"))
+)
+
+;; read/write pnpm store
+(allow file-read* file-write* file-write-create
+ (subpath (string-append (param "HOME_DIR") "/Library/pnpm/store"))
+)
+
+;; read [~]/Library/Java
+(allow file-read*
+ (subpath (string-append (param "HOME_DIR") "/Library/Java"))
+ (subpath "/Library/Java")
+)
+
+;; Xcode Command Line Tools - needed so /usr/bin/git (an xcode-select shim)
+;; can locate the real git binary
+(allow file-read*
+ (subpath "/Library/Developer/CommandLineTools")
+)
+
+;; Generated allow-read rules for: /Users/joe/src
+;; for some reason claude-code needs list access to all parent directories of TARGET_DIR
+;; - it doesn't need access to read the contents of directories, only the directories
+;; themselves. Otherwise it will set PATH to "" and disable colored output
+(allow file-read* (literal "/Users"))
+(allow file-read* (literal "/Users/joe"))
+(allow file-read* (subpath "/Users/joe/src"))
+
+(allow file-read* (subpath (string-append (param "HOME_DIR") "/.dotfiles")))
+(deny file-read* (subpath (string-append (param "HOME_DIR") "/.dotfiles/tmp")))
diff --git a/hostnix/mojo/packages/claude-code/default.nix b/hostnix/mojo/packages/claude-code/default.nix
new file mode 100644
index 0000000..2e3fd35
--- /dev/null
+++ b/hostnix/mojo/packages/claude-code/default.nix
@@ -0,0 +1,21 @@
+{ writeShellScriptBin, claude-code }:
+
+writeShellScriptBin "claude" ''
+ if [[ $HOME/ = ''${PWD%/}/* ]]; then
+ echo "fatal: refusing to allow access to $PWD" >&2
+ exit 1
+ fi
+
+ git_dir="$(git rev-parse --absolute-git-dir 2>/dev/null)"
+ jj_root="$(jj root --ignore-working-copy 2>/dev/null)"
+
+ exec /usr/bin/sandbox-exec -f ${./claude.sb} \
+ -D TARGET_DIR="$(realpath "$PWD")" \
+ -D TMP_DIR=/tmp \
+ -D HOME_DIR="$HOME" \
+ -D CACHE_DIR="$HOME/.cache" \
+ -D GIT_DIR="''${git_dir:-$PWD/.git}" \
+ -D JJ_DIR="''${jj_root:-$PWD}/.jj" \
+ ${claude-code}/bin/claude \
+ --allow-dangerously-skip-permissions "$@"
+''