From d6f0a79a8ac0aa1cec0ad18032aeaf7ec08fac85 Mon Sep 17 00:00:00 2001 From: Wyller Gomes Date: Tue, 7 Apr 2026 15:43:25 +0000 Subject: [PATCH 1/4] fix(opencode): create parent directories and fix ownership properly - Create opencode directories during build with correct ownership - Update fix-permissions script to also fix parent directories - Skip directories that cannot be changed (use sudo with fallback) - Only change ownership if needed (avoid unnecessary operations) --- src/opencode/install.sh | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/opencode/install.sh b/src/opencode/install.sh index 283e2c0..55105cb 100644 --- a/src/opencode/install.sh +++ b/src/opencode/install.sh @@ -114,17 +114,41 @@ su "$USERNAME" -c "curl -fsSL https://opencode.ai/install | bash -s -- --no-modi ln -s "${USER_HOME}/.opencode/bin/opencode" /usr/local/bin/opencode +log "Criando diretórios para volumes persistentes..." + +mkdir -p "${USER_HOME}/.config/opencode" +mkdir -p "${USER_HOME}/.local/share/opencode" +mkdir -p "${USER_HOME}/.local/state/opencode" + +chown -R "${USERNAME}:${USERNAME}" \ + "${USER_HOME}/.config/opencode" \ + "${USER_HOME}/.local/share/opencode" \ + "${USER_HOME}/.local/state/opencode" + cat > /usr/local/bin/opencode-fix-permissions </dev/null)" != "${USERNAME}" ]; then + sudo chown ${USERNAME}:${USERNAME} "\$path" 2>/dev/null || true + fi +done + for path in \ "${USER_HOME}/.config/opencode" \ "${USER_HOME}/.local/share/opencode" \ "${USER_HOME}/.local/state/opencode" do if [ -e "\$path" ]; then - sudo chown -R ${USERNAME}:${USERNAME} "\$path" + sudo chown -R ${USERNAME}:${USERNAME} "\$path" 2>/dev/null || true fi done EOF From f323e55aca267a1470d9ee8a58309c312c7baab4 Mon Sep 17 00:00:00 2001 From: Wyller Gomes Date: Tue, 7 Apr 2026 16:22:16 +0000 Subject: [PATCH 2/4] fix(opencode): update feature reference to use specific image version --- src/opencode/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opencode/README.md b/src/opencode/README.md index aa04e71..9785691 100644 --- a/src/opencode/README.md +++ b/src/opencode/README.md @@ -33,7 +33,7 @@ The feature can be added without additional configuration. To customize the user { "image": "mcr.microsoft.com/devcontainers/base:trixie", "features": { - "./features/opencode": {} + "ghcr.io/wcgomes/devcontainer-features/opencode:0": {} }, "mounts": [ { From 138d17c2da95d37745791f3762b063833b4dc360 Mon Sep 17 00:00:00 2001 From: Wyller Gomes Date: Tue, 7 Apr 2026 16:25:58 +0000 Subject: [PATCH 3/4] docs(opencode): update README.md and add AGENTS.md for feature documentation --- AGENTS.md | 38 ++++++++++++++++++++++++++++++++++++++ README.md | 45 +-------------------------------------------- 2 files changed, 39 insertions(+), 44 deletions(-) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..654c598 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,38 @@ +# Dev Container Features + +## Testing + +```bash +# Install devcontainers CLI +npm install -g @devcontainers/cli + +# Test a specific feature against a specific image +devcontainer features test -f opencode -i debian:latest . + +# Skip scenarios, run only autogenerated tests +devcontainer features test --skip-scenarios -f opencode . + +# Skip autogenerated, run only scenario tests +devcontainer features test --skip-autogenerated --skip-duplicated -f opencode . +``` + +## Features + +| Feature | Description | +|---------|-------------| +| `opencode` | Installs opencode CLI + fixes volume-mounted directory permissions | +| `agency-agents` | Installs msitarzewski/agency-agents for Cursor/Copilot | + +## Feature Structure + +Each feature lives in `src//` with: +- `devcontainer-feature.json` - metadata + options +- `install.sh` - entrypoint script + +## Options + +Options from `devcontainer-feature.json` are exported as environment variables (uppercase, sanitized). Example: option `tool` becomes `$TOOL` in install.sh. + +## Publishing + +Features are published to GHCR. Release workflow runs on tag push (e.g., `feature_opencode_0.2.0`). \ No newline at end of file diff --git a/README.md b/README.md index e98703e..72b1f62 100644 --- a/README.md +++ b/README.md @@ -107,47 +107,4 @@ When these directories are volume-mounted into the container, they may be owned ### Shared Volumes Between Projects -If you share the same `~/.opencode` volume mounts across multiple projects, be aware that opencode's state and data will be shared as well. This can be useful for preserving context between projects, but may also cause unexpected behaviour if projects have conflicting configurations. Consider using separate volume mounts per project if isolation is needed. - -## Repo and Feature Structure - -Similar to the [`devcontainers/features`](https://github.com/devcontainers/features) repo, this repository has a `src` folder. Each Feature has its own sub-folder, containing at least a `devcontainer-feature.json` and an entrypoint script `install.sh`. - -``` -├── src -│ ├── agency-agents -│ │ ├── devcontainer-feature.json -│ │ └── install.sh -... -``` - -An [implementing tool](https://containers.dev/supporting#tools) will composite [the documented dev container properties](https://containers.dev/implementors/features/#devcontainer-feature-json-properties) from the feature's `devcontainer-feature.json` file, and execute in the `install.sh` entrypoint script in the container during build time. Implementing tools are also free to process attributes under the `customizations` property as desired. - -### Options - -All available options for a Feature should be declared in the `devcontainer-feature.json`. The syntax for the `options` property can be found in the [devcontainer Feature json properties reference](https://containers.dev/implementors/features/#devcontainer-feature-json-properties). - -For example, the `agency-agents` feature exposes a `tool` string option. If no option is provided in a user's `devcontainer.json`, the value defaults to `auto`. - -```jsonc -{ - // ... - "options": { - "tool": { - "type": "string", - "default": "auto", - "description": "Tool name passed to ./scripts/install.sh --tool . Use 'auto' for --parallel auto-detection." - } - } -} -``` - -Options are exported as Feature-scoped environment variables. The option name is capitalised and sanitised according to [option resolution](https://containers.dev/implementors/features/#option-resolution). - -```bash -#!/bin/sh - -tool="${TOOL:-auto}" - -... -``` \ No newline at end of file +If you share the same `~/.opencode` volume mounts across multiple projects, be aware that opencode's state and data will be shared as well. This can be useful for preserving context between projects, but may also cause unexpected behaviour if projects have conflicting configurations. Consider using separate volume mounts per project if isolation is needed. \ No newline at end of file From 3e2cc9043fec43e003997d0134e9abca872ddee7 Mon Sep 17 00:00:00 2001 From: Wyller Gomes Date: Tue, 7 Apr 2026 16:26:50 +0000 Subject: [PATCH 4/4] chore(opencode): bump version to 0.2.1 --- src/opencode/devcontainer-feature.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opencode/devcontainer-feature.json b/src/opencode/devcontainer-feature.json index d634fd6..d2cad16 100644 --- a/src/opencode/devcontainer-feature.json +++ b/src/opencode/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "opencode CLI", "id": "opencode", - "version": "0.2.0", + "version": "0.2.1", "description": "Installs the opencode AI coding agent CLI and ensures volume-mounted data directories are owned by the correct user.", "documentationURL": "https://opencode.ai", "options": {