Skip to content

Commit 685007e

Browse files
committed
Claude works
1 parent 00a892d commit 685007e

3 files changed

Lines changed: 132 additions & 127 deletions

File tree

dot_files/ai-dev/Justfile

Lines changed: 72 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ local_image := "localhost/ai-dev"
55
remote_image := "ghcr.io/binarypie-dev/ai-dev:latest"
66

77
# Common podman run flags (UID 0 inside = host user in rootless podman)
8-
podman_flags := "--rm -it --user 0:0 --security-opt label=disable"
8+
podman_flags := "--rm -it --init --user 0:0 --security-opt label=disable"
99

1010
# Default recipe - show help
1111
default:
@@ -44,12 +44,13 @@ push:
4444
claude *args:
4545
#!/usr/bin/bash
4646
set -euo pipefail
47-
mkdir -p "$HOME/.claude" "$HOME/.config/claude"
47+
mkdir -p "$HOME/.claude"
48+
touch "$HOME/.claude.json"
4849
exec podman run {{podman_flags}} \
4950
-e HOME="$HOME" \
5051
-v "$(pwd):$(pwd):rw" \
5152
-v "$HOME/.claude:$HOME/.claude:rw" \
52-
-v "$HOME/.config/claude:$HOME/.config/claude:rw" \
53+
-v "$HOME/.claude.json:$HOME/.claude.json:rw" \
5354
-w "$(pwd)" \
5455
{{local_image}} \
5556
claude {{args}}
@@ -76,7 +77,8 @@ gemini *args:
7677
enter:
7778
#!/usr/bin/bash
7879
set -euo pipefail
79-
mkdir -p "$HOME/.claude" "$HOME/.config/claude" "$HOME/.gemini"
80+
mkdir -p "$HOME/.claude" "$HOME/.gemini"
81+
touch "$HOME/.claude.json"
8082
env_flags=""
8183
for var in $(env | grep -E '^(GOOGLE_|GEMINI_|ANTHROPIC_)' | cut -d= -f1); do
8284
env_flags="$env_flags -e $var"
@@ -86,7 +88,7 @@ enter:
8688
$env_flags \
8789
-v "$(pwd):$(pwd):rw" \
8890
-v "$HOME/.claude:$HOME/.claude:rw" \
89-
-v "$HOME/.config/claude:$HOME/.config/claude:rw" \
91+
-v "$HOME/.claude.json:$HOME/.claude.json:rw" \
9092
-v "$HOME/.gemini:$HOME/.gemini:rw" \
9193
-w "$(pwd)" \
9294
{{local_image}}
@@ -100,91 +102,79 @@ install:
100102
#!/usr/bin/bash
101103
set -euo pipefail
102104
mkdir -p "$HOME/.local/bin"
103-
104-
cat > "$HOME/.local/bin/claude" << 'WRAPPER'
105-
#!/usr/bin/bash
106-
set -euo pipefail
107-
mkdir -p "$HOME/.claude" "$HOME/.config/claude"
108-
exec podman run --rm -it \
109-
--user 0:0 \
110-
--security-opt label=disable \
111-
-e HOME="$HOME" \
112-
-v "$(pwd):$(pwd):rw" \
113-
-v "$HOME/.claude:$HOME/.claude:rw" \
114-
-v "$HOME/.config/claude:$HOME/.config/claude:rw" \
115-
-w "$(pwd)" \
116-
ghcr.io/binarypie-dev/ai-dev:latest \
117-
claude "$@"
118-
WRAPPER
105+
printf '%s\n' '#!/usr/bin/bash' \
106+
'set -euo pipefail' \
107+
'mkdir -p "$HOME/.claude"' \
108+
'touch "$HOME/.claude.json"' \
109+
'exec podman run --rm -it --init \' \
110+
' --user 0:0 \' \
111+
' --security-opt label=disable \' \
112+
' -e HOME="$HOME" \' \
113+
' -v "$(pwd):$(pwd):rw" \' \
114+
' -v "$HOME/.claude:$HOME/.claude:rw" \' \
115+
' -v "$HOME/.claude.json:$HOME/.claude.json:rw" \' \
116+
' -w "$(pwd)" \' \
117+
' ghcr.io/binarypie-dev/ai-dev:latest \' \
118+
' claude "$@"' > "$HOME/.local/bin/claude"
119119
chmod +x "$HOME/.local/bin/claude"
120-
121-
cat > "$HOME/.local/bin/gemini" << 'WRAPPER'
122-
#!/usr/bin/bash
123-
set -euo pipefail
124-
mkdir -p "$HOME/.gemini"
125-
env_flags=""
126-
for var in $(env | grep -E '^(GOOGLE_|GEMINI_)' | cut -d= -f1); do
127-
env_flags="$env_flags -e $var"
128-
done
129-
exec podman run --rm -it \
130-
--user 0:0 \
131-
--security-opt label=disable \
132-
-e HOME="$HOME" \
133-
$env_flags \
134-
-v "$(pwd):$(pwd):rw" \
135-
-v "$HOME/.gemini:$HOME/.gemini:rw" \
136-
-w "$(pwd)" \
137-
ghcr.io/binarypie-dev/ai-dev:latest \
138-
gemini "$@"
139-
WRAPPER
120+
printf '%s\n' '#!/usr/bin/bash' \
121+
'set -euo pipefail' \
122+
'mkdir -p "$HOME/.gemini"' \
123+
'env_flags=""' \
124+
'for var in $(env | grep -E '"'"'^(GOOGLE_|GEMINI_)'"'"' | cut -d= -f1); do' \
125+
' env_flags="$env_flags -e $var"' \
126+
'done' \
127+
'exec podman run --rm -it --init \' \
128+
' --user 0:0 \' \
129+
' --security-opt label=disable \' \
130+
' -e HOME="$HOME" \' \
131+
' $env_flags \' \
132+
' -v "$(pwd):$(pwd):rw" \' \
133+
' -v "$HOME/.gemini:$HOME/.gemini:rw" \' \
134+
' -w "$(pwd)" \' \
135+
' ghcr.io/binarypie-dev/ai-dev:latest \' \
136+
' gemini "$@"' > "$HOME/.local/bin/gemini"
140137
chmod +x "$HOME/.local/bin/gemini"
141-
142138
echo "Installed wrapper scripts to ~/.local/bin/claude and ~/.local/bin/gemini"
143139

