@alanbem/dclaude 0.0.13 → 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -3
- package/dclaude +389 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -132,12 +132,15 @@ dclaude gh # Interactive GitHub login
|
|
|
132
132
|
dclaude exec gh pr list # Use gh commands
|
|
133
133
|
```
|
|
134
134
|
|
|
135
|
-
### SSH Server
|
|
135
|
+
### SSH Key and Server Management
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
Load SSH keys and start SSH server for JetBrains Gateway, VS Code Remote, or any SSH client:
|
|
138
138
|
|
|
139
139
|
```bash
|
|
140
|
-
dclaude ssh #
|
|
140
|
+
dclaude ssh # Load keys + start SSH server
|
|
141
|
+
dclaude ssh keys # Load SSH keys into agent
|
|
142
|
+
dclaude ssh server # Start SSH server, shows port
|
|
143
|
+
dclaude ssh server --stop # Stop SSH server
|
|
141
144
|
# Connect: ssh claude@localhost -p <port>
|
|
142
145
|
# Password: claude
|
|
143
146
|
```
|
|
@@ -151,6 +154,32 @@ dclaude chrome # Launch Chrome with DevTools
|
|
|
151
154
|
dclaude # Claude can now interact with the browser
|
|
152
155
|
```
|
|
153
156
|
|
|
157
|
+
### AWS CLI Integration
|
|
158
|
+
|
|
159
|
+
AWS CLI v2 is pre-installed in the container. Configure how AWS credentials are provided:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
# Auto (default): mounts ~/.aws from host if it exists, otherwise no config
|
|
163
|
+
dclaude
|
|
164
|
+
|
|
165
|
+
# Mount host's ~/.aws directory (read-write, shared with host)
|
|
166
|
+
DCLAUDE_AWS_CLI=mount dclaude
|
|
167
|
+
|
|
168
|
+
# Use isolated Docker volume (persists across container recreations)
|
|
169
|
+
DCLAUDE_AWS_CLI=volume dclaude
|
|
170
|
+
|
|
171
|
+
# No AWS config mounting
|
|
172
|
+
DCLAUDE_AWS_CLI=none dclaude
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
**Volume mode** provides isolated AWS config per namespace:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
dclaude aws configure # Copy ~/.aws/config (profiles, regions) into container
|
|
179
|
+
dclaude aws login # Run 'aws login' in container
|
|
180
|
+
dclaude aws login --profile staging # Login with specific profile
|
|
181
|
+
```
|
|
182
|
+
|
|
154
183
|
### iTerm2 Shell Integration
|
|
155
184
|
|
|
156
185
|
If you use iTerm2 on macOS, dclaude automatically enables [iTerm2 Shell Integration](https://iterm2.com/documentation-shell-integration.html):
|
|
@@ -173,6 +202,7 @@ dclaude automatically tells Claude about its container environment so it can giv
|
|
|
173
202
|
- **Network mode** - Whether `localhost` works or needs `host.docker.internal`
|
|
174
203
|
- **Docker access** - Whether Docker commands are available
|
|
175
204
|
- **SSH auth method** - How git authentication is configured
|
|
205
|
+
- **AWS CLI** - Whether and how AWS credentials are configured
|
|
176
206
|
- **Path mirroring** - That file paths match the host
|
|
177
207
|
|
|
178
208
|
This helps Claude understand its environment without you explaining it. Disable if needed:
|
|
@@ -195,6 +225,7 @@ DCLAUDE_SYSTEM_CONTEXT=false dclaude
|
|
|
195
225
|
| `DCLAUDE_QUIET` | `false` | Suppress info messages |
|
|
196
226
|
| `DCLAUDE_NO_UPDATE` | `false` | Skip image update check |
|
|
197
227
|
| `DCLAUDE_SYSTEM_CONTEXT` | `true` | Inform Claude about container environment |
|
|
228
|
+
| `DCLAUDE_AWS_CLI` | `auto` | AWS config: `auto`, `mount`, `volume`, `none` |
|
|
198
229
|
| `DCLAUDE_ITERM2` | `true` | Enable iTerm2 shell integration (only affects iTerm2) |
|
|
199
230
|
|
|
200
231
|
## Configuration File
|
|
@@ -220,6 +251,7 @@ dclaude walks up the directory tree to find `.dclaude` files. Any dclaude sessio
|
|
|
220
251
|
| `MOUNT_ROOT` | Mount directory (relative to config file, or absolute path) |
|
|
221
252
|
| `DEBUG` | Enable debug output (`true`, `false`) |
|
|
222
253
|
| `CHROME_PORT` | Chrome DevTools port |
|
|
254
|
+
| `AWS_CLI` | AWS config mode (`mount`, `volume`, `none`) |
|
|
223
255
|
|
|
224
256
|
**Precedence:** Environment variables override `.dclaude` file settings.
|
|
225
257
|
|
|
@@ -327,6 +359,7 @@ The container includes:
|
|
|
327
359
|
- **Docker CLI** and **Docker Compose**
|
|
328
360
|
- **Git**, **GitHub CLI** (`gh`), common dev tools
|
|
329
361
|
- **tmux** for session management
|
|
362
|
+
- **AWS CLI v2** for cloud operations
|
|
330
363
|
- **SSH server** for IDE integration
|
|
331
364
|
|
|
332
365
|
## Troubleshooting
|
package/dclaude
CHANGED
|
@@ -135,6 +135,9 @@ load_config_file() {
|
|
|
135
135
|
fi
|
|
136
136
|
fi
|
|
137
137
|
;;
|
|
138
|
+
AWS_CLI)
|
|
139
|
+
[[ -z "${DCLAUDE_AWS_CLI:-}" ]] && DCLAUDE_AWS_CLI="$value"
|
|
140
|
+
;;
|
|
138
141
|
esac
|
|
139
142
|
fi
|
|
140
143
|
done < "$config_file"
|
|
@@ -151,6 +154,7 @@ readonly DEBUG="${DCLAUDE_DEBUG:-false}"
|
|
|
151
154
|
readonly GIT_AUTH_MODE="${DCLAUDE_GIT_AUTH:-auto}" # auto, agent-forwarding, key-mount, none
|
|
152
155
|
readonly NAMESPACE="${DCLAUDE_NAMESPACE:-}"
|
|
153
156
|
CHROME_PORT="${DCLAUDE_CHROME_PORT:-9222}"
|
|
157
|
+
readonly AWS_CLI_MODE="${DCLAUDE_AWS_CLI:-auto}" # auto, mount, volume, none
|
|
154
158
|
|
|
155
159
|
# Show config file if loaded (always at info level, details at debug)
|
|
156
160
|
if [[ -n "$DCLAUDE_CONFIG_FILE" ]]; then
|
|
@@ -161,6 +165,7 @@ if [[ -n "$DCLAUDE_CONFIG_FILE" ]]; then
|
|
|
161
165
|
[[ -n "${DCLAUDE_GIT_AUTH:-}" ]] && debug " GIT_AUTH=$DCLAUDE_GIT_AUTH"
|
|
162
166
|
[[ -n "${DCLAUDE_CHROME_PORT:-}" ]] && debug " CHROME_PORT=$DCLAUDE_CHROME_PORT"
|
|
163
167
|
[[ -n "${DCLAUDE_MOUNT_ROOT:-}" ]] && debug " MOUNT_ROOT=$DCLAUDE_MOUNT_ROOT"
|
|
168
|
+
[[ -n "${DCLAUDE_AWS_CLI:-}" ]] && debug " AWS_CLI=$DCLAUDE_AWS_CLI"
|
|
164
169
|
fi
|
|
165
170
|
fi
|
|
166
171
|
|
|
@@ -510,6 +515,36 @@ get_volume_name() {
|
|
|
510
515
|
fi
|
|
511
516
|
}
|
|
512
517
|
|
|
518
|
+
# Get AWS volume name (includes namespace if set)
|
|
519
|
+
get_aws_volume_name() {
|
|
520
|
+
if [[ -n "$NAMESPACE" ]]; then
|
|
521
|
+
echo "${VOLUME_PREFIX}-${NAMESPACE}-aws"
|
|
522
|
+
else
|
|
523
|
+
echo "${VOLUME_PREFIX}-aws"
|
|
524
|
+
fi
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
# Resolve AWS CLI mode from configured value
|
|
528
|
+
# auto → mount (if ~/.aws exists) or none
|
|
529
|
+
resolve_aws_cli_mode() {
|
|
530
|
+
case "$AWS_CLI_MODE" in
|
|
531
|
+
mount|volume|none)
|
|
532
|
+
echo "$AWS_CLI_MODE"
|
|
533
|
+
;;
|
|
534
|
+
auto)
|
|
535
|
+
if [[ -d "${HOME}/.aws" ]]; then
|
|
536
|
+
echo "mount"
|
|
537
|
+
else
|
|
538
|
+
echo "none"
|
|
539
|
+
fi
|
|
540
|
+
;;
|
|
541
|
+
*)
|
|
542
|
+
warning "Unknown AWS_CLI mode: $AWS_CLI_MODE (using none)"
|
|
543
|
+
echo "none"
|
|
544
|
+
;;
|
|
545
|
+
esac
|
|
546
|
+
}
|
|
547
|
+
|
|
513
548
|
# Create Docker volumes if they don't exist
|
|
514
549
|
create_volumes() {
|
|
515
550
|
# Create essential volume for Claude CLI persistence
|
|
@@ -526,6 +561,24 @@ create_volumes() {
|
|
|
526
561
|
else
|
|
527
562
|
debug "Volume exists: $volume"
|
|
528
563
|
fi
|
|
564
|
+
|
|
565
|
+
# Create AWS volume if volume mode is active
|
|
566
|
+
local aws_mode
|
|
567
|
+
aws_mode=$(resolve_aws_cli_mode)
|
|
568
|
+
if [[ "$aws_mode" == "volume" ]]; then
|
|
569
|
+
local aws_volume
|
|
570
|
+
aws_volume=$(get_aws_volume_name)
|
|
571
|
+
if ! docker volume inspect "$aws_volume" &> /dev/null; then
|
|
572
|
+
info "Creating AWS volume: $aws_volume"
|
|
573
|
+
if ! docker volume create "$aws_volume" > /dev/null; then
|
|
574
|
+
error "Failed to create volume: $aws_volume"
|
|
575
|
+
exit 1
|
|
576
|
+
fi
|
|
577
|
+
debug "Volume created successfully: $aws_volume"
|
|
578
|
+
else
|
|
579
|
+
debug "Volume exists: $aws_volume"
|
|
580
|
+
fi
|
|
581
|
+
fi
|
|
529
582
|
}
|
|
530
583
|
|
|
531
584
|
# Pull or update the Docker image
|
|
@@ -660,6 +713,7 @@ generate_system_context() {
|
|
|
660
713
|
local has_docker="${3:-false}"
|
|
661
714
|
local platform="${4:-unknown}"
|
|
662
715
|
local docker_socket="${5:-}"
|
|
716
|
+
local aws_cli_mode="${6:-none}"
|
|
663
717
|
|
|
664
718
|
cat <<'EOF'
|
|
665
719
|
|
|
@@ -806,8 +860,36 @@ EOF
|
|
|
806
860
|
## Development Tools Available
|
|
807
861
|
- **Languages**: Node.js 20+, Python 3
|
|
808
862
|
- **Package Managers**: npm, pip, Homebrew/Linuxbrew
|
|
809
|
-
- **Tools**: git, gh (GitHub CLI), docker, docker-compose, curl, tmux, nano
|
|
863
|
+
- **Tools**: git, gh (GitHub CLI), docker, docker-compose, aws (AWS CLI v2), curl, tmux, nano
|
|
810
864
|
- **Shell**: bash (your commands execute in bash shell)
|
|
865
|
+
EOF
|
|
866
|
+
|
|
867
|
+
# AWS CLI context
|
|
868
|
+
case "$aws_cli_mode" in
|
|
869
|
+
mount)
|
|
870
|
+
cat <<'EOF'
|
|
871
|
+
- **AWS CLI**: Configured — credentials mounted from host's `~/.aws` directory
|
|
872
|
+
- All host AWS profiles, SSO config, and credentials are available
|
|
873
|
+
- Changes to AWS config (e.g., `aws sso login`) are shared with host
|
|
874
|
+
EOF
|
|
875
|
+
;;
|
|
876
|
+
volume)
|
|
877
|
+
cat <<'EOF'
|
|
878
|
+
- **AWS CLI**: Configured — credentials stored in persistent Docker volume
|
|
879
|
+
- AWS config is isolated from host and persists across container recreations
|
|
880
|
+
- Run `aws configure` or `aws configure sso` to set up credentials
|
|
881
|
+
EOF
|
|
882
|
+
;;
|
|
883
|
+
*)
|
|
884
|
+
cat <<'EOF'
|
|
885
|
+
- **AWS CLI**: Installed but no credentials configured
|
|
886
|
+
- User can set `DCLAUDE_AWS_CLI=mount` when launching dclaude to use host's `~/.aws` config
|
|
887
|
+
- User can set `DCLAUDE_AWS_CLI=volume` when launching dclaude for isolated persistent config
|
|
888
|
+
EOF
|
|
889
|
+
;;
|
|
890
|
+
esac
|
|
891
|
+
|
|
892
|
+
cat <<'EOF'
|
|
811
893
|
|
|
812
894
|
## Git Configuration Requirements
|
|
813
895
|
**IMPORTANT**: Before performing any git operations (commit, push, etc.), you MUST:
|
|
@@ -1573,14 +1655,27 @@ main() {
|
|
|
1573
1655
|
debug "Git auth: $resolved_git_auth (user-specified)"
|
|
1574
1656
|
fi
|
|
1575
1657
|
|
|
1658
|
+
# Warn if agent-forwarding is active but no keys are loaded
|
|
1659
|
+
if [[ "$resolved_git_auth" == "agent-forwarding" ]]; then
|
|
1660
|
+
local ssh_add_rc=0
|
|
1661
|
+
ssh-add -l >/dev/null 2>&1 || ssh_add_rc=$?
|
|
1662
|
+
if [[ $ssh_add_rc -eq 1 ]]; then
|
|
1663
|
+
warning "SSH agent has no keys loaded — SSH won't work inside container."
|
|
1664
|
+
warning "Run 'dclaude ssh keys' to load your keys."
|
|
1665
|
+
fi
|
|
1666
|
+
fi
|
|
1667
|
+
|
|
1576
1668
|
# Generate system context for Claude (if enabled) - must be done early for all code paths
|
|
1577
1669
|
local claude_args=()
|
|
1578
1670
|
if [[ "$ENABLE_SYSTEM_CONTEXT" == "true" ]]; then
|
|
1579
1671
|
local has_docker="false"
|
|
1580
1672
|
[[ -n "$DOCKER_SOCKET" ]] && [[ -S "$DOCKER_SOCKET" ]] && has_docker="true"
|
|
1581
1673
|
|
|
1674
|
+
local resolved_aws_cli_mode
|
|
1675
|
+
resolved_aws_cli_mode=$(resolve_aws_cli_mode)
|
|
1676
|
+
|
|
1582
1677
|
local system_context
|
|
1583
|
-
system_context=$(generate_system_context "$network_mode" "$resolved_git_auth" "$has_docker" "$platform" "$DOCKER_SOCKET")
|
|
1678
|
+
system_context=$(generate_system_context "$network_mode" "$resolved_git_auth" "$has_docker" "$platform" "$DOCKER_SOCKET" "$resolved_aws_cli_mode")
|
|
1584
1679
|
|
|
1585
1680
|
claude_args+=("--append-system-prompt" "$system_context")
|
|
1586
1681
|
debug "System context enabled (${#system_context} chars, has_docker=$has_docker, git_auth=$resolved_git_auth, platform=$platform)"
|
|
@@ -1793,6 +1888,32 @@ main() {
|
|
|
1793
1888
|
[[ -n "$ssh_arg" ]] && DOCKER_ARGS+=("$ssh_arg")
|
|
1794
1889
|
done < <(handle_git_auth)
|
|
1795
1890
|
|
|
1891
|
+
# Handle AWS CLI configuration mounting
|
|
1892
|
+
local resolved_aws_mode
|
|
1893
|
+
resolved_aws_mode=$(resolve_aws_cli_mode)
|
|
1894
|
+
# Pass mode to entrypoint so it knows whether to chown .aws (volume only)
|
|
1895
|
+
DOCKER_ARGS+=(-e "DCLAUDE_AWS_CLI_MODE=${resolved_aws_mode}")
|
|
1896
|
+
case "$resolved_aws_mode" in
|
|
1897
|
+
mount)
|
|
1898
|
+
if [[ -d "${HOME}/.aws" ]]; then
|
|
1899
|
+
DOCKER_ARGS+=(-v "${HOME}/.aws:/home/claude/.aws")
|
|
1900
|
+
info "AWS CLI: mounting host ~/.aws"
|
|
1901
|
+
debug "AWS config mounted from host: ${HOME}/.aws"
|
|
1902
|
+
else
|
|
1903
|
+
warning "AWS_CLI=mount but ~/.aws not found, skipping"
|
|
1904
|
+
fi
|
|
1905
|
+
;;
|
|
1906
|
+
volume)
|
|
1907
|
+
local aws_volume
|
|
1908
|
+
aws_volume=$(get_aws_volume_name)
|
|
1909
|
+
DOCKER_ARGS+=(-v "${aws_volume}:/home/claude/.aws")
|
|
1910
|
+
debug "AWS config using volume: $aws_volume"
|
|
1911
|
+
;;
|
|
1912
|
+
none)
|
|
1913
|
+
debug "AWS CLI config mounting disabled"
|
|
1914
|
+
;;
|
|
1915
|
+
esac
|
|
1916
|
+
|
|
1796
1917
|
# Add any additional environment variables
|
|
1797
1918
|
if [[ -n "${CLAUDE_MODEL:-}" ]]; then
|
|
1798
1919
|
DOCKER_ARGS+=(-e "CLAUDE_MODEL=${CLAUDE_MODEL}")
|
|
@@ -2269,8 +2390,117 @@ cmd_stop() {
|
|
|
2269
2390
|
exit 0
|
|
2270
2391
|
}
|
|
2271
2392
|
|
|
2272
|
-
# Subcommand: SSH
|
|
2393
|
+
# Subcommand: SSH — dispatches to 'keys', 'server', or both
|
|
2273
2394
|
cmd_ssh() {
|
|
2395
|
+
local rc=0
|
|
2396
|
+
case "${1:-}" in
|
|
2397
|
+
keys)
|
|
2398
|
+
shift
|
|
2399
|
+
cmd_ssh_keys "$@" || rc=$?
|
|
2400
|
+
;;
|
|
2401
|
+
server)
|
|
2402
|
+
shift
|
|
2403
|
+
cmd_ssh_server "$@" || rc=$?
|
|
2404
|
+
;;
|
|
2405
|
+
--help|-h)
|
|
2406
|
+
cat << 'SSH_HELP'
|
|
2407
|
+
dclaude ssh - SSH Key and Server Management
|
|
2408
|
+
|
|
2409
|
+
Usage:
|
|
2410
|
+
dclaude ssh Load SSH keys into agent and start SSH server
|
|
2411
|
+
dclaude ssh keys Load SSH keys into agent
|
|
2412
|
+
dclaude ssh server Start SSH server and show connection info
|
|
2413
|
+
dclaude ssh server --stop Stop SSH server
|
|
2414
|
+
|
|
2415
|
+
SSH_HELP
|
|
2416
|
+
exit 0
|
|
2417
|
+
;;
|
|
2418
|
+
"")
|
|
2419
|
+
# Bare 'dclaude ssh': load keys (non-fatal), then start server
|
|
2420
|
+
cmd_ssh_keys "$@" || true
|
|
2421
|
+
echo ""
|
|
2422
|
+
cmd_ssh_server "$@" || rc=$?
|
|
2423
|
+
;;
|
|
2424
|
+
*)
|
|
2425
|
+
error "Unknown subcommand: $1"
|
|
2426
|
+
info "Usage: dclaude ssh [keys | server]"
|
|
2427
|
+
exit 1
|
|
2428
|
+
;;
|
|
2429
|
+
esac
|
|
2430
|
+
exit "$rc"
|
|
2431
|
+
}
|
|
2432
|
+
|
|
2433
|
+
# Subcommand: SSH key loading
|
|
2434
|
+
cmd_ssh_keys() {
|
|
2435
|
+
# Parse flags
|
|
2436
|
+
while [[ $# -gt 0 ]]; do
|
|
2437
|
+
case "$1" in
|
|
2438
|
+
--help|-h)
|
|
2439
|
+
cat << 'SSH_KEYS_HELP'
|
|
2440
|
+
dclaude ssh keys - Load SSH Keys into Agent
|
|
2441
|
+
|
|
2442
|
+
Usage:
|
|
2443
|
+
dclaude ssh keys Detect and load SSH keys from ~/.ssh/
|
|
2444
|
+
|
|
2445
|
+
Detects private keys (id_rsa, id_ed25519, etc.) in ~/.ssh/ and loads
|
|
2446
|
+
them into the SSH agent via ssh-add. May prompt for passphrases.
|
|
2447
|
+
|
|
2448
|
+
SSH_KEYS_HELP
|
|
2449
|
+
return 0
|
|
2450
|
+
;;
|
|
2451
|
+
*)
|
|
2452
|
+
error "Unknown option: $1"
|
|
2453
|
+
info "Usage: dclaude ssh keys"
|
|
2454
|
+
return 1
|
|
2455
|
+
;;
|
|
2456
|
+
esac
|
|
2457
|
+
done
|
|
2458
|
+
|
|
2459
|
+
local ssh_dir="${HOME}/.ssh"
|
|
2460
|
+
if [[ ! -d "$ssh_dir" ]]; then
|
|
2461
|
+
error "No ~/.ssh directory found"
|
|
2462
|
+
return 1
|
|
2463
|
+
fi
|
|
2464
|
+
|
|
2465
|
+
# Detect private key files
|
|
2466
|
+
local keys=()
|
|
2467
|
+
for key_file in "$ssh_dir"/id_*; do
|
|
2468
|
+
[[ -f "$key_file" ]] || continue
|
|
2469
|
+
# Skip public keys and certificates
|
|
2470
|
+
[[ "$key_file" == *.pub ]] && continue
|
|
2471
|
+
[[ "$key_file" == *-cert.pub ]] && continue
|
|
2472
|
+
keys+=("$key_file")
|
|
2473
|
+
done
|
|
2474
|
+
|
|
2475
|
+
if [[ ${#keys[@]} -eq 0 ]]; then
|
|
2476
|
+
warning "No SSH keys found in ~/.ssh/"
|
|
2477
|
+
info "Generate a key with: ssh-keygen -t ed25519"
|
|
2478
|
+
return 1
|
|
2479
|
+
fi
|
|
2480
|
+
|
|
2481
|
+
info "Loading SSH keys..."
|
|
2482
|
+
local loaded=0
|
|
2483
|
+
for key_file in "${keys[@]}"; do
|
|
2484
|
+
local display_path="~/.ssh/$(basename "$key_file")"
|
|
2485
|
+
if ssh-add "$key_file" 2>/dev/null; then
|
|
2486
|
+
success " $display_path"
|
|
2487
|
+
loaded=$((loaded + 1))
|
|
2488
|
+
else
|
|
2489
|
+
warning " $display_path (failed — wrong passphrase or unsupported key)"
|
|
2490
|
+
fi
|
|
2491
|
+
done
|
|
2492
|
+
|
|
2493
|
+
echo ""
|
|
2494
|
+
if [[ $loaded -gt 0 ]]; then
|
|
2495
|
+
success "$loaded key(s) loaded into SSH agent."
|
|
2496
|
+
else
|
|
2497
|
+
error "No keys were loaded"
|
|
2498
|
+
return 1
|
|
2499
|
+
fi
|
|
2500
|
+
}
|
|
2501
|
+
|
|
2502
|
+
# Subcommand: SSH server for remote access (JetBrains Gateway, debugging, etc.)
|
|
2503
|
+
cmd_ssh_server() {
|
|
2274
2504
|
local action=""
|
|
2275
2505
|
|
|
2276
2506
|
# Parse flags
|
|
@@ -2281,12 +2511,12 @@ cmd_ssh() {
|
|
|
2281
2511
|
shift
|
|
2282
2512
|
;;
|
|
2283
2513
|
--help|-h)
|
|
2284
|
-
cat << '
|
|
2285
|
-
dclaude ssh - SSH Server for Remote Access
|
|
2514
|
+
cat << 'SSH_SERVER_HELP'
|
|
2515
|
+
dclaude ssh server - SSH Server for Remote Access
|
|
2286
2516
|
|
|
2287
2517
|
Usage:
|
|
2288
|
-
dclaude ssh
|
|
2289
|
-
dclaude ssh --stop
|
|
2518
|
+
dclaude ssh server Start SSH server and show connection info
|
|
2519
|
+
dclaude ssh server --stop Stop SSH server
|
|
2290
2520
|
|
|
2291
2521
|
Connection:
|
|
2292
2522
|
ssh claude@localhost -p <port>
|
|
@@ -2301,20 +2531,20 @@ Use Cases:
|
|
|
2301
2531
|
|
|
2302
2532
|
JetBrains Gateway Setup:
|
|
2303
2533
|
1. Start container: dclaude
|
|
2304
|
-
2. Start SSH: dclaude ssh
|
|
2534
|
+
2. Start SSH: dclaude ssh server
|
|
2305
2535
|
3. Open JetBrains Gateway
|
|
2306
2536
|
4. New Connection → SSH → localhost:<port shown above>
|
|
2307
2537
|
5. Username: claude, Password: claude
|
|
2308
2538
|
6. Gateway will download and install IDE backend automatically
|
|
2309
2539
|
7. Select your project directory
|
|
2310
2540
|
|
|
2311
|
-
|
|
2312
|
-
|
|
2541
|
+
SSH_SERVER_HELP
|
|
2542
|
+
return 0
|
|
2313
2543
|
;;
|
|
2314
2544
|
*)
|
|
2315
2545
|
error "Unknown option: $1"
|
|
2316
|
-
info "Usage: dclaude ssh [--stop]"
|
|
2317
|
-
|
|
2546
|
+
info "Usage: dclaude ssh server [--stop]"
|
|
2547
|
+
return 1
|
|
2318
2548
|
;;
|
|
2319
2549
|
esac
|
|
2320
2550
|
done
|
|
@@ -2325,7 +2555,7 @@ SSH_HELP
|
|
|
2325
2555
|
if ! docker ps -a --format '{{.Names}}' | grep -q "^${container_name}$"; then
|
|
2326
2556
|
error "No container found for this directory"
|
|
2327
2557
|
info "Run 'dclaude' first to create a persistent container"
|
|
2328
|
-
|
|
2558
|
+
return 1
|
|
2329
2559
|
fi
|
|
2330
2560
|
|
|
2331
2561
|
local container_status=$(docker inspect --format='{{.State.Status}}' "$container_name" 2>/dev/null)
|
|
@@ -2337,7 +2567,7 @@ SSH_HELP
|
|
|
2337
2567
|
sleep 1
|
|
2338
2568
|
else
|
|
2339
2569
|
error "Container $container_name is in unexpected state: $container_status"
|
|
2340
|
-
|
|
2570
|
+
return 1
|
|
2341
2571
|
fi
|
|
2342
2572
|
fi
|
|
2343
2573
|
|
|
@@ -2353,9 +2583,9 @@ SSH_HELP
|
|
|
2353
2583
|
echo ""
|
|
2354
2584
|
echo " dclaude rm -f"
|
|
2355
2585
|
echo " dclaude"
|
|
2356
|
-
echo " dclaude ssh"
|
|
2586
|
+
echo " dclaude ssh server"
|
|
2357
2587
|
echo ""
|
|
2358
|
-
|
|
2588
|
+
return 1
|
|
2359
2589
|
fi
|
|
2360
2590
|
|
|
2361
2591
|
case "$action" in
|
|
@@ -2397,8 +2627,6 @@ SSH_HELP
|
|
|
2397
2627
|
echo ""
|
|
2398
2628
|
;;
|
|
2399
2629
|
esac
|
|
2400
|
-
|
|
2401
|
-
exit 0
|
|
2402
2630
|
}
|
|
2403
2631
|
|
|
2404
2632
|
# Subcommand: remove container for current directory
|
|
@@ -2477,6 +2705,133 @@ cmd_rm() {
|
|
|
2477
2705
|
}
|
|
2478
2706
|
|
|
2479
2707
|
# Subcommand: configure git identity
|
|
2708
|
+
cmd_aws_configure() {
|
|
2709
|
+
local container_name="$1"
|
|
2710
|
+
|
|
2711
|
+
# This subcommand only makes sense for volume mode
|
|
2712
|
+
local resolved_mode
|
|
2713
|
+
resolved_mode=$(resolve_aws_cli_mode)
|
|
2714
|
+
if [[ "$resolved_mode" != "volume" ]]; then
|
|
2715
|
+
error "dclaude aws configure is only for AWS_CLI=volume mode"
|
|
2716
|
+
if [[ "$resolved_mode" == "mount" ]]; then
|
|
2717
|
+
info "Current mode is 'mount' — host's ~/.aws is already available in the container"
|
|
2718
|
+
else
|
|
2719
|
+
info "Set DCLAUDE_AWS_CLI=volume to use persistent AWS volume"
|
|
2720
|
+
fi
|
|
2721
|
+
exit 1
|
|
2722
|
+
fi
|
|
2723
|
+
|
|
2724
|
+
echo ""
|
|
2725
|
+
echo "AWS CLI Configuration"
|
|
2726
|
+
echo "─────────────────────"
|
|
2727
|
+
|
|
2728
|
+
# Check existing config in container
|
|
2729
|
+
local existing_config
|
|
2730
|
+
existing_config=$(docker exec -u claude "$container_name" cat /home/claude/.aws/config 2>/dev/null || echo "")
|
|
2731
|
+
|
|
2732
|
+
if [[ -n "$existing_config" ]]; then
|
|
2733
|
+
echo "Current config in container:"
|
|
2734
|
+
echo "$existing_config" | sed 's/^/ /'
|
|
2735
|
+
echo ""
|
|
2736
|
+
read -p "Overwrite with host config? [y/N]: " overwrite
|
|
2737
|
+
if [[ "$overwrite" != "y" && "$overwrite" != "Y" ]]; then
|
|
2738
|
+
exit 0
|
|
2739
|
+
fi
|
|
2740
|
+
fi
|
|
2741
|
+
|
|
2742
|
+
# Check host config
|
|
2743
|
+
if [[ ! -f "${HOME}/.aws/config" ]]; then
|
|
2744
|
+
error "No ~/.aws/config found on host"
|
|
2745
|
+
info "Run 'aws configure sso' on your host first, then re-run this command"
|
|
2746
|
+
exit 1
|
|
2747
|
+
fi
|
|
2748
|
+
|
|
2749
|
+
echo "Found on host:"
|
|
2750
|
+
sed 's/^/ /' "${HOME}/.aws/config"
|
|
2751
|
+
echo ""
|
|
2752
|
+
info "Only config (profiles, regions, SSO URLs) will be copied — no credentials or tokens"
|
|
2753
|
+
echo ""
|
|
2754
|
+
read -p "Copy to container? [Y/n]: " copy
|
|
2755
|
+
if [[ "$copy" == "n" || "$copy" == "N" ]]; then
|
|
2756
|
+
exit 0
|
|
2757
|
+
fi
|
|
2758
|
+
|
|
2759
|
+
# Copy config file into container (docker cp copies as root, fix ownership after)
|
|
2760
|
+
docker exec -u claude "$container_name" mkdir -p /home/claude/.aws
|
|
2761
|
+
docker cp "${HOME}/.aws/config" "${container_name}:/home/claude/.aws/config"
|
|
2762
|
+
docker exec "$container_name" chown claude:claude /home/claude/.aws /home/claude/.aws/config
|
|
2763
|
+
docker exec "$container_name" chmod 600 /home/claude/.aws/config
|
|
2764
|
+
|
|
2765
|
+
echo ""
|
|
2766
|
+
success "AWS config copied to container"
|
|
2767
|
+
info "Run 'dclaude aws login' or 'aws login' inside dclaude to authenticate"
|
|
2768
|
+
exit 0
|
|
2769
|
+
}
|
|
2770
|
+
|
|
2771
|
+
cmd_aws_login() {
|
|
2772
|
+
local container_name="$1"
|
|
2773
|
+
shift
|
|
2774
|
+
|
|
2775
|
+
local tty_flags
|
|
2776
|
+
tty_flags=$(detect_tty_flags)
|
|
2777
|
+
|
|
2778
|
+
info "Starting AWS login..."
|
|
2779
|
+
# shellcheck disable=SC2086
|
|
2780
|
+
exec docker exec $tty_flags -u claude "$container_name" aws login "$@"
|
|
2781
|
+
}
|
|
2782
|
+
|
|
2783
|
+
cmd_aws() {
|
|
2784
|
+
local container_name=$(get_container_name "$HOST_PATH")
|
|
2785
|
+
|
|
2786
|
+
# Check if container exists
|
|
2787
|
+
if ! docker ps -a --format '{{.Names}}' | grep -q "^${container_name}$"; then
|
|
2788
|
+
error "No container found for this directory"
|
|
2789
|
+
info "Run 'dclaude' first to create a container"
|
|
2790
|
+
exit 1
|
|
2791
|
+
fi
|
|
2792
|
+
|
|
2793
|
+
# Check if container is running
|
|
2794
|
+
local container_status=$(docker inspect --format='{{.State.Status}}' "$container_name" 2>/dev/null)
|
|
2795
|
+
if [[ "$container_status" != "running" ]]; then
|
|
2796
|
+
if [[ "$container_status" == "exited" ]]; then
|
|
2797
|
+
info "Starting container: $container_name"
|
|
2798
|
+
docker start "$container_name" >/dev/null
|
|
2799
|
+
sleep 1
|
|
2800
|
+
else
|
|
2801
|
+
error "Container $container_name is in unexpected state: $container_status"
|
|
2802
|
+
exit 1
|
|
2803
|
+
fi
|
|
2804
|
+
fi
|
|
2805
|
+
|
|
2806
|
+
# Dispatch subcommands
|
|
2807
|
+
local subcmd="${1:-}"
|
|
2808
|
+
case "$subcmd" in
|
|
2809
|
+
configure)
|
|
2810
|
+
shift
|
|
2811
|
+
cmd_aws_configure "$container_name" "$@"
|
|
2812
|
+
;;
|
|
2813
|
+
login)
|
|
2814
|
+
shift
|
|
2815
|
+
cmd_aws_login "$container_name" "$@"
|
|
2816
|
+
;;
|
|
2817
|
+
--help|-h|"")
|
|
2818
|
+
echo "Usage:"
|
|
2819
|
+
echo " dclaude aws configure Copy AWS config from host (volume mode)"
|
|
2820
|
+
echo " dclaude aws login Run AWS login in container"
|
|
2821
|
+
echo " dclaude aws login --profile <name> Login with specific profile"
|
|
2822
|
+
exit 0
|
|
2823
|
+
;;
|
|
2824
|
+
*)
|
|
2825
|
+
error "Unknown subcommand: $subcmd"
|
|
2826
|
+
echo "Usage:"
|
|
2827
|
+
echo " dclaude aws configure Copy AWS config from host (volume mode)"
|
|
2828
|
+
echo " dclaude aws login Run AWS login in container"
|
|
2829
|
+
echo " dclaude aws login --profile <name> Login with specific profile"
|
|
2830
|
+
exit 1
|
|
2831
|
+
;;
|
|
2832
|
+
esac
|
|
2833
|
+
}
|
|
2834
|
+
|
|
2480
2835
|
cmd_git() {
|
|
2481
2836
|
local container_name=$(get_container_name "$HOST_PATH")
|
|
2482
2837
|
|
|
@@ -2616,6 +2971,10 @@ if [[ $# -gt 0 ]]; then
|
|
|
2616
2971
|
shift
|
|
2617
2972
|
cmd_git "$@"
|
|
2618
2973
|
;;
|
|
2974
|
+
aws)
|
|
2975
|
+
shift
|
|
2976
|
+
cmd_aws "$@"
|
|
2977
|
+
;;
|
|
2619
2978
|
--help|-h|help)
|
|
2620
2979
|
cat << 'EOF'
|
|
2621
2980
|
dclaude - Dockerized Claude Code Launcher
|
|
@@ -2628,8 +2987,12 @@ Usage:
|
|
|
2628
2987
|
dclaude update Update Claude CLI inside container
|
|
2629
2988
|
dclaude stop Stop container for current directory
|
|
2630
2989
|
dclaude rm [-f] Remove container for current directory
|
|
2631
|
-
dclaude ssh
|
|
2990
|
+
dclaude ssh Load SSH keys and start SSH server
|
|
2991
|
+
dclaude ssh keys Load SSH keys into agent
|
|
2992
|
+
dclaude ssh server Start SSH server for remote access
|
|
2632
2993
|
dclaude git Configure git identity (name/email)
|
|
2994
|
+
dclaude aws configure Copy AWS config from host to container (volume mode)
|
|
2995
|
+
dclaude aws login Run AWS login in container
|
|
2633
2996
|
dclaude chrome [options] Launch Chrome with DevTools and MCP integration
|
|
2634
2997
|
dclaude gh Authenticate GitHub CLI (runs gh auth login)
|
|
2635
2998
|
dclaude exec [command] Execute command in container (default: bash)
|
|
@@ -2644,6 +3007,7 @@ Environment Variables:
|
|
|
2644
3007
|
DCLAUDE_GIT_AUTH SSH auth for Git: auto, agent-forwarding, key-mount, none
|
|
2645
3008
|
DCLAUDE_NETWORK Network mode: auto, host, bridge
|
|
2646
3009
|
DCLAUDE_MOUNT_ROOT Mount parent directory (absolute or relative path)
|
|
3010
|
+
DCLAUDE_AWS_CLI AWS config mode: auto, mount, volume, none
|
|
2647
3011
|
DCLAUDE_DOCKER_SOCKET Override Docker socket path
|
|
2648
3012
|
DCLAUDE_TMUX_SESSION Custom tmux session name (default: claude-TIMESTAMP)
|
|
2649
3013
|
DCLAUDE_CHROME_BIN Chrome executable path (auto-detected if not set)
|
|
@@ -2655,6 +3019,7 @@ Configuration File (.dclaude):
|
|
|
2655
3019
|
Create a .dclaude file at project root to configure dclaude for that tree:
|
|
2656
3020
|
NAMESPACE=mycompany
|
|
2657
3021
|
NETWORK=host
|
|
3022
|
+
AWS_CLI=mount
|
|
2658
3023
|
DEBUG=true
|
|
2659
3024
|
MOUNT_ROOT=. # Mount config file's directory
|
|
2660
3025
|
MOUNT_ROOT=.. # Mount parent of config file's directory
|
|
@@ -2693,9 +3058,11 @@ Examples:
|
|
|
2693
3058
|
dclaude rm # Remove stopped container
|
|
2694
3059
|
dclaude rm -f # Force remove running container
|
|
2695
3060
|
|
|
2696
|
-
# SSH
|
|
2697
|
-
dclaude ssh #
|
|
2698
|
-
dclaude ssh
|
|
3061
|
+
# SSH key and server management
|
|
3062
|
+
dclaude ssh # Load keys + start SSH server
|
|
3063
|
+
dclaude ssh keys # Load SSH keys into agent
|
|
3064
|
+
dclaude ssh server # Start SSH server, show connection info
|
|
3065
|
+
dclaude ssh server --stop # Stop SSH server
|
|
2699
3066
|
|
|
2700
3067
|
# Launch Chrome with DevTools for MCP integration
|
|
2701
3068
|
dclaude chrome
|