Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ version bump" below.
| `github-dev` | 1.0.7 | gh CLI, Copilot Chat, PR/Issues/Actions extensions |
| `graphite-dev` | 1.0.0 | Graphite CLI (`gt`, via npm) + Graphite VS Code extension, `gt auth` from `GRAPHITE_TOKEN` on start (dependsOn node) |
| `copilot-dev` | 1.0.4 | Copilot Chat + AI instructions (commits, PRs, code review) |
| `claude-dev` | 1.4.1 | Claude Code extension + CLI + `~/.claude` named-volume persistence (credentials + memory) + optional Remote Control server (`claude-rc`) |
| `claude-dev` | 1.4.2 | Claude Code extension + CLI + `~/.claude` named-volume persistence (credentials + memory) + optional Remote Control server (`claude-rc`) |
| `mistral-dev` | 1.3.2 | Mistral Vibe extension + `~/.vibe` named-volume persistence |
| `cline-dev` | 1.1.0 | Cline extension (`saoudrizwan.claude-dev`) + optional CLI + `~/.cline` named-volume persistence |
| `kimi-dev` | 1.0.0 | Kimi Code extension (`moonshot-ai.kimi-code`) + optional CLI + `~/.kimi-code` named-volume persistence |
Expand Down
3 changes: 3 additions & 0 deletions src/claude-dev/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ convention would silently share one memory/settings bucket under that model.
| `remoteControlSpawn` | `same-dir` \| `worktree` | `same-dir` | How the server creates sessions. |
| `remoteControlAutoTrust` | boolean | `false` | Answer yes to "Trust this folder?" for the server's folder — see [Trusting the folder](#remote-control-drive-this-devcontainer-from-your-phone-or-another-computer). Without it, run `claude` once in the folder and accept. |
| `remoteControlPermissionMode` | string | `""` | Starting permission mode for the server's sessions (e.g. `acceptEdits`, `plan`). Empty: Claude Code's default. |
| `remoteControlModel` | string | `""` | Default model of the server's sessions (`sonnet`, `opus`, or a full model id), exported as `ANTHROPIC_MODEL` to the server; its sessions inherit it. Empty: Claude Code's default. |

## IDE support

Expand Down Expand Up @@ -197,6 +198,8 @@ without depending on that user's shell profile already including

## Version History

- **v1.4.2**: `remoteControlModel` option: default model of the Remote Control sessions
(`claude remote-control` has no `--model`, so `claude-rc` exports it as `ANTHROPIC_MODEL`).
- **v1.4.0**: `CLAUDE_CONFIG_DIR` now points at the volume, so `~/.claude.json` (account, trust)
persists too. Added `remoteControl` (off by default) and its `remoteControlName`,
`remoteControlDir`, `remoteControlSpawn` and `remoteControlPermissionMode` options: keeps a
Expand Down
5 changes: 5 additions & 0 deletions src/claude-dev/claude-rc
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,13 @@ RC_NAME_OPTION=""
RC_DIR_OPTION=""
RC_SPAWN_OPTION="same-dir"
RC_PERMISSION_MODE_OPTION=""
RC_MODEL_OPTION=""
RC_AUTO_TRUST_OPTION="false"
# shellcheck source=/dev/null
[ -f "${OPTIONS_FILE}" ] && . "${OPTIONS_FILE}"
# `claude remote-control` has no --model flag: the sessions it spawns inherit the server's
# environment, so the default model goes through ANTHROPIC_MODEL.
if [ -n "${RC_MODEL_OPTION}" ]; then export ANTHROPIC_MODEL="${RC_MODEL_OPTION}"; fi

