Skip to content
Open
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
86 changes: 86 additions & 0 deletions .github/workflows/opencode-plugin.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: OpenCode plugin

# opencode-genclass (packages/opencode-plugin): typecheck, build and the unit tests (the V1 hooks, the V2 setup on a
# fake context, the digest against a stub bridge, parity with `genclass-mcp hook`), then in a second job the plugin
# in the real OpenCode binaries (test/smoke/run.mjs): opencode-ai@1.19.5 and @opencode/cli@2.2.5 from npm, the
# genclass server listed and connected through the plugin, a project's own genclass entry winning, and on 1.x the
# findings digest reaching a stub model's request. Every check talks to 127.0.0.1 only, besides npm (the binaries
# and @genclass/mcp). A separate workflow from ci.yml so it never blocks the main CI job; it publishes nothing.

on:
push:
paths:
- "packages/opencode-plugin/**"
- "packages/mcp/src/cli.ts"
- "packages/mcp/src/text.ts"
- "packages/mcp/package.json"
- "package-lock.json"
- ".github/workflows/opencode-plugin.yml"
pull_request:
paths:
- "packages/opencode-plugin/**"
- "packages/mcp/src/cli.ts"
- "packages/mcp/src/text.ts"
- "packages/mcp/package.json"
- "package-lock.json"
- ".github/workflows/opencode-plugin.yml"
workflow_dispatch:

permissions:
contents: read

concurrency:
group: opencode-plugin-${{ github.ref }}
cancel-in-progress: true

jobs:
unit:
name: "opencode-genclass: typecheck, build, unit tests"
runs-on: ubuntu-latest
timeout-minutes: 10
env:
ONNXRUNTIME_NODE_INSTALL: skip
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm

- name: Install
run: npm ci --no-audit --no-fund

- name: Typecheck
run: npm run typecheck -w opencode-genclass

- name: Build
run: npm run build -w opencode-genclass

- name: Unit tests
working-directory: packages/opencode-plugin
run: npx vitest run

opencode:
name: "opencode-genclass in OpenCode 1.19.5 and 2.2.5"
needs: unit
runs-on: ubuntu-latest
timeout-minutes: 20
env:
ONNXRUNTIME_NODE_INSTALL: skip
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm

- name: Install
run: npm ci --no-audit --no-fund

- name: Build
run: npm run build -w opencode-genclass

- name: The plugin in the real binaries
run: node packages/opencode-plugin/test/smoke/run.mjs
123 changes: 123 additions & 0 deletions .github/workflows/release-opencode.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
name: Release OpenCode plugin

# Publishes opencode-genclass (packages/opencode-plugin) to npm from a tag `opencode-v<version>` whose version equals
# packages/opencode-plugin/package.json (e.g. opencode-v0.1.0), with npm provenance, the way release-mcp.yml publishes
# @genclass/mcp. Authentication: npm trusted publishing (OIDC, `id-token: write`); no npm token is stored.
#
# Owner setup:
# - First version only: npm configures trusted publishing from a package's own settings page, so the package must exist
# before this workflow can publish it. Push the tag once: the workflow builds, tests and uploads the tarball as the
# `opencode-tarball` artifact, and its publish step fails without a trusted publisher. Publish that exact tarball once
# from your own npm login (`npm publish opencode-genclass-<version>.tgz --access public`), then on npmjs.com:
# opencode-genclass → Settings → Trusted publishing → GitHub Actions: organization genclass-dev, this repository,
# workflow filename release-opencode.yml, environment npm-publish. Later versions publish from here.
# - The npm-publish GitHub environment (shared with release.yml and release-mcp.yml) asks its reviewers to approve.
# - The plugin starts `npx -y @genclass/mcp@<version>` (src/index.ts, kept in step by packages/mcp/test/manifests.test.ts):
# release that version of @genclass/mcp first (release-mcp.yml).

on:
push:
tags: ["opencode-v*"]

permissions:
contents: read

concurrency:
group: release-opencode-${{ github.ref }}
cancel-in-progress: false

jobs:
publish:
name: "opencode-genclass: verify, build, test, publish with provenance"
runs-on: ubuntu-latest
timeout-minutes: 30
environment: npm-publish
permissions:
contents: read
id-token: write # OIDC token for npm trusted publishing and the provenance attestation
env:
ONNXRUNTIME_NODE_INSTALL: skip
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.ref }}

- uses: actions/setup-node@v4
with:
node-version: 22
registry-url: https://registry.npmjs.org
cache: npm

# trusted publishing needs npm >= 11.5.1 (Node 22 ships npm 10)
- name: npm 11
run: npm install -g npm@11 && npm --version

- name: The tag names the package version, and the server it starts is on npm
run: |
TAG="${GITHUB_REF_NAME#opencode-v}"
PKG=$(node -p "require('./packages/opencode-plugin/package.json').version")
echo "tag $TAG, package.json $PKG"
test "$TAG" = "$PKG"
MCP=$(node -p "require('./packages/mcp/package.json').version")
grep -q "\"@genclass/mcp@$MCP\"" packages/opencode-plugin/src/index.ts
npm view "@genclass/mcp@$MCP" version

