From 4c6b4f5d4d02850818e742efb09d053a58e6339c Mon Sep 17 00:00:00 2001 From: Timmy Date: Mon, 18 May 2026 08:40:21 +0100 Subject: [PATCH] fix: project sleds need claude CLI + extensions.worktreeConfig Two issues that surfaced when story 1 ran in the adopted huskies-server sled: 1. Dockerfile.base: the base image had no nodejs / claude CLI, so every coder agent spawn in an adopted project sled failed with `Unable to spawn claude: No viable candidates found in PATH`. Install nodejs + @anthropic-ai/claude-code in the base image so every sled built from it can spawn agents out of the box. 2. worktree/create.rs::install_pre_commit_hook: `git config --worktree` requires `extensions.worktreeConfig = true` to be set on the repo config; without it, every worktree creation logged a noisy `Pre-commit hook install failed` warning. Enable the extension idempotently before the per-worktree hooks-path set so the hook install succeeds cleanly. After this, rebuild huskies-project-base and recreate any adopted project containers to pick up the CLI. Co-Authored-By: Claude Opus 4.7 (1M context) --- docker/Dockerfile.base | 3 +++ server/src/worktree/create.rs | 10 +++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/docker/Dockerfile.base b/docker/Dockerfile.base index ddd6845d..23ad9813 100644 --- a/docker/Dockerfile.base +++ b/docker/Dockerfile.base @@ -27,6 +27,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ procps \ openssh-server \ sudo \ + nodejs \ + npm \ + && npm install -g @anthropic-ai/claude-code \ && rm -rf /var/lib/apt/lists/* # Copy the huskies binary and entrypoint from the main image. diff --git a/server/src/worktree/create.rs b/server/src/worktree/create.rs index 521b6dff..9355ec99 100644 --- a/server/src/worktree/create.rs +++ b/server/src/worktree/create.rs @@ -152,9 +152,17 @@ pub fn install_pre_commit_hook(wt_path: &Path) -> Result<(), String> { std::fs::set_permissions(&hook_path, std::fs::Permissions::from_mode(0o755)) .map_err(|e| format!("chmod pre-commit hook: {e}"))?; + // `git config --worktree` requires `extensions.worktreeConfig = true` on + // the repository config; enable it idempotently before the per-worktree + // hooks-path set below. Writing without `--worktree` targets the main + // GIT_DIR/config which all worktrees share, so a single call is enough. + let _ = std::process::Command::new("git") + .args(["config", "extensions.worktreeConfig", "true"]) + .current_dir(wt_path) + .output(); + // Point git at the per-worktree hooks dir so only this worktree uses // these hooks (not the main repo or other worktrees). - // Requires extensions.worktreeConfig = true in the repository config. let output = std::process::Command::new("git") .args(["config", "--worktree", "core.hooksPath", ".git-hooks"]) .current_dir(wt_path)