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
12 changes: 11 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ chars. When adding entries to `permission.bash`:
- TypeScript with `strict: true`, compiled by `tsc` to `dist/`. Source in `bin/` and `src/`.
- Internal imports use `.js` extensions even though source is `.ts` (NodeNext convention; tsc emits the `.js` files at the matching paths).
- Edits → `npm run build` → `node dist/bin/...` (or `npm link` once for global use).
- One runtime dep: `chalk`. Don't add more without justification.
- Two runtime deps: `chalk`, `ajv`. Don't add more without justification.
- Atomic writes: `writeFile(tmp); rename(tmp, final)`. Never write the
target in place.
- All paths use `node:path`'s `resolve`/`join`; never string-concat
Expand Down Expand Up @@ -130,6 +130,16 @@ Do NOT add any of the following without an explicit human review:
the only source of truth.
- New runtime dependencies in general — see "Code conventions" above.

Third-party code in a preset (`plugin`, `mcp` command, `@fetch`) → pin
exact version, git tag, or SHA. Unpinned ref or `@latest` → justify in
`@description`. opencode caches by full spec string and never re-checks,
so an unpinned ref freezes at first resolve; changing the string is what
triggers the re-fetch.

`@fetch` → always `sha256=`, and version the dest filename too;
`fetchAsset` skips an existing dest, so reusing the filename makes a bump
a no-op. Verify the hash against a second source before committing.

The `npm publish` step must pass `--provenance` so the published
tarball carries SLSA build attestation verifiable via
`npm audit signatures`.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,18 +84,18 @@ on a readline for the next.