144140
# Install wrapper scripts pointing to local image
145141
install-local:
146142
#!/usr/bin/bash
147143
set -euo pipefail
148144
mkdir -p "$HOME/.local/bin"
149-
150-
cat > "$HOME/.local/bin/claude" << 'WRAPPER'
151-
#!/usr/bin/bash
152-
set -euo pipefail
153-
mkdir -p "$HOME/.claude" "$HOME/.config/claude"
154-
exec podman run --rm -it \
155-
--user 0:0 \
156-
--security-opt label=disable \
157-
-e HOME="$HOME" \
158-
-v "$(pwd):$(pwd):rw" \
159-
-v "$HOME/.claude:$HOME/.claude:rw" \
160-
-v "$HOME/.config/claude:$HOME/.config/claude:rw" \
161-
-w "$(pwd)" \
162-
localhost/ai-dev \
163-
claude "$@"
164-
WRAPPER
145+
printf '%s\n' '#!/usr/bin/bash' \
146+
'set -euo pipefail' \
147+
'mkdir -p "$HOME/.claude"' \
148+
'touch "$HOME/.claude.json"' \
149+
'exec podman run --rm -it --init \' \
150+
' --user 0:0 \' \
151+
' --security-opt label=disable \' \
152+
' -e HOME="$HOME" \' \
153+
' -v "$(pwd):$(pwd):rw" \' \
154+
' -v "$HOME/.claude:$HOME/.claude:rw" \' \
155+
' -v "$HOME/.claude.json:$HOME/.claude.json:rw" \' \
156+
' -w "$(pwd)" \' \
157+
' localhost/ai-dev \' \
158+
' claude "$@"' > "$HOME/.local/bin/claude"
165159
chmod +x "$HOME/.local/bin/claude"
166-
167-
cat > "$HOME/.local/bin/gemini" << 'WRAPPER'
168-
#!/usr/bin/bash
169-
set -euo pipefail
170-
mkdir -p "$HOME/.gemini"
171-
env_flags=""
172-
for var in $(env | grep -E '^(GOOGLE_|GEMINI_)' | cut -d= -f1); do
173-
env_flags="$env_flags -e $var"
174-
done
175-
exec podman run --rm -it \
176-
--user 0:0 \
177-
--security-opt label=disable \
178-
-e HOME="$HOME" \
179-
$env_flags \
180-
-v "$(pwd):$(pwd):rw" \
181-
-v "$HOME/.gemini:$HOME/.gemini:rw" \
182-
-w "$(pwd)" \
183-
localhost/ai-dev \
184-
gemini "$@"
185-
WRAPPER
160+
printf '%s\n' '#!/usr/bin/bash' \
161+
'set -euo pipefail' \
162+
'mkdir -p "$HOME/.gemini"' \
163+
'env_flags=""' \
164+
'for var in $(env | grep -E '"'"'^(GOOGLE_|GEMINI_)'"'"' | cut -d= -f1); do' \
165+
' env_flags="$env_flags -e $var"' \
166+
'done' \
167+
'exec podman run --rm -it --init \' \
168+
' --user 0:0 \' \
169+
' --security-opt label=disable \' \
170+
' -e HOME="$HOME" \' \
171+
' $env_flags \' \
172+
' -v "$(pwd):$(pwd):rw" \' \
173+
' -v "$HOME/.gemini:$HOME/.gemini:rw" \' \
174+
' -w "$(pwd)" \' \
175+
' localhost/ai-dev \' \
176+
' gemini "$@"' > "$HOME/.local/bin/gemini"
186177
chmod +x "$HOME/.local/bin/gemini"
187-
188178
echo "Installed wrapper scripts (local image) to ~/.local/bin/claude and ~/.local/bin/gemini"
189179

