Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
"ghcr.io/stuartleeks/dev-container-features/shell-history:0": {},
"ghcr.io/jsburckhardt/devcontainer-features/gic:1": {}


"ghcr.io/devcontainers/features/github-cli:latest": {}
Copy link

Copilot AI Sep 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change replaces (and removes) the previously declared gic feature but appears unrelated to adding the opencode feature; revert or move to a separate PR to keep scope focused.

Suggested change
"ghcr.io/devcontainers/features/github-cli:latest": {}
"ghcr.io/devcontainers/features/github-cli:latest": {},
"ghcr.io/someorg/gic:latest": {}

Copilot uses AI. Check for mistakes.
},
"updateContentCommand": "npm install -g @devcontainers/cli",
"remoteUser": "node",
Expand Down
1 change: 1 addition & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ When creating a new feature, follow these steps:
- Update the ../../test/_global/all-tools.sh to validate the new feature is installed.
- Update the ../../test/_global/scenarios.json to include the new feature.
- include the feature in the workflows
- run `devcontainer features test -f $(feature) -i ubuntu:latest`
18 changes: 0 additions & 18 deletions .github/prompts/generate-commit-message.prompt.md

This file was deleted.

152 changes: 152 additions & 0 deletions .github/prompts/new-feature.prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
---
mode: 'agent'
description: 'Implement a new Dev Container Feature in this repository.'
---

# New Devcontainer Feature Generator

## Purpose
Implement a new Dev Container Feature in this repository.

## Invocation Pattern (Human Usage Examples)
- `/new-feature just in @casey/just`
- `/new-feature ripgrep in @BurntSushi/ripgrep`
- `/new-feature mise in @jdx/mise version=2024.7.1`
- `/new-feature protolint in @yoheimuta/protolint checksum=true`

Copilot: Parse the user’s invocation to fill the Variables section below before generating changes.

## Variables (to be derived or defaulted)
Extract from user command or infer:
- FEATURE_ID: Lowercase id (no spaces). Example: `just`, `ripgrep`, `mise`.
- FEATURE_DISPLAY_NAME: Human-friendly (capitalize if appropriate). Example: `Just`, `Ripgrep`.
- SOURCE_REPO: GitHub `owner/name` the binary/tool comes from. Example: `casey/just`.
- BINARY_NAME: Name of the installed executable (often equals FEATURE_ID; override if different).
- REQUESTED_VERSION: Explicit version if user supplied `version=...`; else "latest".
- SUPPORT_CHECKSUM: Boolean if user included `checksum=true`; default false.
- EXTRA_OPTIONS: Optional structured options (e.g. additional feature options) if user appended `opt:key=value` pairs.
- INITIAL_FEATURE_VERSION: Always start at `1.0.0` (Feature’s internal semver, NOT the tool upstream version).
- ARCH_LIST: Default `[x86_64, i686, aarch64, armv7]` (omit unsupported ones if known).
- RELEASE_ASSET_PATTERN: Infer typical asset naming scheme once you inspect the SOURCE_REPO’s latest release assets (handle suffix variations like `linux-x86_64.tar.gz`, `.zip`, plain binary, etc.).

If inference is ambiguous, favor adding commented fallback logic rather than guessing incorrectly.

## High-Level Task
Create a new Feature at `src/FEATURE_ID` that:
1. Installs the tool from GitHub releases (or alternative upstream if tool uses another distribution method).
2. Supports a `version` option (default `"latest"`) resolving to the latest stable release (exclude pre-releases unless user explicitly requests one).
3. Implements multi-architecture support mapping `uname -m` to release asset names.
4. Provides graceful fallback if GitHub API calls fail (e.g. rate limit / firewall) by:
- Trying API first (`https://api.github.com/repos/SOURCE_REPO/releases/latest`)
- Falling back to parsing HTML of `https://github.com/SOURCE_REPO/releases/latest` or using a lightweight strategy (document what you did).
5. (Optional) Performs checksum verification if SUPPORT_CHECKSUM is true AND the upstream provides checksums (e.g. `SHA256SUMS` file).
6. Adds tests: basic install + pinned version test; checksum test if applicable.
7. Updates root README to list the feature with usage examples.
8. Integrates tests into existing CI matrix (mirroring the just feature pattern).
9. Uses consistent shell style and safety (`set -euo pipefail`, traps for cleanup).
10. Leaves unrelated files untouched (NO incidental formatting changes, NO kyverno/zarf edits, NO drive-by refactors).

## File/Directory Deliverables
Create:
- `src/FEATURE_ID/devcontainer-feature.json`
- `src/FEATURE_ID/install.sh`
- `test/FEATURE_ID/test.sh`
- `test/_global/FEATURE_ID-specific-version.sh`
update
- `test/_global/all-tools.sh`
- `test/_global/scenarios.json`
- `.github/workflows/test.yaml`

Modify minimally:
- Root `README.md` (add new feature entry & examples)

## devcontainer-feature.json Requirements
- `id`: FEATURE_ID
- `version`: INITIAL_FEATURE_VERSION
- `name`: FEATURE_DISPLAY_NAME
- `description`: Concise summary of what the tool does
- `documentationURL`: Link to this feature’s README
- `options.version`: string, default "latest"
- Add any EXTRA_OPTIONS (preserve ordering)
- `instantiationMode`: "onCreate"

