From 08059ca5c7a40362d41c755a43cebf7a4ebddff5 Mon Sep 17 00:00:00 2001 From: "Tobias L. Maier" Date: Wed, 22 Apr 2026 01:14:47 +0200 Subject: [PATCH 1/6] feat(claude-code): add yoloAlias option for skip-permissions shortcut Add a boolean option that creates a 'yolo' shell alias mapping to 'claude --allow-dangerously-skip-permissions' in bash, zsh, and fish. --- src/claude-code/NOTES.md | 4 +++ src/claude-code/devcontainer-feature.json | 5 ++++ src/claude-code/install.sh | 30 ++++++++++++++++++++++ test/claude-code/claude_code_yolo_alias.sh | 19 ++++++++++++++ test/claude-code/scenarios.json | 8 ++++++ 5 files changed, 66 insertions(+) create mode 100755 test/claude-code/claude_code_yolo_alias.sh diff --git a/src/claude-code/NOTES.md b/src/claude-code/NOTES.md index 8694121..4995e21 100644 --- a/src/claude-code/NOTES.md +++ b/src/claude-code/NOTES.md @@ -13,6 +13,10 @@ By default, the `latest` release channel is installed. You can also specify: The channel chosen at install time becomes the default for auto-updates. +## YOLO Alias + +When `yoloAlias` is set to `true`, a `yolo` shell alias is created that expands to `claude --allow-dangerously-skip-permissions`. The alias is configured for bash, zsh, and fish. + ## Auto-Updates The native binary automatically updates in the background. Update checks are performed on startup and periodically while running. To disable auto-updates, set the `DISABLE_AUTOUPDATER=1` environment variable. diff --git a/src/claude-code/devcontainer-feature.json b/src/claude-code/devcontainer-feature.json index 9003213..b356730 100644 --- a/src/claude-code/devcontainer-feature.json +++ b/src/claude-code/devcontainer-feature.json @@ -8,6 +8,11 @@ "type": "string", "default": "latest", "description": "Version to install. Use 'latest', 'stable', or a specific semver (e.g. '1.0.58')." + }, + "yoloAlias": { + "type": "boolean", + "default": false, + "description": "Create a 'yolo' shell alias for 'claude --allow-dangerously-skip-permissions' in bash, zsh, and fish." } }, "customizations": { diff --git a/src/claude-code/install.sh b/src/claude-code/install.sh index a7e371b..f30a353 100755 --- a/src/claude-code/install.sh +++ b/src/claude-code/install.sh @@ -53,4 +53,34 @@ if [ -f "$INSTALL_HOME/.local/bin/claude" ] && [ ! -f /usr/local/bin/claude ]; t echo "Symlinked claude to /usr/local/bin/claude" fi +# Set up yolo alias if requested +if [ "${YOLOALIAS:-false}" = "true" ]; then + echo "Setting up 'yolo' alias..." + ALIAS_CMD='alias yolo="claude --allow-dangerously-skip-permissions"' + TARGET_HOME="${INSTALL_HOME}" + + # bash + echo "$ALIAS_CMD" >> "$TARGET_HOME/.bashrc" + + # zsh + echo "$ALIAS_CMD" >> "$TARGET_HOME/.zshrc" + + # fish — create a function file (idiomatic for fish) + FISH_FUNC_DIR="$TARGET_HOME/.config/fish/functions" + mkdir -p "$FISH_FUNC_DIR" + cat > "$FISH_FUNC_DIR/yolo.fish" << 'FISHEOF' +function yolo --description "claude --allow-dangerously-skip-permissions" + claude --allow-dangerously-skip-permissions $argv +end +FISHEOF + + # Fix ownership if installing for non-root user + if [ -n "$_REMOTE_USER" ] && [ "$_REMOTE_USER" != "root" ]; then + chown "$_REMOTE_USER" "$TARGET_HOME/.bashrc" "$TARGET_HOME/.zshrc" + chown -R "$_REMOTE_USER" "$FISH_FUNC_DIR" + fi + + echo "yolo alias configured for bash, zsh, and fish." +fi + echo "Claude Code installed successfully!" diff --git a/test/claude-code/claude_code_yolo_alias.sh b/test/claude-code/claude_code_yolo_alias.sh new file mode 100755 index 0000000..ab351bd --- /dev/null +++ b/test/claude-code/claude_code_yolo_alias.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# This test file will be executed against the 'claude_code_yolo_alias' scenario +# to verify that the yolo alias is properly configured. + +set -e + +# Import test library bundled with the devcontainer CLI +source dev-container-features-test-lib + +# Feature-specific tests +check "claude command available" which claude +check "yolo alias in bashrc" bash -c "grep -q 'alias yolo=' ~/.bashrc" +check "yolo alias in zshrc" bash -c "grep -q 'alias yolo=' ~/.zshrc" +check "fish yolo function exists" bash -c "test -f ~/.config/fish/functions/yolo.fish" +check "yolo resolves in bash" bash -ic "type yolo" + +# Report results +reportResults diff --git a/test/claude-code/scenarios.json b/test/claude-code/scenarios.json index 7c4a444..6faef15 100644 --- a/test/claude-code/scenarios.json +++ b/test/claude-code/scenarios.json @@ -19,5 +19,13 @@ "features": { "claude-code": {} } + }, + "claude_code_yolo_alias": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "claude-code": { + "yoloAlias": true + } + } } } From f7f18e59bb420c6f9f88092ddde54662161a6b49 Mon Sep 17 00:00:00 2001 From: "Tobias L. Maier" Date: Wed, 22 Apr 2026 21:59:17 +0200 Subject: [PATCH 2/6] fix(claude-code): address PR review feedback for yoloAlias Make alias appending idempotent with grep guard, add security warning to docs, and strengthen test assertions to verify full command string. --- src/claude-code/NOTES.md | 4 ++++ src/claude-code/install.sh | 18 ++++++++++++++++-- test/claude-code/claude_code_yolo_alias.sh | 6 +++--- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/claude-code/NOTES.md b/src/claude-code/NOTES.md index 4995e21..2839726 100644 --- a/src/claude-code/NOTES.md +++ b/src/claude-code/NOTES.md @@ -17,6 +17,10 @@ The channel chosen at install time becomes the default for auto-updates. When `yoloAlias` is set to `true`, a `yolo` shell alias is created that expands to `claude --allow-dangerously-skip-permissions`. The alias is configured for bash, zsh, and fish. +> **Warning:** `--allow-dangerously-skip-permissions` disables Claude Code's normal permission checks and confirmation prompts for potentially sensitive actions. This meaningfully reduces safety and may allow unintended or unsafe changes, so only enable `yoloAlias` if you understand and accept the security implications. +> +> Creating this alias may also override an existing `yolo` alias in your shell configuration. + ## Auto-Updates The native binary automatically updates in the background. Update checks are performed on startup and periodically while running. To disable auto-updates, set the `DISABLE_AUTOUPDATER=1` environment variable. diff --git a/src/claude-code/install.sh b/src/claude-code/install.sh index f30a353..eb8d0d0 100755 --- a/src/claude-code/install.sh +++ b/src/claude-code/install.sh @@ -59,11 +59,25 @@ if [ "${YOLOALIAS:-false}" = "true" ]; then ALIAS_CMD='alias yolo="claude --allow-dangerously-skip-permissions"' TARGET_HOME="${INSTALL_HOME}" + add_shell_alias_if_missing() { + local rc_file="$1" + local alias_name="$2" + local alias_cmd="$3" + + if [ -f "$rc_file" ] && grep -Eq "^[[:space:]]*alias[[:space:]]+${alias_name}=" "$rc_file"; then + echo "Skipping $rc_file: alias '$alias_name' already exists." + return 0 + fi + + touch "$rc_file" + printf '%s\n' "$alias_cmd" >> "$rc_file" + } + # bash - echo "$ALIAS_CMD" >> "$TARGET_HOME/.bashrc" + add_shell_alias_if_missing "$TARGET_HOME/.bashrc" "yolo" "$ALIAS_CMD" # zsh - echo "$ALIAS_CMD" >> "$TARGET_HOME/.zshrc" + add_shell_alias_if_missing "$TARGET_HOME/.zshrc" "yolo" "$ALIAS_CMD" # fish — create a function file (idiomatic for fish) FISH_FUNC_DIR="$TARGET_HOME/.config/fish/functions" diff --git a/test/claude-code/claude_code_yolo_alias.sh b/test/claude-code/claude_code_yolo_alias.sh index ab351bd..2030b5d 100755 --- a/test/claude-code/claude_code_yolo_alias.sh +++ b/test/claude-code/claude_code_yolo_alias.sh @@ -10,9 +10,9 @@ source dev-container-features-test-lib # Feature-specific tests check "claude command available" which claude -check "yolo alias in bashrc" bash -c "grep -q 'alias yolo=' ~/.bashrc" -check "yolo alias in zshrc" bash -c "grep -q 'alias yolo=' ~/.zshrc" -check "fish yolo function exists" bash -c "test -f ~/.config/fish/functions/yolo.fish" +check "yolo alias in bashrc" bash -c "grep -Fq 'claude --allow-dangerously-skip-permissions' ~/.bashrc" +check "yolo alias in zshrc" bash -c "grep -Fq 'claude --allow-dangerously-skip-permissions' ~/.zshrc" +check "fish yolo function body" bash -c "test -f ~/.config/fish/functions/yolo.fish && grep -Fq 'claude --allow-dangerously-skip-permissions' ~/.config/fish/functions/yolo.fish" check "yolo resolves in bash" bash -ic "type yolo" # Report results From 0527e9e77baf373c5100a73e8da53327b71a0e2b Mon Sep 17 00:00:00 2001 From: "Tobias L. Maier" Date: Wed, 22 Apr 2026 22:11:10 +0200 Subject: [PATCH 3/6] fix(claude-code): guard fish function overwrite and narrow chown scope Skip writing yolo.fish if it already exists to match bash/zsh behavior. Chown only the specific file instead of the entire functions directory. Update docs to reflect the skip-if-exists behavior. --- src/claude-code/NOTES.md | 2 +- src/claude-code/install.sh | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/claude-code/NOTES.md b/src/claude-code/NOTES.md index 2839726..8c45402 100644 --- a/src/claude-code/NOTES.md +++ b/src/claude-code/NOTES.md @@ -19,7 +19,7 @@ When `yoloAlias` is set to `true`, a `yolo` shell alias is created that expands > **Warning:** `--allow-dangerously-skip-permissions` disables Claude Code's normal permission checks and confirmation prompts for potentially sensitive actions. This meaningfully reduces safety and may allow unintended or unsafe changes, so only enable `yoloAlias` if you understand and accept the security implications. > -> Creating this alias may also override an existing `yolo` alias in your shell configuration. +> If a `yolo` alias or function already exists in your shell configuration, the installer will skip adding it to avoid overwriting your setup. ## Auto-Updates diff --git a/src/claude-code/install.sh b/src/claude-code/install.sh index eb8d0d0..28234a2 100755 --- a/src/claude-code/install.sh +++ b/src/claude-code/install.sh @@ -81,17 +81,22 @@ if [ "${YOLOALIAS:-false}" = "true" ]; then # fish — create a function file (idiomatic for fish) FISH_FUNC_DIR="$TARGET_HOME/.config/fish/functions" - mkdir -p "$FISH_FUNC_DIR" - cat > "$FISH_FUNC_DIR/yolo.fish" << 'FISHEOF' + FISH_FUNC_FILE="$FISH_FUNC_DIR/yolo.fish" + if [ -f "$FISH_FUNC_FILE" ]; then + echo "Skipping $FISH_FUNC_FILE: function already exists." + else + mkdir -p "$FISH_FUNC_DIR" + cat > "$FISH_FUNC_FILE" << 'FISHEOF' function yolo --description "claude --allow-dangerously-skip-permissions" claude --allow-dangerously-skip-permissions $argv end FISHEOF + fi # Fix ownership if installing for non-root user if [ -n "$_REMOTE_USER" ] && [ "$_REMOTE_USER" != "root" ]; then chown "$_REMOTE_USER" "$TARGET_HOME/.bashrc" "$TARGET_HOME/.zshrc" - chown -R "$_REMOTE_USER" "$FISH_FUNC_DIR" + chown "$_REMOTE_USER" "$FISH_FUNC_FILE" fi echo "yolo alias configured for bash, zsh, and fish." From cc08fcd63734d2fcd42e9ac9cf83520e7ec8ac3d Mon Sep 17 00:00:00 2001 From: "Tobias L. Maier" Date: Wed, 22 Apr 2026 23:07:11 +0200 Subject: [PATCH 4/6] fix(claude-code): precise docs wording and add remoteUser test scenario Update NOTES.md to accurately describe which existing definitions are detected. Add test scenario combining yoloAlias with remoteUser to verify file ownership for non-root users. --- src/claude-code/NOTES.md | 2 +- ...claude_code_yolo_alias_with_custom_user.sh | 22 +++++++++++++++++++ test/claude-code/scenarios.json | 9 ++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100755 test/claude-code/claude_code_yolo_alias_with_custom_user.sh diff --git a/src/claude-code/NOTES.md b/src/claude-code/NOTES.md index 8c45402..ee84484 100644 --- a/src/claude-code/NOTES.md +++ b/src/claude-code/NOTES.md @@ -19,7 +19,7 @@ When `yoloAlias` is set to `true`, a `yolo` shell alias is created that expands > **Warning:** `--allow-dangerously-skip-permissions` disables Claude Code's normal permission checks and confirmation prompts for potentially sensitive actions. This meaningfully reduces safety and may allow unintended or unsafe changes, so only enable `yoloAlias` if you understand and accept the security implications. > -> If a `yolo` alias or function already exists in your shell configuration, the installer will skip adding it to avoid overwriting your setup. +> If a `yolo` alias already exists in `.bashrc`/`.zshrc`, or a `yolo.fish` function file already exists, the installer will skip adding it to avoid overwriting your setup. ## Auto-Updates diff --git a/test/claude-code/claude_code_yolo_alias_with_custom_user.sh b/test/claude-code/claude_code_yolo_alias_with_custom_user.sh new file mode 100755 index 0000000..4fc49f8 --- /dev/null +++ b/test/claude-code/claude_code_yolo_alias_with_custom_user.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# This test file will be executed against the 'claude_code_yolo_alias_with_custom_user' scenario +# to verify that the yolo alias is properly configured for a non-root remoteUser. + +set -e + +# Import test library bundled with the devcontainer CLI +source dev-container-features-test-lib + +# Feature-specific tests +check "claude command available" which claude +check "yolo alias in bashrc" bash -c "grep -Fq 'claude --allow-dangerously-skip-permissions' ~/.bashrc" +check "yolo alias in zshrc" bash -c "grep -Fq 'claude --allow-dangerously-skip-permissions' ~/.zshrc" +check "fish yolo function body" bash -c "test -f ~/.config/fish/functions/yolo.fish && grep -Fq 'claude --allow-dangerously-skip-permissions' ~/.config/fish/functions/yolo.fish" +check "bashrc owned by current user" bash -c "test \"$(stat -c '%U' ~/.bashrc)\" = \"$(whoami)\"" +check "zshrc owned by current user" bash -c "test \"$(stat -c '%U' ~/.zshrc)\" = \"$(whoami)\"" +check "fish function owned by current user" bash -c "test \"$(stat -c '%U' ~/.config/fish/functions/yolo.fish)\" = \"$(whoami)\"" +check "yolo resolves in bash" bash -ic "type yolo" + +# Report results +reportResults diff --git a/test/claude-code/scenarios.json b/test/claude-code/scenarios.json index 6faef15..41ea1b0 100644 --- a/test/claude-code/scenarios.json +++ b/test/claude-code/scenarios.json @@ -27,5 +27,14 @@ "yoloAlias": true } } + }, + "claude_code_yolo_alias_with_custom_user": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "remoteUser": "vscode", + "features": { + "claude-code": { + "yoloAlias": true + } + } } } From ced9e5ba850527b9379f8692b244083166b4363f Mon Sep 17 00:00:00 2001 From: "Tobias L. Maier" Date: Wed, 22 Apr 2026 23:12:23 +0200 Subject: [PATCH 5/6] fix(claude-code): handle missing trailing newline and fix directory ownership Ensure rc files end with a newline before appending alias to prevent concatenation onto the previous line. Chown fish config directories individually so non-root users can manage their fish config. --- src/claude-code/install.sh | 10 +++++++++- .../claude_code_yolo_alias_with_custom_user.sh | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/claude-code/install.sh b/src/claude-code/install.sh index 28234a2..c4d1075 100755 --- a/src/claude-code/install.sh +++ b/src/claude-code/install.sh @@ -70,6 +70,10 @@ if [ "${YOLOALIAS:-false}" = "true" ]; then fi touch "$rc_file" + # Ensure the file ends with a newline before appending + if [ -s "$rc_file" ] && [ "$(tail -c 1 "$rc_file" | wc -l)" -eq 0 ]; then + printf '\n' >> "$rc_file" + fi printf '%s\n' "$alias_cmd" >> "$rc_file" } @@ -82,6 +86,7 @@ if [ "${YOLOALIAS:-false}" = "true" ]; then # fish — create a function file (idiomatic for fish) FISH_FUNC_DIR="$TARGET_HOME/.config/fish/functions" FISH_FUNC_FILE="$FISH_FUNC_DIR/yolo.fish" + FISH_CREATED=false if [ -f "$FISH_FUNC_FILE" ]; then echo "Skipping $FISH_FUNC_FILE: function already exists." else @@ -91,12 +96,15 @@ function yolo --description "claude --allow-dangerously-skip-permissions" claude --allow-dangerously-skip-permissions $argv end FISHEOF + FISH_CREATED=true fi # Fix ownership if installing for non-root user if [ -n "$_REMOTE_USER" ] && [ "$_REMOTE_USER" != "root" ]; then chown "$_REMOTE_USER" "$TARGET_HOME/.bashrc" "$TARGET_HOME/.zshrc" - chown "$_REMOTE_USER" "$FISH_FUNC_FILE" + if [ "$FISH_CREATED" = true ]; then + chown "$_REMOTE_USER" "$TARGET_HOME/.config" "$TARGET_HOME/.config/fish" "$FISH_FUNC_DIR" "$FISH_FUNC_FILE" + fi fi echo "yolo alias configured for bash, zsh, and fish." diff --git a/test/claude-code/claude_code_yolo_alias_with_custom_user.sh b/test/claude-code/claude_code_yolo_alias_with_custom_user.sh index 4fc49f8..1a583b6 100755 --- a/test/claude-code/claude_code_yolo_alias_with_custom_user.sh +++ b/test/claude-code/claude_code_yolo_alias_with_custom_user.sh @@ -15,6 +15,7 @@ check "yolo alias in zshrc" bash -c "grep -Fq 'claude --allow-dangerously-skip-p check "fish yolo function body" bash -c "test -f ~/.config/fish/functions/yolo.fish && grep -Fq 'claude --allow-dangerously-skip-permissions' ~/.config/fish/functions/yolo.fish" check "bashrc owned by current user" bash -c "test \"$(stat -c '%U' ~/.bashrc)\" = \"$(whoami)\"" check "zshrc owned by current user" bash -c "test \"$(stat -c '%U' ~/.zshrc)\" = \"$(whoami)\"" +check "fish functions dir owned by current user" bash -c "test \"$(stat -c '%U' ~/.config/fish/functions)\" = \"$(whoami)\"" check "fish function owned by current user" bash -c "test \"$(stat -c '%U' ~/.config/fish/functions/yolo.fish)\" = \"$(whoami)\"" check "yolo resolves in bash" bash -ic "type yolo" From fc8c7811d514e81f0893652f94419a4bc32d4b5a Mon Sep 17 00:00:00 2001 From: "Tobias L. Maier" Date: Wed, 22 Apr 2026 23:15:55 +0200 Subject: [PATCH 6/6] chore(claude-code): bump version to 2.2.0 --- src/claude-code/devcontainer-feature.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/claude-code/devcontainer-feature.json b/src/claude-code/devcontainer-feature.json index b356730..486629b 100644 --- a/src/claude-code/devcontainer-feature.json +++ b/src/claude-code/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "claude-code", - "version": "2.1.0", + "version": "2.2.0", "name": "Claude Code", "description": "Installs Claude Code CLI for AI-powered development assistance", "options": {