Add OpenCode sandbox workflows#3
Conversation
|
here is calc.py def normalize_user_label(label):
value = label.strip()
value = value.lower()
value = value.replace(" ", "-")
return value
return value
def format_status(name, enabled):
if enabled:
status = "enabled"
else:
status = "disabled"
return f"{normalize_user_label(name)}:{status}" |
|
|
||
| Use the mounted sandbox commands for repeatable workflows when they fit the task: | ||
|
|
||
| - `/refactor-audit <target>`: inspect a target for refactor opportunities without editing files. |
There was a problem hiding this comment.
What is a target? Does the LLM know that? Im confused
| # A hardened Docker sandbox setup for opencode | ||
|
|
||
| With OpenCode + vLLM (Gemma 4 26B MoE) configs | ||
| With OpenCode + vLLM local model configs |
There was a problem hiding this comment.
name the model (qwen3.6-35b) is more descriptive for people cloning the repo, then hiding it inside the config inside a nested directory.
There was a problem hiding this comment.
Fixed this for now - may we should have a sperate section for linking all related parts and files where the llm is addressed
| 1. Press `/model` — your model should appear under your provider name with an orange dot | ||
| 2. Type `hello, what model are you?` — the response should mention your model ID | ||
| 3. Check the status bar at the bottom — it should show `Gemma 4 26B MoE · vLLM (Gemma4 local)` | ||
| 3. Check the status bar at the bottom — it should show your configured model, for example `Qwen3.6 35B A3B · vLLM` |
There was a problem hiding this comment.
very nice, the previous part should be named just like that.
| ``` | ||
|
|
||
| All runtimes are installed at **build time** under the `opencode` user, so the container starts instantly with no network downloads at runtime. The tool binaries are on `PATH` and their data directories (`CARGO_HOME`, `RUSTUP_HOME`) are pinned via environment variables so they survive the `HOME` override that redirects opencode's session state to the mounted workspace. | ||
| All runtimes are installed at **build time** under the `opencode` user, so the container starts instantly with no language runtime downloads at startup. Base tooling includes `ripgrep` for OpenCode search tools and `tzdata` for correct Europe/Berlin timestamps. The tool binaries are on `PATH` and their data directories (`CARGO_HOME`, `RUSTUP_HOME`) are pinned via environment variables. |
There was a problem hiding this comment.
Why remove "so they survive the HOME override that redirects opencode's session state to the mounted workspace."?
| "agent": { | ||
| "build": { | ||
| "prompt": "All project are located under /home/opencode/workspace, you will only work there and create a new subdirectory for each task or project, NO EXCEPTIONS. You must maintain a file called WORKLOG.md in the current project working directory at all times.\\n\\nRules:\\n- Before starting any task, check if WORKLOG.md exists and read it to understand prior context.\\n- After completing EACH task, immediately update WORKLOG.md with: what was done (specific files changed, exact lines modified), what was found (exact issues, not vague summaries), and what still needs doing with current date and time in german timezone. Do NOT proceed to the next task until WORKLOG.md has been updated.\\n- If WORKLOG.md does not exist, create it before doing anything else.", | ||
| "prompt": "Follow the sandbox rules from /home/opencode/.config/opencode/AGENTS.md. Before finishing any task that changes files, read WORKLOG.md if present and append a concise entry with the current Europe/Berlin timestamp from `TZ=Europe/Berlin date \"+%d.%m.%Y, %H:%M (%Z)\"`, changed files, concrete findings, and pending follow-ups.", |
There was a problem hiding this comment.
this should be kept
"All project are located under /home/opencode/workspace, you will only work there and create a new subdirectory for each task or project, NO EXCEPTIONS."
|
@coderabbitai full review |
✅ Action performedFull review finished. |
📝 WalkthroughWalkthroughThis PR introduces a complete OpenCode sandbox framework by establishing agent constraints, command specifications, container configuration, and user documentation. It defines how agents should operate within ChangesSandbox Rules, Commands, and Runtime
🎯 3 (Moderate) | ⏱️ ~25 minutes
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
README.md (1)
138-138:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix compose filename in troubleshooting text.
Line 138 references
docker-compose.yml, but this repo usescompose.yml. The current wording can mislead users during config checks.Suggested fix
-If this returns an error, check that `docker compose` is run from the same directory as `docker-compose.yml` and that `./config/opencode.json` exists. +If this returns an error, check that `docker compose` is run from the same directory as `compose.yml` and that `./config/opencode.json` exists.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@README.md` at line 138, Update the troubleshooting sentence that currently mentions `docker-compose.yml` to reference the correct compose filename `compose.yml`; locate the exact line string "check that `docker compose` is run from the same directory as `docker-compose.yml` and that `./config/opencode.json` exists" and replace `docker-compose.yml` with `compose.yml` so the guidance matches this repository's actual file.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.opencode/commands/git-commit.md:
- Around line 18-21: The WORKLOG.md step requires a commit hash that doesn't
exist yet (see step "8. Append a concise entry to `WORKLOG.md`" and the template
expecting a hash), so reorder the steps so the commit is created before
appending the WORKLOG entry (i.e., perform steps 10–11 to make the commit and
capture the hash, then append the WORKLOG.md entry including that hash, then
stage/commit the WORKLOG if necessary), or alternatively change the WORKLOG
template to omit the commit hash pre-commit; update the sequence around
`WORKLOG.md`, the conventional commit instruction example, and the post-commit
status display to reflect the new ordering.
In `@entrypoint.sh`:
- Around line 54-58: OPENCODE_WORKSPACE is only assigned and not exported so the
launched process (exec gosu $APP_USER:$APP_GROUP opencode) won't receive it;
export OPENCODE_WORKSPACE="/home/opencode/workspace" (before exporting HOME and
before the exec line) so the environment variable is available to the opencode
process and any downstream commands that depend on it.
---
Outside diff comments:
In `@README.md`:
- Line 138: Update the troubleshooting sentence that currently mentions
`docker-compose.yml` to reference the correct compose filename `compose.yml`;
locate the exact line string "check that `docker compose` is run from the same
directory as `docker-compose.yml` and that `./config/opencode.json` exists" and
replace `docker-compose.yml` with `compose.yml` so the guidance matches this
repository's actual file.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: eed6b390-7754-4305-b521-e1b660930756
📒 Files selected for processing (12)
.opencode/commands/git-commit.md.opencode/commands/refactor-apply.md.opencode/commands/refactor-audit.md.opencode/skills/write-worklog/SKILL.mdDockerfileREADME.mdcompose.ymlconfig/AGENTS.mdconfig/opencode-with-vllm-side.jsonconfig/opencode.jsonentrypoint.shscripts/reset-sandbox.sh
| 8. Append a concise entry to `WORKLOG.md` before committing. | ||
| 9. Stage only approved files. | ||
| 10. Use a concise Conventional Commit message, for example `feat: add sandbox commands` or `fix: preserve opencode home path`. | ||
| 11. After committing, show the commit hash and final `git status --short`. |
There was a problem hiding this comment.
Fix impossible ordering for commit hash in WORKLOG entry.
The workflow requires writing WORKLOG.md before commit, but the template requires a commit hash that only exists after commit. Reorder steps (commit first, then append worklog) or remove hash from the pre-commit entry shape.
Suggested minimal correction
-8. Append a concise entry to `WORKLOG.md` before committing.
-9. Stage only approved files.
-10. Use a concise Conventional Commit message, for example `feat: add sandbox commands` or `fix: preserve opencode home path`.
-11. After committing, show the commit hash and final `git status --short`.
+8. Stage only approved files.
+9. Use a concise Conventional Commit message, for example `feat: add sandbox commands` or `fix: preserve opencode home path`.
+10. Commit the changes.
+11. Append a concise entry to `WORKLOG.md` including the commit hash/subject.
+12. Show the commit hash and final `git status --short`.Also applies to: 45-47
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.opencode/commands/git-commit.md around lines 18 - 21, The WORKLOG.md step
requires a commit hash that doesn't exist yet (see step "8. Append a concise
entry to `WORKLOG.md`" and the template expecting a hash), so reorder the steps
so the commit is created before appending the WORKLOG entry (i.e., perform steps
10–11 to make the commit and capture the hash, then append the WORKLOG.md entry
including that hash, then stage/commit the WORKLOG if necessary), or
alternatively change the WORKLOG template to omit the commit hash pre-commit;
update the sequence around `WORKLOG.md`, the conventional commit instruction
example, and the post-commit status display to reflect the new ordering.
| OPENCODE_WORKSPACE="/home/opencode/workspace" | ||
| echo "> Set HOME to $OPENCODE_WORKSPACE (mounted workspace volume)" | ||
| export HOME="$OPENCODE_WORKSPACE" | ||
|
|
||
| exec gosu $APP_USER:$APP_GROUP "opencode" | ||
| exec gosu $APP_USER:$APP_GROUP opencode |
There was a problem hiding this comment.
Export OPENCODE_WORKSPACE before launching OpenCode.
OPENCODE_WORKSPACE is assigned but not exported, so opencode won’t see it in its environment. That breaks the stated runtime contract for downstream command/skill behavior relying on this variable.
Suggested fix
OPENCODE_WORKSPACE="/home/opencode/workspace"
echo "> Set HOME to $OPENCODE_WORKSPACE (mounted workspace volume)"
+export OPENCODE_WORKSPACE
export HOME="$OPENCODE_WORKSPACE"
exec gosu $APP_USER:$APP_GROUP opencodeBased on learnings: “All projects must be located under /home/opencode/workspace with no exceptions…”
📝 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.
| OPENCODE_WORKSPACE="/home/opencode/workspace" | |
| echo "> Set HOME to $OPENCODE_WORKSPACE (mounted workspace volume)" | |
| export HOME="$OPENCODE_WORKSPACE" | |
| exec gosu $APP_USER:$APP_GROUP "opencode" | |
| exec gosu $APP_USER:$APP_GROUP opencode | |
| OPENCODE_WORKSPACE="/home/opencode/workspace" | |
| echo "> Set HOME to $OPENCODE_WORKSPACE (mounted workspace volume)" | |
| export OPENCODE_WORKSPACE | |
| export HOME="$OPENCODE_WORKSPACE" | |
| exec gosu $APP_USER:$APP_GROUP opencode |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@entrypoint.sh` around lines 54 - 58, OPENCODE_WORKSPACE is only assigned and
not exported so the launched process (exec gosu $APP_USER:$APP_GROUP opencode)
won't receive it; export OPENCODE_WORKSPACE="/home/opencode/workspace" (before
exporting HOME and before the exec line) so the environment variable is
available to the opencode process and any downstream commands that depend on it.
Source: Learnings
There was a problem hiding this comment.
@coderabbitai can you please look at the feat/add-omp branch inside the entrypoint.sh and evaluate if that solution is better and more secure?
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Fetch entrypoint.sh from the feat/add-omp branch
gh api repos/jammsen/docker-opencode-sandbox/contents/entrypoint.sh?ref=feat/add-omp \
--jq '.content' | base64 -dLength of output: 3213
@jammsen, here's the comparison between feat/add-omp and the current PR branch for entrypoint.sh:
✅ What's better in feat/add-omp
| Area | Current PR (feat/cleanup-hook) |
feat/add-omp |
|---|---|---|
gosu argument quoting |
gosu $APP_USER:$APP_GROUP opencode (unquoted) |
gosu "$APP_USER":"$APP_GROUP" "$TOOL" (properly quoted) |
| Tool argument quoting | opencode (hardcoded, unquoted) |
"$TOOL" (variable, quoted) |
Conditional HOME export |
Always sets HOME to workspace |
Only sets HOME to workspace for opencode; omp keeps its real HOME — architecturally cleaner |
⚠️ Same issue remains in feat/add-omp
OPENCODE_WORKSPACE is still assigned but not exported — opencode (or omp) won't see it as an environment variable. The fix is the same as my original suggestion:
OPENCODE_WORKSPACE="/home/opencode/workspace"
+export OPENCODE_WORKSPACE🔴 New concern introduced in feat/add-omp
The interactive prompt has no timeout:
read -r -p "Enter selection [1]: " SELECTIONIn headless/non-TTY Docker environments (e.g., docker run -d, CI pipelines, restart policies), this will hang indefinitely waiting for input. A timeout with a sensible default would make it safe:
read -r -t 10 -p "Enter selection [1]: " SELECTION || SELECTION="1"Summary
feat/add-omp is better in quoting and the conditional HOME logic, but it shares the OPENCODE_WORKSPACE export gap and introduces a new hang risk with the unguarded read. If you plan to merge feat/add-omp eventually, both issues should be addressed there too.
There was a problem hiding this comment.
Regarding - "OPENCODE_WORKSPACE is still assigned but not exported" - So what you are saying is we try to set a variable when its not existent or empty? Isnt this still in bash scope and not in shell scope? Can you give a full example of this, rundown workflow and a flow-diagram for this please?
Regarding - "In headless/non-TTY Docker environments (e.g., docker run -d, CI pipelines, restart policies), this will hang indefinitely waiting for input." - Yes thats right, please consult the README.md this repo is a "build it yourself locally with docker-compose sandbox, the sets for setup are litteraly git clone and run script. The script contains docker compose build and up. Thats by design: The cotainer has to wait for the interactive input in which agentic-coding tool to start, or if they dont, the containier cant start fully. Its what this "sandbox" is about, very hardenend Docker Environment out of the box, with a select picker that "shall not break!", Gandalf would say, to let the user work in it.
Thanks for the review!
There was a problem hiding this comment.
@jammsen, great questions — let me break both down.
1. Bash scope vs. exported environment variables
You're right that OPENCODE_WORKSPACE is accessible within the bash script itself. But the issue is about what child processes can see, not the bash script.
Here's the distinction:
| Syntax | Bash-local (current shell) | Child process environment |
|---|---|---|
VAR=value |
✅ Visible | ❌ Not inherited |
export VAR=value |
✅ Visible | ✅ Inherited |
When exec gosu $APP_USER:$APP_GROUP opencode runs, it replaces the current process with a new opencode process running as a different user. That new process starts with a fresh environment composed only of exported variables — bare bash-local assignments never make it across the exec boundary.
Concrete example
#!/usr/bin/env bash
NOT_EXPORTED="hello"
export EXPORTED="world"
bash -c 'echo "NOT_EXPORTED=$NOT_EXPORTED"' # prints: NOT_EXPORTED=
bash -c 'echo "EXPORTED=$EXPORTED"' # prints: EXPORTED=worldFlow diagram
flowchart TD
A["entrypoint.sh\n(bash, PID 1, root)"] --> B["OPENCODE_WORKSPACE=...\nbash-local only ❌"]
A --> C["export HOME=...\nenvironment variable ✅"]
B & C --> D["exec gosu opencode:opencode opencode\nreplaces current process"]
D --> E["opencode process\nnew PID, non-root user"]
E --> F{"ENV: OPENCODE_WORKSPACE?"}
E --> G{"ENV: HOME?"}
F -->|"not exported → absent"| H["❌ opencode cannot see\nOPENCODE_WORKSPACE"]
G -->|"was exported → present"| I["✅ opencode sees\nHOME=/home/opencode/workspace"]
So the fix is simply:
OPENCODE_WORKSPACE="/home/opencode/workspace"
+export OPENCODE_WORKSPACE
echo "> Set HOME to $OPENCODE_WORKSPACE (mounted workspace volume)"
export HOME="$OPENCODE_WORKSPACE"This ensures opencode — and any downstream commands/skills relying on $OPENCODE_WORKSPACE — can actually read it from their environment.
2. Interactive TTY / headless concern — acknowledged ✅
You're absolutely right — I missed the sandbox-first design intent. This is a local, interactive, git-clone-and-run setup where the user must be present at the terminal. The interactive read waiting for tool selection is intentional and correct by design. I withdraw that concern entirely.
Thanks for the thorough explanation! 🐇 🤔
✏️ Learnings added
Learnt from: jammsen
Repo: jammsen/docker-opencode-sandbox PR: 3
File: entrypoint.sh:54-58
Timestamp: 2026-06-06T13:58:50.595Z
Learning: In jammsen/docker-opencode-sandbox, the `feat/add-omp` branch introduces an interactive `read` prompt in `entrypoint.sh` (no timeout) for the user to select which agentic coding tool to launch (e.g., opencode or omp). This is intentional by design: the repo is a local sandbox (`docker-compose build && up`) that requires interactive terminal input at startup. The container is not intended for headless/CI/non-TTY use. Flagging the missing `read -t` timeout as an issue is incorrect for this repo.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
gh api repos/jammsen/docker-opencode-sandbox/contents/entrypoint.sh?ref=feat/add-omp \
--jq '.content' | base64 -dLength of output: 3896
@jammsen, the duplicate case block is gone — great fix! Here's the full re-review:
✅ Complete security checklist — current feat/add-omp
| # | Finding | Status |
|---|---|---|
| 1 | set -euo pipefail |
✅ |
| 2 | umask 0027 |
✅ |
| 3 | readonly APP_USER APP_GROUP APP_HOME |
✅ |
| 4 | Numeric PUID/PGID regex validation (^[1-9][0-9]*$) |
✅ |
| 5 | readonly OPENCODE_WORKSPACE |
✅ |
| 6 | export OPENCODE_WORKSPACE |
✅ |
| 7 | Workspace dir existence check before launch | ✅ |
| 8 | Full path + quoted gosu (/usr/local/sbin/gosu "$APP_USER":"$APP_GROUP" "$TOOL") |
✅ |
| 9 | Single tightened case with explicit 1|"", 2, and * warning |
✅ |
🟡 One minor dead-code observation (low priority)
The zero-check block (lines 28–32) is now unreachable:
# This block can never be reached anymore:
if [[ "${PUID}" -eq 0 ]] || [[ "${PGID}" -eq 0 ]]; then
...
fiThe regex ^[1-9][0-9]*$ already guarantees PUID/PGID are positive integers — 0 fails the regex and exits before reaching this check. It's harmless dead code, but could be removed for clarity:
-if [[ "${PUID}" -eq 0 ]] || [[ "${PGID}" -eq 0 ]]; then
- echo ">>> [Config] PUID=${PUID} PGID=${PGID} — Running the application user as root is not supported."
- echo " This container is designed to drop privileges after setup. Please set non-zero values for PUID and PGID."
- exit 1
-fiThat's the only remaining cleanup item. Everything else is solid. 🐇 🔐
🧠 Learnings used
Learnt from: jammsen
Repo: jammsen/docker-opencode-sandbox PR: 3
File: entrypoint.sh:54-58
Timestamp: 2026-06-06T13:58:50.595Z
Learning: In jammsen/docker-opencode-sandbox, the `feat/add-omp` branch introduces an interactive `read` prompt in `entrypoint.sh` (no timeout) for the user to select which agentic coding tool to launch (e.g., opencode or omp). This is intentional by design: the repo is a local sandbox (`docker-compose build && up`) that requires interactive terminal input at startup. The container is not intended for headless/CI/non-TTY use. Flagging the missing `read -t` timeout as an issue is incorrect for this repo.
There was a problem hiding this comment.
Oh yeah good catch, i get it its basically what we have already but better, therefor its not needed anymore. What wondering already a bit but left it in, because your code reference placed it about this block hahaha
There was a problem hiding this comment.
removed the unreachble statement, please re-evaluate
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
gh api repos/jammsen/docker-opencode-sandbox/contents/entrypoint.sh?ref=feat/add-omp \
--jq '.content' | base64 -dLength of output: 3801
@jammsen, confirmed — the dead-code block is cleanly removed. Here's the final complete checklist:
✅ Final security checklist — feat/add-omp
| # | Finding | Status |
|---|---|---|
| 1 | set -euo pipefail |
✅ |
| 2 | umask 0027 |
✅ |
| 3 | readonly APP_USER APP_GROUP APP_HOME |
✅ |
| 4 | Numeric PUID/PGID regex validation (^[1-9][0-9]*$) |
✅ |
| 5 | Unreachable zero-check block removed | ✅ |
| 6 | readonly OPENCODE_WORKSPACE |
✅ |
| 7 | export OPENCODE_WORKSPACE |
✅ |
| 8 | Workspace dir existence check before launch | ✅ |
| 9 | Full path + quoted gosu | ✅ |
| 10 | Single tightened case with 1|"", 2, explicit * warning |
✅ |
🟡 One final low-priority observation — set -u + unguarded env vars
Now that set -u is active, any variable not exported into the container environment will cause the script to abort with a cryptic unbound variable error before your nice error message fires. The three affected vars are PUID, PGID, and ENABLE_OMP:
-if ! [[ "${PUID}" =~ ^[1-9][0-9]*$ ]] || ! [[ "${PGID}" =~ ^[1-9][0-9]*$ ]]; then
+if ! [[ "${PUID:-}" =~ ^[1-9][0-9]*$ ]] || ! [[ "${PGID:-}" =~ ^[1-9][0-9]*$ ]]; then
-if [[ "$ENABLE_OMP" = "true" ]] && ...
+if [[ "${ENABLE_OMP:-}" = "true" ]] && ...The :- provides an empty-string default when the variable is unset — the regex and string checks then fail gracefully with your own error messages rather than bash's generic one. If your Dockerfile/compose always sets these via ENV/environment:, you'll never hit this in practice, but it's good defensive hygiene.
Other than that — the script is solid. Great iterative work! 🐇 🔐
🧠 Learnings used
Learnt from: jammsen
Repo: jammsen/docker-opencode-sandbox PR: 3
File: entrypoint.sh:54-58
Timestamp: 2026-06-06T13:58:50.595Z
Learning: In jammsen/docker-opencode-sandbox, the `feat/add-omp` branch introduces an interactive `read` prompt in `entrypoint.sh` (no timeout) for the user to select which agentic coding tool to launch (e.g., opencode or omp). This is intentional by design: the repo is a local sandbox (`docker-compose build && up`) that requires interactive terminal input at startup. The container is not intended for headless/CI/non-TTY use. Flagging the missing `read -t` timeout as an issue is incorrect for this repo.
| "agent": { | ||
| "build": { | ||
| "prompt": "You must maintain a file called WORKLOG.md in the current project working directory at all times.\\n\\nRules:\\n- Before starting any task, check if WORKLOG.md exists and read it to understand prior context.\\n- After completing EACH task, immediately update WORKLOG.md with: what was done (specific files changed, exact lines modified), what was found (exact issues, not vague summaries), and what still needs doing with current date and time in german timezone. Do NOT proceed to the next task until WORKLOG.md has been updated.\\n- If WORKLOG.md does not exist, create it before doing anything else.", | ||
| "prompt": "All projects are located under /home/opencode/workspace. Work only there, with no exceptions, unless the user explicitly asks for access outside the sandbox. Follow the sandbox rules from /home/opencode/.config/opencode/AGENTS.md. Before finishing any task that changes files, read WORKLOG.md in the active project directory if present and append a concise entry with the current Europe/Berlin timestamp from `TZ=Europe/Berlin date \"+%d.%m.%Y, %H:%M (%Z)\"`, changed files, concrete findings, and pending follow-ups.", |
|
|
||
| while [[ $# -gt 0 ]]; do | ||
| case "$1" in | ||
| -y|--yes) |
There was a problem hiding this comment.
--destroy
would remove -y and --yes, its clear that reset destroy stuff, i think --destroy as a quick setting is more "authoritative" for what is going to happen.
| $ROOT_DIR/workspace/.gitkeep | ||
| $ROOT_DIR/data/.gitkeep | ||
|
|
||
| This cannot be undone. |
There was a problem hiding this comment.
As this is a destructive operation, this cannot be undone!
What changed
This adds a more reliable OpenCode sandbox workflow setup for local vLLM-backed usage:
config/AGENTS.md./refactor-audit <target>for read-only refactor analysis./refactor-apply <approved scope>for focused refactors with verification andWORKLOG.mdupdates./git-commitfor reviewed Conventional Commit workflows.write-worklogskill so it is an on-demand formatting helper rather than a second global rule source.HOME=/home/opencodeand changed the entrypoint to start OpenCode from/home/opencode/workspacewithout moving the home directory.ripgrepandtzdatato the image so OpenCode search tooling and Europe/Berlin timestamps work without runtime downloads or UTC fallback.Why
The previous setup mixed persistent rules, skills, and command behavior in ways that were harder for local models to follow reliably. In testing, broad
AGENTS.mdinstructions were useful for orientation, but repeatable workflow requirements were followed more consistently when embedded directly in slash commands.This keeps the layers clearer:
AGENTS.mdprovides short global sandbox orientation.Validation
Configuration and syntax checks:
Container/runtime checks performed:
docker compose build docker compose run --rm opencode --version docker compose run --rm --entrypoint bash opencode -lc 'rg --version | head -n 1; TZ=Europe/Berlin date "+%d.%m.%Y, %H:%M (%Z)"'Observed results:
1.15.10.ripgrep 15.1.0was available in the container.CEST.Workflow smoke test performed in a temporary workspace project:
docker compose run --rm opencode run \ --dir /home/opencode/workspace/opencode-agent-follow-test \ --command refactor-apply \ "In calc.py, extract the duplicated label normalization steps from normalize_user_label and normalize_project_label into a private helper named _normalize_label. Keep behavior unchanged. Do not touch any other code." \ --format defaultObserved result:
calc.pywas refactored as requested.WORKLOG.mdwas updated with the changed file, findings, CEST timestamp, and pending state.A normal non-command OpenCode run was also tested with a small file edit and updated
WORKLOG.mdas expected.Notes
/refactor-auditwas recognized as theplanagent and remained read-only, but the local model stalled during one audit smoke test. The command wiring was correct; the stall appears related to local model/tool-loop behavior rather than configuration.Summary by CodeRabbit
Documentation
New Features
reset-sandboxutility script for resetting sandbox state.Chores