## install.sh Requirements
1. `#!/usr/bin/env bash`
2. `set -euo pipefail`
3. Parse inputs: `VERSION=$VERSION` (from feature option) -> treat "latest" specially.
4. Architecture map example (adjust names per RELEASE_ASSET_PATTERN):
- `x86_64` or `amd64` -> `x86_64`
- `aarch64` or `arm64` -> `aarch64`
- `armv7l` -> `armv7`
- `i386` or `i686` -> `i686`
5. Resolve version:
- If VERSION == "latest":
- Try GitHub API → extract tag_name minus leading `v` if present
- Fallback to scraping or light pattern detection from releases page HTML
- Else trust user-supplied
6. Construct download URL (document pattern).
7. Download to temp dir. Use curl with retry/backoff flags similar to just feature style.
8. Extract / move binary:
- If archive: detect extension (.tar.gz, .zip), extract accordingly.
- Ensure final binary path: `/usr/local/bin/BINARY_NAME` and `chmod 0755`.
9. (Optional) Checksum:
- Download checksums file, grep the asset, verify via `sha256sum -c -`
10. Verification:
- Run `${BINARY_NAME} --version` or fallback command; ensure it prints something containing resolved version if version != "latest".
11. Output a success message.


## CI Integration
- Update workflow to include FEATURE_ID in matrix if that’s how others are integrated.
- Keep ordering logical (append near similar tooling features).
- Avoid reorganizing unrelated entries.

## Commit / PR Conventions
Suggested (may auto-squash):
1. `chore: scaffold FEATURE_ID feature`
2. `feat: implement FEATURE_ID install logic`
3. `test: add tests for FEATURE_ID`
4. `docs: add FEATURE_ID feature documentation`

PR Title:
`feat: add FEATURE_ID devcontainer feature`

PR Body Should Include:
- Summary
- Version handling strategy
- Architecture support
- Checksum support (yes/no)
- Usage examples
- Tests added
- Statement: “No unrelated changes; excludes kyverno/zarf fixes.”

## Constraints & Non-Goals
- Do NOT refactor global scripts.
- Do NOT adjust unrelated workflow triggers.
- Do NOT rename existing features.
- Do NOT remove or reorder existing README content beyond adding new entry.

## Acceptance Criteria
- All new tests pass in CI.
- Feature listed in root README.
- `install.sh` resilient to GitHub API failure with fallback.
- Pinning a version works.
- Latest resolution works.
- No unrelated file diffs (confirm with `git diff` scope).
- If checksum requested and available upstream, verification implemented (skip gracefully if not).

## Output Format Instruction for Copilot
When generating the PR:
1. Create new branch (named `feature/FEATURE_ID`).
2. Add/modify files exactly as specified.
3. Open a pull request with the defined title and body.
4. Include only relevant changes.

## Post-Generation Self-Check (Copilot)
Before finalizing:
- Re-open each new file; ensure placeholders replaced.
- Ensure executable bits on `install.sh` and test scripts.
- Ensure JSON is valid (no trailing commas).
- Ensure shell uses POSIX-compatible constructs (or justify bash usage).
- Verify version extraction logic with both “latest” and pinned flows (mentally or via test design).
- Confirm absence of kyverno/zarf references / modifications.
1 change: 1 addition & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ jobs:
- codex
- bat
- just
- opencode
baseImage:
- debian:latest
- ubuntu:latest
Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ This repository contains a _collection_ of Features.
| just | https://github.com/casey/just | A command runner. Just is a handy way to save and run project-specific commands. |
| UV/UVX | https://docs.astral.sh/uv/ | An extremely fast Python package and project manager, written in Rust. A single tool to replace pip, pip-tools, pipx, poetry, pyenv, virtualenv, and more. |
| Ruff | https://docs.astral.sh/ruff/ | An extremely fast Python linter and code formatter, written in Rust. |
| OpenCode | https://opencode.ai/ | AI coding agent, built for the terminal. An open-source alternative to Claude Code with support for multiple LLM providers. |
| Codex-cli | https://github.com/openai/codex | Codex CLI is an experimental project under active development. |


Expand Down Expand Up @@ -283,6 +284,24 @@ Running `k3d` inside the built container will print the help menu of k3d.
```bash
k3d --version
```

### `opencode`

Running `opencode` inside the built container will allow you to use the AI coding agent.

```jsonc
{
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"ghcr.io/jsburckhardt/devcontainer-features/opencode:1": {}
}
}
```

```bash
opencode --version
```

### `Codex-CLI`

Running `codex` inside the built container will print the help menu of codex.
Expand Down
21 changes: 21 additions & 0 deletions src/opencode/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "OpenCode",
"id": "opencode",
"version": "1.0.0",
"description": "AI coding agent, built for the terminal. An open-source alternative to Claude Code with support for multiple LLM providers.",
"documentationURL": "https://opencode.ai/docs",
"options": {
"version": {
Comment on lines +7 to +8
Copy link

Copilot AI Sep 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The feature metadata is missing an instantiationMode field (e.g., "instantiationMode": "onCreate") as outlined in the repository’s feature authoring conventions; adding it makes execution timing explicit.

Suggested change
"options": {
"version": {
"instantiationMode": "onCreate",
"options": {

Copilot uses AI. Check for mistakes.
"type": "string",
"default": "latest",
"description": "Version of opencode to install from GitHub releases e.g. 0.10.4"
}
},
"customizations": {
"vscode": {
"extensions": [
"sst-dev.opencode"
]
}
}
}
Loading