mirror of
https://github.com/backnotprop/plannotator.git
synced 2026-09-14 14:17:26 +08:00
fe84b3d37e
Review found the capability probe was wrong in the direction that matters.
ctx.command.transform exists on pre-#44765 hosts too: our own pinned
@opencode-ai/plugin@0.0.0-next-16775 declares CommandDraft as
{ list, get, update, remove } with no add. The probe therefore returned true on
next and latest, draft.add was undefined, and because transforms are stored and
replayed the TypeError landed in the batched reload flush and aborted it before
commit, plausibly taking every command registration on the host down with it.
Capability is now read from the draft handed to the callback, which is the only
witness, and the registration call is wrapped so no transform rejection can fail
plugin setup.
The stubs also shadowed the native definitions on new hosts. Command definitions
land in a name-keyed map where add is Map.set, transforms replay in registration
order, and OpenCode's own ConfigCommandPlugin activates in the post group after
package plugins while scanning the exact directory the installer writes the
three stubs to. A setup-time registration is therefore always overwritten on a
normal install. The plugin now re-registers the same transform once activation
settles, so its definitions are last in the replay order, and calls
ctx.command.reload() explicitly because a late registration only adds its reload
to the already-flushed boot batch. Ownership is read back from
ctx.command.list() by description, which is why the native descriptions and the
stub frontmatter are deliberately distinct. If the reclaim cannot run the stubs
keep the names and the commands still work through their fallback bodies.
Also: a failing switchAgent no longer costs the reviewer their feedback on the
command path, feedback is delivered as "queue" rather than replaying the
invocation's admission mode minutes later when a steer would land mid-turn, and
the agent-list comment no longer asserts a bare-array response that could not be
reproduced upstream (accepting both shapes is still right, since reading .data
blindly throws into a catch that degrades silently).
Tests: the real old-host draft shape registers nothing and throws nothing, the
shadowing contest is modelled against upstream's replay semantics, the OpenCode 1
parts-clearing invariant is pinned for all three commands in both plan-agent and
manual mode now that the stubs carry real instructions, and the V2 smoke asserts
the plugin did not activate as failed and that all three commands resolve. The
smoke now also installs the stubs into its sandbox config dir so the contest
actually happens there. scripts/opencode2-native-commands-smoke.sh runs the same
smoke against a dev-channel build with native commands required; CI cannot,
because it pins a next build.
AI-assisted (Claude) under maintainer direction.
54 lines
2.0 KiB
Bash
Executable File
54 lines
2.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Verify the OpenCode 2 native slash commands against a host that actually has
|
|
# the post-#44765 command API.
|
|
#
|
|
# CI cannot do this: .github/workflows/test.yml pins @opencode-ai/cli to a
|
|
# `next` build, and `next` still ships the older command draft (no `add`), so
|
|
# the CI leg can only prove the fallback path. The command API currently lives
|
|
# on the `beta` and `dev` dist-tags, which move daily and are not something to
|
|
# pin a required check to. So this is a script a human runs before a release.
|
|
#
|
|
# Usage:
|
|
# scripts/opencode2-native-commands-smoke.sh [dist-tag] # default: dev
|
|
#
|
|
# What it proves:
|
|
# 1. The plugin activates without status:"failed".
|
|
# 2. All three slash commands resolve.
|
|
# 3. They resolve to the PLUGIN's definitions, not the markdown stubs the
|
|
# fixture installs into the sandbox config dir exactly as install.sh does.
|
|
# (3) is the shadowing check and is fatal here because of
|
|
# PLANNOTATOR_SMOKE_EXPECT_NATIVE=1.
|
|
#
|
|
# What it does NOT prove: that /plannotator-review opens the UI without a model
|
|
# turn. Run that by hand in the TUI against the same build.
|
|
|
|
set -euo pipefail
|
|
|
|
tag="${1:-dev}"
|
|
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
work="$(mktemp -d)"
|
|
trap 'rm -rf "$work"' EXIT
|
|
|
|
echo "==> installing @opencode-ai/cli@$tag into $work"
|
|
cd "$work"
|
|
npm init -y >/dev/null 2>&1
|
|
npm install --no-audit --no-fund "@opencode-ai/cli@$tag" >/dev/null
|
|
opencode_bin="$work/node_modules/.bin/opencode"
|
|
if [ ! -x "$opencode_bin" ]; then
|
|
echo "No opencode binary at $opencode_bin" >&2
|
|
exit 1
|
|
fi
|
|
"$opencode_bin" --version
|
|
|
|
echo "==> building and packing the plugin"
|
|
cd "$repo_root"
|
|
bun run build:opencode
|
|
cd "$repo_root/apps/opencode-plugin"
|
|
bun pm pack --filename "$work/plannotator-opencode.tgz" >/dev/null
|
|
|
|
echo "==> running the smoke with native commands required"
|
|
PLANNOTATOR_SMOKE_EXPECT_NATIVE=1 \
|
|
bun run --cwd "$repo_root/apps/opencode-plugin" smoke:v2 -- \
|
|
"$opencode_bin" \
|
|
"$work/plannotator-opencode.tgz"
|