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
16 changes: 16 additions & 0 deletions .github/workflows/marketplace.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,15 @@ jobs:
echo "::error::${TAG} ships a manifest for ${MANIFEST_VERSION}"
exit 1
fi
# The static declaration copy is attached only by releases that bound one; `gh release
# download` fails when no asset matches, so absence is expected, not an error.
if grep -q '^\[agent_configuration\]' dist/manifest.toml; then
gh release download "$TAG" \
--repo "$GITHUB_REPOSITORY" \
--pattern agent-configuration.json \
--dir dist \
--clobber
fi

# `GITHUB_TOKEN` cannot write to another repository, so the push borrows a short-lived
# installation token from the organization's app rather than a long-lived PAT.
Expand Down Expand Up @@ -175,6 +184,13 @@ jobs:
mkdir -p "$DIR"
cp ../dist/manifest.toml "${DIR}/orax.toml"
cp ../README.md "${DIR}/README.md"
# The declaration copy the manifest's `[agent_configuration]` names, when this release
# bound one; the sync reads it relative to this entry directory.
if [ -f ../dist/agent-configuration.json ]; then
cp ../dist/agent-configuration.json "${DIR}/agent-configuration.json"
else
rm -f "${DIR}/agent-configuration.json"
fi

# The bare logo, plus any themed variant (`logo.dark.svg`) and raster format the plugin
# carries. Cleared first so a variant the plugin has since dropped does not linger.
Expand Down
12 changes: 10 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ jobs:

# Writes dist/packages/*.orax (one per declared target) and dist/manifest.toml, reproducing
# exactly what upstream.lock.json records rather than resolving anything itself.
# With `--agent-configuration` every package carries assets/config.json, the Agent
# declaration, and the release binds it; the flag waits until the Ora hosts that resolve the
# declaration are deployed — current hosts install an `agent`-kind package carrying it but
# then refuse to activate the plugin, so the bytes must not ship early.
- name: Package
env:
GH_TOKEN: ${{ github.token }}
Expand All @@ -78,8 +82,12 @@ jobs:
TAG: ${{ inputs.tag || github.ref_name }}
run: |
set -euo pipefail
gh release create "$TAG" \
dist/packages/*.orax dist/manifest.toml \
ASSETS=(dist/packages/*.orax dist/manifest.toml)
# The static declaration copy only exists when the release bound one.
if [ -f dist/agent-configuration.json ]; then
ASSETS+=(dist/agent-configuration.json)
fi
gh release create "$TAG" "${ASSETS[@]}" \
--title "$TAG" \
--generate-notes

Expand Down
30 changes: 25 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,25 @@ Bump `orax.toml` `version` before tagging: `install_local` refuses a version
that is already installed and never retires older ones, so reusing a number
silently leaves the old code running.

### The Agent declaration, and when a release ships it

`assets/config.json` is the Agent declaration of what this plugin asks the host
to configure: one personal model connection over `openai-completions` or
`anthropic-messages`. It only ships when packaging runs with
`deno task package --agent-configuration`: every `.orax` then carries it, the
script reads it back from each finished archive and refuses a release whose
packages disagree, writes the static copy `dist/agent-configuration.json`, and
adds `[agent_configuration]` to `dist/manifest.toml`. `release.yml` attaches the
copy and `marketplace.yml` places it beside the registry entry. A release binds
exactly one declaration digest, and `tests/package_test.ts` pins it, so
reformatting the file is a conscious, release-affecting change.

**The flag waits for host support.** A current Ora host installs an `agent`-kind
package carrying a declaration it cannot compile and then refuses to activate
it, so `release.yml` passes the flag only once hosts resolving the declaration
are deployed — an owner decision made by editing one line. Without the flag the
release is exactly what it was before.

## Logging

Everything this plugin says goes through the SDK's `plugin.logger`, which writes
Expand Down Expand Up @@ -346,11 +365,12 @@ the run.

- `deno task check` / `lint` / `format` / `simulate` / `build` / `sync` /
`package`.
- There is no unit test suite here; `tests/host-simulator.ts` drives the plugin
the way Ora's host does and needs a real CLI, staged or on PATH. CI runs only
`check` and `lint`, deliberately: type checking resolves the whole module
graph, so it is also what catches an SDK version that is not published yet,
and lint stays meaningful even while that fails.
- `deno task test` runs `tests/package_test.ts`, the packaging checks that need
no CLI. `tests/host-simulator.ts` drives the plugin the way Ora's host does
and needs a real CLI, staged or on PATH. CI runs only `check` and `lint`,
deliberately: type checking resolves the whole module graph, so it is also
what catches an SDK version that is not published yet, and lint stays
meaningful even while that fails.
- The SDK is imported from its published JSR package and pinned in `deno.json`;
keep `deno.lock` synchronized when changing the SDK version.
- `scripts/package.ts` and `scripts/upstream.ts` know nothing about OpenCode
Expand Down
1 change: 1 addition & 0 deletions assets/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"schemaVersion":2,"agent":{"modelAccess":{"contractVersion":1,"protocols":["openai-completions","anthropic-messages"],"modelCardinality":"single"}}}
14 changes: 11 additions & 3 deletions deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@
"minimumDependencyAge": 0,
"imports": {
"@ora-space/plugin-sdk": "jsr:@ora-space/plugin-sdk@0.10.0",
"@std/assert": "jsr:@std/assert@^1.0.0",
"@std/cli": "jsr:@std/cli@^1.0.32",
"@std/path": "jsr:@std/path@^1.1.6",
"@std/tar": "jsr:@std/tar@^0.1.10",
"@zip-js/zip-js": "jsr:@zip-js/zip-js@^2.8.61"
},
"tasks": {
"check": "deno check src/main.ts scripts/package.ts scripts/sync-upstream.ts tests/host-simulator.ts",
"check": "deno check src/main.ts scripts/package.ts scripts/sync-upstream.ts tests/host-simulator.ts tests/package_test.ts",
"lint": "deno lint src scripts tests bundle.config.ts",
"format": "deno fmt src scripts tests bundle.config.ts deno.json README.md AGENTS.md",
"test": "deno test --allow-read --allow-write tests/package_test.ts",
"simulate": "deno run --allow-run --allow-read --allow-env --allow-net tests/host-simulator.ts",
"dev": "deno run --no-prompt --allow-run --allow-read --allow-env --allow-net src/main.ts",
"build": "deno bundle src/main.ts -o dist/main.js",
Expand All @@ -22,7 +24,11 @@
},
"compilerOptions": {
"strict": true,
"lib": ["deno.ns", "dom", "esnext"]
"lib": [
"deno.ns",
"dom",
"esnext"
]
},
"fmt": {
"lineWidth": 80,
Expand All @@ -31,7 +37,9 @@
},
"lint": {
"rules": {
"tags": ["recommended"]
"tags": [
"recommended"
]
}
}
}
13 changes: 11 additions & 2 deletions deno.lock

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

Loading
Loading