|
1 | 1 | # AI Development Environment (Sandboxed Podman Container) |
2 | | -# Uses entrypoint-based UID/GID mapping for correct permissions |
| 2 | +# Uses scripts/ for shared logic between local dev and system install |
3 | 3 |
|
4 | 4 | local_image := "localhost/ai-dev" |
5 | 5 | remote_image := "ghcr.io/binarypie-dev/ai-dev:latest" |
6 | 6 |
|
7 | | -# Common podman run flags (UID 0 inside = host user in rootless podman) |
8 | | -podman_flags := "--rm -it --init --user 0:0 --security-opt label=disable" |
9 | | - |
10 | 7 | # Default recipe - show help |
11 | 8 | default: |
12 | 9 | @just --list |
@@ -37,145 +34,44 @@ push: |
37 | 34 | podman push {{remote_image}} |
38 | 35 |
|
39 | 36 | # ============================================================================= |
40 | | -# Usage |
| 37 | +# Usage (local image) |
41 | 38 | # ============================================================================= |
42 | 39 |
|
43 | 40 | # Run Claude Code in the current directory |
44 | 41 | claude *args: |
45 | | - #!/usr/bin/bash |
46 | | - set -euo pipefail |
47 | | - mkdir -p "$HOME/.claude" |
48 | | - touch "$HOME/.claude.json" |
49 | | - exec podman run {{podman_flags}} \ |
50 | | - -e HOME="$HOME" \ |
51 | | - -v "$(pwd):$(pwd):rw" \ |
52 | | - -v "$HOME/.claude:$HOME/.claude:rw" \ |
53 | | - -v "$HOME/.claude.json:$HOME/.claude.json:rw" \ |
54 | | - -w "$(pwd)" \ |
55 | | - {{local_image}} \ |
56 | | - claude {{args}} |
| 42 | + AI_DEV_IMAGE={{local_image}} ./scripts/claude.sh {{args}} |
57 | 43 |
|
58 | 44 | # Run Gemini CLI in the current directory |
59 | 45 | gemini *args: |
60 | | - #!/usr/bin/bash |
61 | | - set -euo pipefail |
62 | | - mkdir -p "$HOME/.gemini" |
63 | | - env_flags="" |
64 | | - for var in $(env | grep -E '^(GOOGLE_|GEMINI_)' | cut -d= -f1); do |
65 | | - env_flags="$env_flags -e $var" |
66 | | - done |
67 | | - exec podman run {{podman_flags}} \ |
68 | | - -e HOME="$HOME" \ |
69 | | - $env_flags \ |
70 | | - -v "$(pwd):$(pwd):rw" \ |
71 | | - -v "$HOME/.gemini:$HOME/.gemini:rw" \ |
72 | | - -w "$(pwd)" \ |
73 | | - {{local_image}} \ |
74 | | - gemini {{args}} |
| 46 | + AI_DEV_IMAGE={{local_image}} ./scripts/gemini.sh {{args}} |
75 | 47 |
|
76 | 48 | # Enter the container interactively |
77 | 49 | enter: |
78 | | - #!/usr/bin/bash |
79 | | - set -euo pipefail |
80 | | - mkdir -p "$HOME/.claude" "$HOME/.gemini" |
81 | | - touch "$HOME/.claude.json" |
82 | | - env_flags="" |
83 | | - for var in $(env | grep -E '^(GOOGLE_|GEMINI_|ANTHROPIC_)' | cut -d= -f1); do |
84 | | - env_flags="$env_flags -e $var" |
85 | | - done |
86 | | - exec podman run {{podman_flags}} \ |
87 | | - -e HOME="$HOME" \ |
88 | | - $env_flags \ |
89 | | - -v "$(pwd):$(pwd):rw" \ |
90 | | - -v "$HOME/.claude:$HOME/.claude:rw" \ |
91 | | - -v "$HOME/.claude.json:$HOME/.claude.json:rw" \ |
92 | | - -v "$HOME/.gemini:$HOME/.gemini:rw" \ |
93 | | - -w "$(pwd)" \ |
94 | | - {{local_image}} |
| 50 | + AI_DEV_IMAGE={{local_image}} ./scripts/enter.sh |
95 | 51 |
|
96 | 52 | # ============================================================================= |
97 | 53 | # Installation (wrapper scripts to ~/.local/bin) |
98 | 54 | # ============================================================================= |
99 | 55 |
|
100 | | -# Install wrapper scripts for claude and gemini to ~/.local/bin |
| 56 | +# Install wrapper scripts using remote image |
101 | 57 | install: |
102 | 58 | #!/usr/bin/bash |
103 | 59 | set -euo pipefail |
104 | 60 | mkdir -p "$HOME/.local/bin" |
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" |
119 | | - chmod +x "$HOME/.local/bin/claude" |
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" |
137 | | - chmod +x "$HOME/.local/bin/gemini" |
138 | | - echo "Installed wrapper scripts to ~/.local/bin/claude and ~/.local/bin/gemini" |
139 | | - |
140 | | -# Install wrapper scripts pointing to local image |
| 61 | + cp scripts/claude.sh "$HOME/.local/bin/claude" |
| 62 | + cp scripts/gemini.sh "$HOME/.local/bin/gemini" |
| 63 | + chmod +x "$HOME/.local/bin/claude" "$HOME/.local/bin/gemini" |
| 64 | + echo "Installed ~/.local/bin/claude and ~/.local/bin/gemini (image: {{remote_image}})" |
| 65 | + |
| 66 | +# Install wrapper scripts using local image |
141 | 67 | install-local: |
142 | 68 | #!/usr/bin/bash |
143 | 69 | set -euo pipefail |
144 | 70 | mkdir -p "$HOME/.local/bin" |
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" |
159 | | - chmod +x "$HOME/.local/bin/claude" |
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" |
177 | | - chmod +x "$HOME/.local/bin/gemini" |
178 | | - echo "Installed wrapper scripts (local image) to ~/.local/bin/claude and ~/.local/bin/gemini" |
| 71 | + sed 's|ghcr.io/binarypie-dev/ai-dev:latest|localhost/ai-dev|' scripts/claude.sh > "$HOME/.local/bin/claude" |
| 72 | + sed 's|ghcr.io/binarypie-dev/ai-dev:latest|localhost/ai-dev|' scripts/gemini.sh > "$HOME/.local/bin/gemini" |
| 73 | + chmod +x "$HOME/.local/bin/claude" "$HOME/.local/bin/gemini" |
| 74 | + echo "Installed ~/.local/bin/claude and ~/.local/bin/gemini (image: {{local_image}})" |
179 | 75 |
|
180 | 76 | # Remove wrapper scripts from ~/.local/bin |
181 | 77 | uninstall: |
@@ -207,28 +103,11 @@ clean: |
207 | 103 | # Test the built image works correctly |
208 | 104 | test-build: build |
209 | 105 | @echo "Testing container..." |
210 | | - podman run {{podman_flags}} -e HOME="$HOME" {{local_image}} claude --version |
211 | | - podman run {{podman_flags}} -e HOME="$HOME" {{local_image}} gemini --version |
| 106 | + AI_DEV_IMAGE={{local_image}} ./scripts/claude.sh --version |
| 107 | + AI_DEV_IMAGE={{local_image}} ./scripts/gemini.sh --version |
212 | 108 | @echo "" |
213 | 109 | @echo "All tests passed!" |
214 | 110 |
|
215 | 111 | # Debug: show container environment, paths, and auth state |
216 | 112 | debug: |
217 | | - #!/usr/bin/bash |
218 | | - set -euo pipefail |
219 | | - mkdir -p "$HOME/.claude" "$HOME/.gemini" |
220 | | - touch "$HOME/.claude.json" |
221 | | - env_flags="" |
222 | | - for var in $(env | grep -E '^(GOOGLE_|GEMINI_|ANTHROPIC_)' | cut -d= -f1); do |
223 | | - env_flags="$env_flags -e $var" |
224 | | - done |
225 | | - podman run {{podman_flags}} \ |
226 | | - -e HOME="$HOME" \ |
227 | | - $env_flags \ |
228 | | - -v "$(pwd):$(pwd):rw" \ |
229 | | - -v "$HOME/.claude:$HOME/.claude:rw" \ |
230 | | - -v "$HOME/.claude.json:$HOME/.claude.json:rw" \ |
231 | | - -v "$HOME/.gemini:$HOME/.gemini:rw" \ |
232 | | - -w "$(pwd)" \ |
233 | | - {{local_image}} \ |
234 | | - --ai-dev-debug |
| 113 | + AI_DEV_IMAGE={{local_image}} ./scripts/enter.sh --ai-dev-debug |
0 commit comments