log() { echo "[claude-rc] $*"; }
warn() { echo "[claude-rc] ⚠️ $*" >&2; }
Expand Down Expand Up @@ -303,6 +307,7 @@ cmd_attach() {

cmd_status() {
echo "remoteControl option: ${RC_ENABLED}"
echo "model: ${ANTHROPIC_MODEL:-default}"
if running; then
# shellcheck source=/dev/null
[ -f "${STATE_FILE}" ] && . "${STATE_FILE}"
Expand Down
7 changes: 6 additions & 1 deletion src/claude-dev/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "claude-dev",
"version": "1.4.1",
"version": "1.4.2",
"name": "Claude Code Development Environment",
"description": "Installs the Claude Code IDE extension (anthropic.claude-code) for VS Code and Cursor, and optionally the claude CLI. Persists ~/.claude (credentials, config, memory) across rebuilds and Codespaces via a Docker named volume, dedicated to this devcontainer. Also self-heals your devcontainer setup.",
"documentationURL": "https://github.com/helpers4/devcontainer/tree/main/src/claude-dev",
Expand Down Expand Up @@ -56,6 +56,11 @@
"type": "string",
"default": "",
"description": "Starting permission mode for the server's sessions (e.g. acceptEdits, plan). Empty means Claude Code's default."
},
"remoteControlModel": {
"type": "string",
"default": "",
"description": "Default model of the server's sessions (e.g. sonnet, opus, or a full model id), exported as ANTHROPIC_MODEL to the server. Empty means Claude Code's default."
}
},
"containerEnv": {
Expand Down
2 changes: 2 additions & 0 deletions src/claude-dev/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ REMOTE_CONTROL_NAME="${REMOTECONTROLNAME:-}"
REMOTE_CONTROL_DIR="${REMOTECONTROLDIR:-}"
REMOTE_CONTROL_SPAWN="${REMOTECONTROLSPAWN:-same-dir}"
REMOTE_CONTROL_PERMISSION_MODE="${REMOTECONTROLPERMISSIONMODE:-}"
REMOTE_CONTROL_MODEL="${REMOTECONTROLMODEL:-}"
REMOTE_CONTROL_AUTO_TRUST="${REMOTECONTROLAUTOTRUST:-false}"

# shellcheck source=/dev/null
Expand Down Expand Up @@ -155,6 +156,7 @@ install -m 0755 "$(dirname "$0")/claude-rc" /usr/local/bin/claude-rc
printf 'RC_DIR_OPTION=%q\n' "${REMOTE_CONTROL_DIR}"
printf 'RC_SPAWN_OPTION=%q\n' "${REMOTE_CONTROL_SPAWN}"
printf 'RC_PERMISSION_MODE_OPTION=%q\n' "${REMOTE_CONTROL_PERMISSION_MODE}"
printf 'RC_MODEL_OPTION=%q\n' "${REMOTE_CONTROL_MODEL}"
printf 'RC_AUTO_TRUST_OPTION=%q\n' "${REMOTE_CONTROL_AUTO_TRUST}"
} > /usr/local/share/claude-dev/remote-control.env
echo " ✅ Installed /usr/local/bin/claude-rc"
Expand Down
3 changes: 2 additions & 1 deletion test/claude-dev/scenarios.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"claude-dev": {
"remoteControl": true,
"remoteControlName": "h4 test",
"remoteControlAutoTrust": true
"remoteControlAutoTrust": true,
"remoteControlModel": "sonnet"
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions test/claude-dev/with_remote_control.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ if ! pgrep -f 'claude-rc loop$' >/dev/null 2>&1; then
fi
echo "✅ PASS: Remote Control loop running"

# remoteControlModel: claude-rc exports it as ANTHROPIC_MODEL before starting the server (whose
# sessions inherit it). /proc/<loop>/environ can't show a later export, so read claude-rc's view.
if ! grep -q '^RC_MODEL_OPTION=sonnet$' "${ENV_FILE}" \
|| ! claude-rc status 2>/dev/null | grep -qE '^model: +sonnet$'; then
echo "❌ FAIL: remoteControlModel=sonnet not applied (options file or claude-rc status)"
exit 1
fi
echo "✅ PASS: remoteControlModel applied as the server's model"

# ~/.claude.json lives in the volume (login, trust and the Remote Control confirmation survive).
if [ "${CLAUDE_CONFIG_DIR:-}" != "/mnt/h4claude" ]; then
echo "❌ FAIL: CLAUDE_CONFIG_DIR is '${CLAUDE_CONFIG_DIR:-unset}', expected /mnt/h4claude"
Expand Down
Loading