190180
# Remove wrapper scripts from ~/.local/bin
@@ -226,7 +216,8 @@ test-build: build
226216
debug:
227217
#!/usr/bin/bash
228218
set -euo pipefail
229-
mkdir -p "$HOME/.claude" "$HOME/.config/claude" "$HOME/.gemini"
219+
mkdir -p "$HOME/.claude" "$HOME/.gemini"
220+
touch "$HOME/.claude.json"
230221
env_flags=""
231222
for var in $(env | grep -E '^(GOOGLE_|GEMINI_|ANTHROPIC_)' | cut -d= -f1); do
232223
env_flags="$env_flags -e $var"
@@ -236,7 +227,7 @@ debug:
236227
$env_flags \
237228
-v "$(pwd):$(pwd):rw" \
238229
-v "$HOME/.claude:$HOME/.claude:rw" \
239-
-v "$HOME/.config/claude:$HOME/.config/claude:rw" \
230+
-v "$HOME/.claude.json:$HOME/.claude.json:rw" \
240231
-v "$HOME/.gemini:$HOME/.gemini:rw" \
241232
-w "$(pwd)" \
242233
{{local_image}} \

dot_files/ai-dev/ai-entrypoint.sh

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,25 @@
11
#!/usr/bin/bash
22
set -e
33

4-
export PATH="/home/linuxbrew/.local/bin:/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:/home/linuxbrew/.npm-global/bin:/home/linuxbrew/go/bin:/home/linuxbrew/.cargo/bin:$PATH"
4+
# Fix root's home directory in /etc/passwd to match host $HOME
5+
# This ensures os.homedir() in Node.js (used by claude/gemini) returns the correct path
6+
if [ -n "$HOME" ] && [ "$HOME" != "/root" ]; then
7+
sed -i "s|root:x:0:0:[^:]*:/root:|root:x:0:0:root:$HOME:|" /etc/passwd 2>/dev/null || true
8+
fi
9+
10+
# Symlink claude install paths to where the native installer expects them at runtime
11+
# (installed under /home/linuxbrew at build time, but $HOME differs at runtime)
12+
if [ -n "$HOME" ] && [ "$HOME" != "/home/linuxbrew" ]; then
13+
mkdir -p "$HOME/.local/bin" "$HOME/.local/share"
14+
ln -sf /home/linuxbrew/.local/bin/claude "$HOME/.local/bin/claude" 2>/dev/null || true
15+
ln -sf /home/linuxbrew/.local/share/claude "$HOME/.local/share/claude" 2>/dev/null || true
16+
fi
17+
18+
# Ensure claude auth files are readable within the container
19+
chmod -R a+rX "$HOME/.claude" 2>/dev/null || true
20+
chmod a+rw "$HOME/.claude.json" 2>/dev/null || true
21+
22+
export PATH="$HOME/.local/bin:/home/linuxbrew/.local/bin:/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:/home/linuxbrew/.npm-global/bin:/home/linuxbrew/go/bin:/home/linuxbrew/.cargo/bin:$PATH"
523

