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
8 changes: 8 additions & 0 deletions src/claude-code/NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ 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.

Comment thread
tmaier marked this conversation as resolved.
> **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 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

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.
Expand Down
7 changes: 6 additions & 1 deletion src/claude-code/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
{
"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": {
"version": {
"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": {
Expand Down
57 changes: 57 additions & 0 deletions src/claude-code/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,61 @@ 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}"

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"
# 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"
}
Comment on lines +62 to +78

# bash
add_shell_alias_if_missing "$TARGET_HOME/.bashrc" "yolo" "$ALIAS_CMD"

# zsh
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"
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
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
Comment thread
tmaier marked this conversation as resolved.
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"
if [ "$FISH_CREATED" = true ]; then
chown "$_REMOTE_USER" "$TARGET_HOME/.config" "$TARGET_HOME/.config/fish" "$FISH_FUNC_DIR" "$FISH_FUNC_FILE"
fi
fi
Comment thread
tmaier marked this conversation as resolved.

echo "yolo alias configured for bash, zsh, and fish."
fi

echo "Claude Code installed successfully!"
19 changes: 19 additions & 0 deletions test/claude-code/claude_code_yolo_alias.sh
Original file line number Diff line number Diff line change
@@ -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 -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
reportResults
23 changes: 23 additions & 0 deletions test/claude-code/claude_code_yolo_alias_with_custom_user.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/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 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"

# Report results
reportResults
17 changes: 17 additions & 0 deletions test/claude-code/scenarios.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,22 @@
"features": {
"claude-code": {}
}
},
"claude_code_yolo_alias": {
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"claude-code": {
"yoloAlias": true
}
}
},
"claude_code_yolo_alias_with_custom_user": {
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"remoteUser": "vscode",
"features": {
"claude-code": {
"yoloAlias": true
}
}
}
}
Loading