| Preset | Category | Mode | Description |
| --- | --- | --- | --- |
| `jdtls-lombok` | LSP | replace | Makes jdtls lombok-aware via `-javaagent` flag |
| `jdtls-lombok` | LSP | replace | Makes jdtls lombok-aware via `-javaagent` flag (pinned to lombok 1.18.46, sha256-verified) |
| `jdtls-clean-workspace` | LSP | replace | Stops jdtls from writing `.project`/`.classpath`/etc. into your project root |
| `mcp-http` | MCP | replace | Add an HTTP MCP server (localhost or remote) with one custom header (prompts for id, URL, header name, header value) |
| `mcp-http-noauth` | MCP | replace | Add an HTTP MCP server (localhost or remote) without auth headers (prompts for id, URL) |
| `mcp-intellij` | MCP | replace | Add the JetBrains IDE MCP server (loopback HTTP, default port 64342) |
| `mcp-litellm` | MCP | replace | Add a LiteLLM proxy's MCP gateway as a remote MCP server (prompts for gateway URL and LiteLLM key; auth via `x-litellm-api-key`, no login flow) |
| `mcp-litellm-passthrough` | MCP | replace | Add one `x-mcp-<alias>-<header>` passthrough header to the `mcp.litellm` server so an upstream MCP server authenticates as you (run once per header; install `mcp-litellm` first) |
| `mcp-playwright` | MCP | replace | Add the Playwright MCP server (`@playwright/mcp`, local stdio via npx) |
| `mcp-playwright` | MCP | replace | Add the Playwright MCP server (`@playwright/mcp`, local stdio via npx; pinned to an exact version) |
| `mcp-vscode` | MCP | replace | Add the VS Code MCP server via the `JuehangQin.vscode-mcp-server` extension (loopback HTTP, default port 3000) |
| `plugin-litellm-pricing` | Plugin | append | Add `opencode-litellm-pricing` — discovers a LiteLLM proxy's models at runtime and adds them to the picker with real per-model pricing instead of `$0` (pair with `provider-litellm` to set the proxy URL and key) |
| `plugin-litellm-pricing` | Plugin | append | Add `opencode-litellm-pricing` — discovers a LiteLLM proxy's models at runtime and adds them to the picker with real per-model pricing instead of `$0` (pair with `provider-litellm` to set the proxy URL and key; pinned to an exact version) |
| `provider-litellm` | Provider | replace | Point the `litellm` provider at your proxy URL for `plugin-litellm-pricing` (prompts for base URL and API key; no models list) |
| `plugin-superpowers` | Plugin | append | Add the Superpowers OpenCode plugin from `obra/superpowers` (brainstorming, plans, TDD, review workflows) |
| `plugin-superpowers` | Plugin | append | Add the Superpowers OpenCode plugin from `obra/superpowers` (brainstorming, plans, TDD, review workflows; pinned to an exact upstream tag) |
| `permissions-git-safe` | Permissions | merge | Read-only git commands (status, diff, log, branch --list, fetch, etc.) |
| `permissions-webfetch-ask` | Permissions | merge | Requires approval before opencode uses the webfetch tool |
| `permissions-shell-safe` | Permissions | merge | Low-risk shell commands (ls, cat, grep, rg, jq, yq, etc.) |
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions presets/jdtls-lombok.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
// a -javaagent flag pointing at lombok.jar to the jdtls command. The
// LSP then resolves lombok-generated getters, setters, builders, etc.
// instead of flagging them as missing. Requires `jdtls` and a JDK 21+
// on PATH.
// on PATH. Pinned to an exact lombok version and verified by sha256;
// bump both the @fetch line and the -javaagent path here to update.
// @author: Jan <jan@trick77.com>
// @version: 0.1.0
// @version: 0.2.0
// @path: lsp.jdtls.command
// @fetch: https://projectlombok.org/downloads/lombok.jar -> {{cache}}/lombok.jar
// @fetch: https://projectlombok.org/downloads/lombok-1.18.46.jar -> {{cache}}/lombok-1.18.46.jar sha256=01f7b1a015e33e2b62d5f5f37053306357ab1415fd181fcba7794f5d198c1126
[
"jdtls",
"--jvm-arg=-javaagent:{{cache}}/lombok.jar"
"--jvm-arg=-javaagent:{{cache}}/lombok-1.18.46.jar"
]
11 changes: 7 additions & 4 deletions presets/mcp-playwright.conf
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@
// navigate, click, fill forms, take screenshots, and read
// accessibility snapshots — useful for end-to-end testing prompts
// and "check this page in a browser" workflows. Runs via
// `npx -y @playwright/mcp@latest`; the first invocation downloads
// `npx -y @playwright/mcp@0.0.78`; the first invocation downloads
// the package and (on first browser use) the Playwright browser
// binaries via `npx playwright install`. No prompts — accepts
// binaries via `npx playwright install`. Pinned to an exact version;
// bump it here to update. npx re-resolves the spec on every server
// start, so an unpinned `@latest` would silently pull new upstream
// code each time opencode launches the browser. No prompts — accepts
// Playwright MCP's defaults (Chromium, headed). Hand-edit
// opencode.json afterwards if you want --browser=firefox/webkit,
// --headless, or other flags.
// @author: Jan <jan@trick77.com>
// @version: 0.1.0
// @version: 0.2.0
// @path: mcp.playwright
{
"type": "local",
"command": ["npx", "-y", "@playwright/mcp@latest"],
"command": ["npx", "-y", "@playwright/mcp@0.0.78"],
"enabled": true
}
4 changes: 2 additions & 2 deletions presets/plugin-litellm-pricing.conf
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
// proxy API key. Pinned to an exact version; bump it here to update. After installing a
// plugin preset, quit and restart opencode.
// @author: Jan <jan@trick77.com>
// @version: 0.2.1
// @version: 0.3.0
// @path: plugin
// @mode: append

["opencode-litellm-pricing@0.1.1"]
["opencode-litellm-pricing@0.2.0"]
10 changes: 7 additions & 3 deletions presets/plugin-superpowers.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
// @description: Adds the Superpowers OpenCode plugin from obra/superpowers.
// Registers the Superpowers skill set, including brainstorming,
// writing-plans, executing-plans, TDD, code review, and related
// workflow skills. Uses OpenCode's git-backed plugin install.
// workflow skills. Uses OpenCode's git-backed plugin install, pinned
// to an exact upstream tag; bump it here to update. opencode resolves
// a plugin spec once and caches it by the full spec string, so an
// unpinned ref would freeze at whatever the default branch happened to
// be on the day you installed.
// @author: Jan <jan@trick77.com>
// @version: 0.1.0
// @version: 0.2.0
// @path: plugin
// @mode: append

["superpowers@git+https://github.com/obra/superpowers.git"]
["superpowers@git+https://github.com/obra/superpowers.git#v6.2.0"]
2 changes: 1 addition & 1 deletion test/builtin-presets.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ test('ships a litellm plugin preset that appends the runtime-discovery plugin',
assert.equal(meta.name, 'plugin-litellm-pricing');
assert.equal(meta.path, 'plugin');
assert.equal(meta.mode, 'append');
assert.deepEqual(body, ['opencode-litellm-pricing@0.1.1']);
assert.deepEqual(body, ['opencode-litellm-pricing@0.2.0']);
});

test('ships a litellm provider preset that points at a proxy URL, no models', async () => {
Expand Down