feat: add justfile with sandbox management targets - #79
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review infoConfiguration used: defaults Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (3)
📝 WalkthroughWalkthroughAdds a Justfile implementing a Docker-based sandbox workflow, updates KAIZEN_LITE.md with a new sandbox-focused example and learning guidance, and modifies Changes
Sequence Diagram(s)sequenceDiagram
participant Dev as Developer
participant Host as Host (Docker)
participant Sandbox as Sandbox Container
participant Workspace as Workspace (mounted)
Dev->>Host: just sandbox-build (build image)
Host-->>Dev: Docker image created
Dev->>Host: just sandbox-setup (copy sample.env -> myenv)
Host-->>Dev: env file prepared
Dev->>Host: just sandbox-run (docker run --env-file, mount workspace)
Host->>Sandbox: start container with env and mounts
Sandbox->>Workspace: access code and mounts
Dev->>Host: just sandbox-test / sandbox-prompt (execute claude inside container)
Host->>Sandbox: run one-shot command or interactive shell
Sandbox-->>Dev: command output / test results
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
justfile (2)
14-20: Use{{sandbox_dir}}consistently instead of hardcodingsandbox/sample.env.Line 16 hardcodes
sandbox/sample.envwhile the declared variable{{sandbox_dir}}exists for exactly this purpose. Ifsandbox_diris ever changed, the source path incpwill silently drift.♻️ Proposed fix
- cp sandbox/sample.env {{env_file}}; \ + cp {{sandbox_dir}}/sample.env {{env_file}}; \🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@justfile` around lines 14 - 20, The sandbox-setup recipe hardcodes the source file path "sandbox/sample.env"; update it to use the sandbox_dir variable instead so the cp uses {{sandbox_dir}}/sample.env; change the cp invocation in the sandbox-setup target (which references env_file) to build the source path from {{sandbox_dir}} and keep the existing env_file usage for the destination so the copy respects future sandbox_dir changes.
1-8: Move variable declarations above thedefaulttarget.Having variables defined after the recipe they conceptually configure is unconventional and harder to scan.
justresolves all declarations regardless of position, so this is purely a readability nit.♻️ Suggested layout
+image := "claude-sandbox" +env_file := "sandbox/myenv" +sandbox_dir := "sandbox" + # Default: list available targets default: `@just` --list - -image := "claude-sandbox" -env_file := "sandbox/myenv" -sandbox_dir := "sandbox"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@justfile` around lines 1 - 8, Move the variable declarations (image, env_file, sandbox_dir) above the default recipe so configuration appears before the recipe it affects; update the file so the variables are declared at top of the justfile and then the default: recipe (the default target) follows, keeping the same variable names (image, env_file, sandbox_dir) and values unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@justfile`:
- Around line 31-32: The sandbox-clean target currently runs "docker rmi
{{image}}" which fails if stopped containers still reference the image; update
the sandbox-clean target to force-remove the image by adding the force flag
(e.g., change docker rmi {{image}} to use -f/--force) so the command will remove
images even when referenced by stopped containers.
- Around line 23-24: Update the sandbox-run recipe so the docker run command
sets the container working directory to the mounted path: add the flag --workdir
/workspace to the docker run invocation used by sandbox-run so the interactive
shell starts inside the mounted "$(pwd)" directory instead of the image's
default WORKDIR.
- Around line 27-28: The sandbox-test justfile target can block indefinitely if
the Claude API call hangs; wrap the Docker run invocation in a timeout (e.g.,
GNU coreutils timeout) so the target exits after a bounded period (choose a
sensible value like 30–60s) and return a non-zero status on timeout; update the
sandbox-test target that currently runs `docker run --rm --env-file {{env_file}}
{{image}} claude -p "who are you"` to invoke it via timeout so CI won't hang.
---
Nitpick comments:
In `@justfile`:
- Around line 14-20: The sandbox-setup recipe hardcodes the source file path
"sandbox/sample.env"; update it to use the sandbox_dir variable instead so the
cp uses {{sandbox_dir}}/sample.env; change the cp invocation in the
sandbox-setup target (which references env_file) to build the source path from
{{sandbox_dir}} and keep the existing env_file usage for the destination so the
copy respects future sandbox_dir changes.
- Around line 1-8: Move the variable declarations (image, env_file, sandbox_dir)
above the default recipe so configuration appears before the recipe it affects;
update the file so the variables are declared at top of the justfile and then
the default: recipe (the default target) follows, keeping the same variable
names (image, env_file, sandbox_dir) and values unchanged.
| sandbox-run: | ||
| docker run --rm -it --env-file {{env_file}} -v "$(pwd)":/workspace {{image}} |
There was a problem hiding this comment.
Add --workdir /workspace so the interactive shell lands in the mounted directory.
Without it the container starts at the Dockerfile's WORKDIR, forcing the user to cd /workspace manually every session.
🐛 Proposed fix
- docker run --rm -it --env-file {{env_file}} -v "$(pwd)":/workspace {{image}}
+ docker run --rm -it --env-file {{env_file}} -v "$(pwd)":/workspace --workdir /workspace {{image}}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| sandbox-run: | |
| docker run --rm -it --env-file {{env_file}} -v "$(pwd)":/workspace {{image}} | |
| sandbox-run: | |
| docker run --rm -it --env-file {{env_file}} -v "$(pwd)":/workspace --workdir /workspace {{image}} |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@justfile` around lines 23 - 24, Update the sandbox-run recipe so the docker
run command sets the container working directory to the mounted path: add the
flag --workdir /workspace to the docker run invocation used by sandbox-run so
the interactive shell starts inside the mounted "$(pwd)" directory instead of
the image's default WORKDIR.
| sandbox-test: | ||
| docker run --rm --env-file {{env_file}} {{image}} claude -p "who are you" |
There was a problem hiding this comment.
Add a timeout to the smoke-test to prevent indefinite blocking.
If the Claude API call hangs (network issue, bad key, etc.) this target blocks forever, which is especially problematic in CI. Using timeout (GNU coreutils) keeps the test bounded.
🐛 Proposed fix
- docker run --rm --env-file {{env_file}} {{image}} claude -p "who are you"
+ docker run --rm --env-file {{env_file}} {{image}} timeout 30 claude -p "who are you"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| sandbox-test: | |
| docker run --rm --env-file {{env_file}} {{image}} claude -p "who are you" | |
| sandbox-test: | |
| docker run --rm --env-file {{env_file}} {{image}} timeout 30 claude -p "who are you" |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@justfile` around lines 27 - 28, The sandbox-test justfile target can block
indefinitely if the Claude API call hangs; wrap the Docker run invocation in a
timeout (e.g., GNU coreutils timeout) so the target exits after a bounded period
(choose a sensible value like 30–60s) and return a non-zero status on timeout;
update the sandbox-test target that currently runs `docker run --rm --env-file
{{env_file}} {{image}} claude -p "who are you"` to invoke it via timeout so CI
won't hang.
| sandbox-clean: | ||
| docker rmi {{image}} |
There was a problem hiding this comment.
docker rmi fails when stopped containers still reference the image.
After a sandbox-run session the stopped container keeps a reference to the image; a subsequent sandbox-clean errors out with "image is being used by stopped container". Adding -f (or --force) handles this gracefully for a local dev workflow.
🐛 Proposed fix
- docker rmi {{image}}
+ docker rmi -f {{image}}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@justfile` around lines 31 - 32, The sandbox-clean target currently runs
"docker rmi {{image}}" which fails if stopped containers still reference the
image; update the sandbox-clean target to force-remove the image by adding the
force flag (e.g., change docker rmi {{image}} to use -f/--force) so the command
will remove images even when referenced by stopped containers.
Add justfile targets for running prompts in the Docker sandbox with optional trace and learn flags. Document a second Kaizen Lite example showing how the agent learns to avoid dead ends (exiftool, Pillow) and go straight to Python stdlib for EXIF parsing in sandboxed environments.
Adds a justfile at the repo root with five targets to simplify common Docker sandbox operations: sandbox-build, sandbox-setup, sandbox-run, sandbox-test, and sandbox-clean.
Summary by CodeRabbit
New Features
Documentation
Chores