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

on:
pull_request:
paths:
- "src/source/opencode2/**"
- ".github/workflows/opencode2-activation.yml"
push:
branches:
- main
paths:
- "src/source/opencode2/**"
- ".github/workflows/opencode2-activation.yml"
workflow_dispatch:

permissions:
contents: read

jobs:
activation:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false

- uses: actions/setup-node@v6
with:
node-version: "24"
cache: npm

- name: Initialize isolated OpenCode 2 paths
shell: bash
run: |
echo "HOME=$RUNNER_TEMP/opencode2-home" >> "$GITHUB_ENV"
echo "XDG_CONFIG_HOME=$RUNNER_TEMP/opencode2-home/.config" >> "$GITHUB_ENV"
echo "XDG_DATA_HOME=$RUNNER_TEMP/opencode2-home/.local/share" >> "$GITHUB_ENV"
echo "XDG_STATE_HOME=$RUNNER_TEMP/opencode2-home/.local/state" >> "$GITHUB_ENV"

- run: npm ci

- name: Install OpenCode 2 CLI with postinstall enabled
run: npm install -g --allow-scripts=@opencode-ai/cli @opencode-ai/cli@next

- name: Install matching OpenCode 2 plugin API
run: npm install --no-save --package-lock=false @opencode-ai/plugin@next

- name: Show tested V2 versions and host API declarations
shell: bash
run: |
node -p "require('./node_modules/@opencode-ai/plugin/package.json').version"
command -v opencode2
opencode2 --version
node -p "JSON.stringify(require('./node_modules/@opencode-ai/plugin/package.json').exports, null, 2)"
for file in context session event command tool; do
echo "--- dist/promise/$file.d.ts ---"
sed -n '1,260p' "$GITHUB_WORKSPACE/node_modules/@opencode-ai/plugin/dist/promise/$file.d.ts" || true
echo "--- dist/promise/$file.js ---"
sed -n '1,260p' "$GITHUB_WORKSPACE/node_modules/@opencode-ai/plugin/dist/promise/$file.js" || true
done

- name: Prepare dependency-free V2 activation probe
shell: bash
run: |
mkdir -p "$HOME" "$XDG_CONFIG_HOME" "$XDG_DATA_HOME" "$XDG_STATE_HOME"
project="$RUNNER_TEMP/opencode-loop-v2-activation"
plugin_dir="$project/.opencode/plugins"
mkdir -p "$plugin_dir"
git init --quiet "$project"
git -C "$project" config user.email "opencode-loop-ci@example.invalid"
git -C "$project" config user.name "OpenCode Loop CI"
cat > "$plugin_dir/opencode-loop-v2-probe.js" <<'EOF'
import { writeFile } from "node:fs/promises"

const id = "bybrawe.opencode-loop.v2.activation-probe"
const marker = new URL("../../v2-activation-marker.json", import.meta.url)
const keys = (value) => value && typeof value === "object" ? Object.keys(value).sort() : []

export default {
id,
async setup(ctx) {
await writeFile(marker, JSON.stringify({
id,
activated: true,
keys: {
context: keys(ctx),
command: keys(ctx?.command),
event: keys(ctx?.event),
session: keys(ctx?.session),
tool: keys(ctx?.tool),
},
capabilities: {
commandTransform: typeof ctx?.command?.transform === "function",
eventSubscribe: typeof ctx?.event?.subscribe === "function",
sessionHook: typeof ctx?.session?.hook === "function",
sessionPrompt: typeof ctx?.session?.prompt === "function",
toolTransform: typeof ctx?.tool?.transform === "function",
toolHook: typeof ctx?.tool?.hook === "function",
},
}, null, 2), "utf8")
},
}
EOF
git -C "$project" add .opencode/plugins/opencode-loop-v2-probe.js
git -C "$project" commit --quiet -m "init"

- name: Verify dependency-free setup runs in real OpenCode 2 host
shell: bash
run: |
project="$RUNNER_TEMP/opencode-loop-v2-activation"
marker="$project/v2-activation-marker.json"
rm -f "$marker"

opencode2 api get /api/command -H "x-opencode-directory: $project" > "$RUNNER_TEMP/opencode2-command.json" 2>&1 || true
if [ ! -f "$marker" ]; then
opencode2 api get /api/plugin -H "x-opencode-directory: $project" > "$RUNNER_TEMP/opencode2-plugin.json" 2>&1 || true
fi

for attempt in $(seq 1 50); do
if [ -f "$marker" ]; then
cat "$marker"
node -e 'const fs=require("node:fs"); const value=JSON.parse(fs.readFileSync(process.argv[1],"utf8")); if(value.id!=="bybrawe.opencode-loop.v2.activation-probe" || value.activated!==true) process.exit(1)' "$marker"
exit 0
fi
sleep 0.2
done

echo "OpenCode 2 did not execute the local plugin setup hook." >&2
cat "$RUNNER_TEMP/opencode2-command.json" >&2 || true
cat "$RUNNER_TEMP/opencode2-plugin.json" >&2 || true
exit 1

- name: Dump OpenCode 2 logs on failure
if: failure()
shell: bash
run: |
find "$XDG_DATA_HOME" -maxdepth 6 -type f -print -exec sh -c 'echo "--- $1"; tail -n 200 "$1"' _ {} \;