624
# Debug mode: print environment and auth state
725
if [ "$1" = "--ai-dev-debug" ]; then
@@ -10,6 +28,9 @@ if [ "$1" = "--ai-dev-debug" ]; then
1028
echo "HOME=$HOME"
1129
echo "PATH=$PATH"
1230
echo ""
31+
echo "=== /etc/passwd root entry ==="
32+
grep "^root:" /etc/passwd
33+
echo ""
1334
echo "=== TTY ==="
1435
ls -la /dev/pts/ 2>/dev/null || echo "no /dev/pts"
1536
echo "tty: $(tty 2>/dev/null || echo 'not a tty')"
@@ -23,9 +44,6 @@ if [ "$1" = "--ai-dev-debug" ]; then
2344
echo "=== $HOME/.claude/ ==="
2445
ls -la "$HOME/.claude/" 2>/dev/null || echo "not found at $HOME/.claude/"
2546
echo ""
26-
echo "=== $HOME/.config/claude/ ==="
27-
ls -la "$HOME/.config/claude/" 2>/dev/null || echo "not found at $HOME/.config/claude/"
28-
echo ""
2947
echo "=== which claude/gemini ==="
3048
which claude 2>/dev/null || echo "claude: not found"
3149
which gemini 2>/dev/null || echo "gemini: not found"

system_files/shared/usr/share/ublue-os/just/62-ai.just

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,19 @@
22
# Hypercube AI development environment commands
33

44
ai_image := "ghcr.io/binarypie-dev/ai-dev:latest"
5-
ai_podman_flags := "--rm -it --user 0:0 --security-opt label=disable"
5+
ai_podman_flags := "--rm -it --init --user 0:0 --security-opt label=disable"
66

77
# Run Claude Code in the current directory
88
ai-claude *args:
99
#!/usr/bin/bash
1010
set -euo pipefail
11-
mkdir -p "$HOME/.claude" "$HOME/.config/claude"
11+
mkdir -p "$HOME/.claude"
12+
touch "$HOME/.claude.json"
1213
exec podman run {{ai_podman_flags}} \
1314
-e HOME="$HOME" \
1415
-v "$(pwd):$(pwd):rw" \
1516
-v "$HOME/.claude:$HOME/.claude:rw" \
16-
-v "$HOME/.config/claude:$HOME/.config/claude:rw" \
17+
-v "$HOME/.claude.json:$HOME/.claude.json:rw" \
1718
-w "$(pwd)" \
1819
{{ai_image}} \
1920
claude {{args}}
@@ -40,7 +41,8 @@ ai-gemini *args:
4041
ai-dev:
4142
#!/usr/bin/bash
4243
set -euo pipefail
43-
mkdir -p "$HOME/.claude" "$HOME/.config/claude" "$HOME/.gemini"
44+
mkdir -p "$HOME/.claude" "$HOME/.gemini"
45+
touch "$HOME/.claude.json"
4446
env_flags=""
4547
for var in $(env | grep -E '^(GOOGLE_|GEMINI_|ANTHROPIC_)' | cut -d= -f1); do
4648
env_flags="$env_flags -e $var"
@@ -50,7 +52,7 @@ ai-dev:
5052
$env_flags \
5153
-v "$(pwd):$(pwd):rw" \
5254
-v "$HOME/.claude:$HOME/.claude:rw" \
53-
-v "$HOME/.config/claude:$HOME/.config/claude:rw" \
55+
-v "$HOME/.claude.json:$HOME/.claude.json:rw" \
5456
-v "$HOME/.gemini:$HOME/.gemini:rw" \
5557
-w "$(pwd)" \
5658
{{ai_image}}
@@ -64,45 +66,39 @@ ai-setup:
6466
podman pull {{ai_image}}
6567