- name: Install
run: npm ci --no-audit --no-fund

- name: Typecheck
run: npm run typecheck -w opencode-genclass

- name: Build
run: npm run build -w opencode-genclass

- name: Unit tests
working-directory: packages/opencode-plugin
run: npx vitest run

- name: The plugin in the real OpenCode binaries
run: node packages/opencode-plugin/test/smoke/run.mjs

- name: Pack
id: pack
working-directory: packages/opencode-plugin
run: |
FILE=$(npm pack --silent | tail -1)
echo "file=$FILE" >> "$GITHUB_OUTPUT"
sha512sum "$FILE"
tar -tzf "$FILE" | sort > "$FILE.files.txt"
cat "$FILE.files.txt"
# the built plugin, its README, changelog and licence; no tests or sources
grep -q "package/dist/index.js" "$FILE.files.txt"
grep -q "package/LICENSE" "$FILE.files.txt"
! grep -q "package/test/" "$FILE.files.txt"
! grep -q "package/src/" "$FILE.files.txt"

- uses: actions/upload-artifact@v4
with:
name: opencode-tarball
path: |
packages/opencode-plugin/${{ steps.pack.outputs.file }}
packages/opencode-plugin/${{ steps.pack.outputs.file }}.files.txt
if-no-files-found: error

- name: Publish with provenance
working-directory: packages/opencode-plugin
run: |
VERSION=$(node -p "require('./package.json').version")
case "$VERSION" in
*-*) DIST_TAG=$(echo "${VERSION#*-}" | cut -d. -f1) ;;
*) DIST_TAG=latest ;;
esac
npm publish "${{ steps.pack.outputs.file }}" --provenance --access public --tag "$DIST_TAG"

- name: Verify the registry signature and provenance
run: |
VERSION=$(node -p "require('./packages/opencode-plugin/package.json').version")
mkdir -p "$RUNNER_TEMP/verify" && cd "$RUNNER_TEMP/verify"
npm init -y > /dev/null
for i in $(seq 1 40); do npm view "opencode-genclass@$VERSION" version --prefer-online && break; sleep 20; done
for i in $(seq 1 10); do npm install --no-audit --no-fund --ignore-scripts "opencode-genclass@$VERSION" && break; sleep 30; done
for i in $(seq 1 20); do npm audit signatures && break; echo "attestations not served yet, retry $i"; sleep 30; done
# the published module has one default export with id, setup and server
node --input-type=module -e "import('opencode-genclass').then((m) => { const d = m.default; if (Object.keys(m).join() !== 'default' || d.id !== 'genclass' || typeof d.setup !== 'function' || typeof d.server !== 'function') process.exit(1); })"
58 changes: 58 additions & 0 deletions docs/adoption/contributions/opencode/PR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Pull request draft: anomalyco/opencode

Send only after `opencode-genclass` is on npm (see README.md, "Before sending"). Base branch `dev`. The diff is
[upstream.patch](upstream.patch): one row at the end of the Plugins table in
`packages/web/src/content/docs/ecosystem.mdx`. OpenCode asks for a short description in the sender's own words
(CONTRIBUTING.md, "Keep It Brief"; the template warns that a large AI-generated description may get the PR closed):
read the body below, then rewrite it in your own words before sending; keep it about this length.

## Title

```
docs: add opencode-genclass to the ecosystem plugins
```

## Body (the repository's template, `.github/pull_request_template.md`)

```markdown
### Issue for this PR

None: a documentation change (exempt from the linked-issue check in CONTRIBUTING.md).

### Type of change

- [ ] Bug fix
- [ ] New feature
- [ ] Refactor / code improvement
- [x] Documentation

### What does this PR do?

Adds one row to the Plugins table on the ecosystem page for opencode-genclass. The plugin adds the GenClass MCP
server (a local server that records what happens in your web app's pages in dev and replays network responses in
different orders to find race conditions) and, before each prompt, adds the findings recorded since the previous
prompt as a text part. One default export serves both OpenCode 1.x (`server` hooks: `config`, `chat.message`) and
2.x (`setup`: `mcp.transform`, `session.hook("prompt")`), the shape the V1 migration guide describes. I work on
GenClass.

### How did you verify your code works?

`prettier --check` (3.6.2, the repo's settings) passes on the file and the table padding is unchanged. The plugin
itself I ran in opencode-ai 1.19.5 and @opencode/cli 2.2.5: the server is listed and connected through the plugin,
a project's own `genclass` entry wins, and on 1.19.5 the findings reach the model request.

### Screenshots / recordings

Not a UI change.

### Checklist

- [x] I have tested my changes locally
- [x] I have not included unrelated changes in this PR

AI assistance: I used Claude (Claude Code) to write the plugin and its tests and to draft this description; I
reviewed the change and ran the checks myself.
```

The template's optional "Visual" section (an animated SVG for the desktop app's "What's new in beta") is for
user-facing app changes; delete it, as above.
Loading
Loading