6668
mkdir -p "$HOME/.local/bin"
67-
68-
cat > "$HOME/.local/bin/claude" << 'WRAPPER'
69-
#!/usr/bin/bash
70-
set -euo pipefail
71-
mkdir -p "$HOME/.claude" "$HOME/.config/claude"
72-
exec podman run --rm -it \
73-
--user 0:0 \
74-
--security-opt label=disable \
75-
-e HOME="$HOME" \
76-
-v "$(pwd):$(pwd):rw" \
77-
-v "$HOME/.claude:$HOME/.claude:rw" \
78-
-v "$HOME/.config/claude:$HOME/.config/claude:rw" \
79-
-w "$(pwd)" \
80-
ghcr.io/binarypie-dev/ai-dev:latest \
81-
claude "$@"
82-
WRAPPER
69+
printf '%s\n' '#!/usr/bin/bash' \
70+
'set -euo pipefail' \
71+
'mkdir -p "$HOME/.claude"' \
72+
'touch "$HOME/.claude.json"' \
73+
'exec podman run --rm -it --init \' \
74+
' --user 0:0 \' \
75+
' --security-opt label=disable \' \
76+
' -e HOME="$HOME" \' \
77+
' -v "$(pwd):$(pwd):rw" \' \
78+
' -v "$HOME/.claude:$HOME/.claude:rw" \' \
79+
' -v "$HOME/.claude.json:$HOME/.claude.json:rw" \' \
80+
' -w "$(pwd)" \' \
81+
' ghcr.io/binarypie-dev/ai-dev:latest \' \
82+
' claude "$@"' > "$HOME/.local/bin/claude"
8383
chmod +x "$HOME/.local/bin/claude"
84-
85-
cat > "$HOME/.local/bin/gemini" << 'WRAPPER'
86-
#!/usr/bin/bash
87-
set -euo pipefail
88-
mkdir -p "$HOME/.gemini"
89-
env_flags=""
90-
for var in $(env | grep -E '^(GOOGLE_|GEMINI_)' | cut -d= -f1); do
91-
env_flags="$env_flags -e $var"
92-
done
93-
exec podman run --rm -it \
94-
--user 0:0 \
95-
--security-opt label=disable \
96-
-e HOME="$HOME" \
97-
$env_flags \
98-
-v "$(pwd):$(pwd):rw" \
99-
-v "$HOME/.gemini:$HOME/.gemini:rw" \
100-
-w "$(pwd)" \
101-
ghcr.io/binarypie-dev/ai-dev:latest \
102-
gemini "$@"
103-
WRAPPER
84+
printf '%s\n' '#!/usr/bin/bash' \
85+
'set -euo pipefail' \
86+
'mkdir -p "$HOME/.gemini"' \
87+
'env_flags=""' \
88+
'for var in $(env | grep -E '"'"'^(GOOGLE_|GEMINI_)'"'"' | cut -d= -f1); do' \
89+
' env_flags="$env_flags -e $var"' \
90+
'done' \
91+
'exec podman run --rm -it --init \' \
92+
' --user 0:0 \' \
93+
' --security-opt label=disable \' \
94+
' -e HOME="$HOME" \' \
95+
' $env_flags \' \
96+
' -v "$(pwd):$(pwd):rw" \' \
97+
' -v "$HOME/.gemini:$HOME/.gemini:rw" \' \
98+
' -w "$(pwd)" \' \
99+
' ghcr.io/binarypie-dev/ai-dev:latest \' \
100+
' gemini "$@"' > "$HOME/.local/bin/gemini"
104101
chmod +x "$HOME/.local/bin/gemini"
105-
106102
echo ""
107103
echo "Setup complete! You can now run 'claude' and 'gemini' directly."
108104

0 commit comments

Comments
 (0)