[packaging] manifest+peerdep drift guards, Windows install, #510 changelog backfill (B/8)#574
Conversation
…tian-Engineering#510 changelog backfill Five separate sub-fixes that all touch packaging/process surface and review together cleanly: * test/manifest.test.ts: guard against contracts.tools / registerTool name drift. PR Martian-Engineering#555 hand-listed 4 tool names in openclaw.plugin.json; nothing prevented the next added/renamed tool from re-introducing the silent-compaction-disabled failure mode. * package.json peerDependencies: tighten @mariozechner/pi-* from "*" to ">=0.66 <1" so the next major silently mismatches at install time rather than runtime. * package.json openclaw.compat.pluginApi: add upper bound (>=2026.2.17 <2026.6.0) and a `tested:` array so `openclaw plugins doctor` can flag known-incompatible host versions instead of leaving users with the silent-load behavior Martian-Engineering#555 fixed. * .github/workflows/ci.yml: add a smoke-install job against the latest published openclaw, asserting plugin registers and lcm_* tools wire up. Catches host-side breaks like Martian-Engineering#555 before users hit them. * openclaw.plugin.json: declare kind: "context-engine" to disambiguate the Windows installer's hook-pack detector (Martian-Engineering#451). * .changeset: retroactive entry crediting jalehman for Martian-Engineering#510, which was in the v0.9.2…v0.9.3 commit delta but absent from the release notes. Closes Martian-Engineering#570, closes Martian-Engineering#571. Refs Martian-Engineering#497, Martian-Engineering#501, Martian-Engineering#527, Martian-Engineering#555, Martian-Engineering#483, Martian-Engineering#451, Martian-Engineering#384, Martian-Engineering#447, Martian-Engineering#492, Martian-Engineering#510, Martian-Engineering#511, Martian-Engineering#521.
There was a problem hiding this comment.
Pull request overview
This PR hardens the plugin’s packaging/compat surface by adding automated guards against manifest/tool drift, tightening peer dependency ranges and host compatibility bounds, adding a minimal CI smoke check against openclaw@latest, and backfilling a missing retroactive changelog entry.
Changes:
- Add
test/manifest.test.tsto assertopenclaw.plugin.json#contracts.toolsmatches toolname:fields andapi.registerTool(...)call sites, and thatmanifest.kindis pinned. - Tighten
peerDependenciesranges and add an upper bound +testedhost list inopenclaw.compat. - Add a CI job that builds the bundle, installs
openclaw@latest, and smoke-imports the plugin bundle.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| test/manifest.test.ts | Adds manifest/tool drift guard tests for contracts/tools and kind. |
| package.json | Adds bounded peer dependency ranges and openclaw.compat upper bound + tested list. |
| .github/workflows/ci.yml | Adds a smoke-latest-openclaw job to import the built bundle against openclaw@latest. |
| .changeset/retroactive-510-bootstrap-ingest-protections.md | Retroactive changeset entry for missing #510 release notes attribution. |
| .changeset/manifest-peerdep-windows-guards.md | Changeset describing the packaging/CI guard improvements. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The initial smoke job called plugin.register() against a stub api that omitted the modelAuth surface (and others) the real register path reaches into. The throw was caught, but registeredTools stayed empty and the assertion `registeredTools.length >= 4` then exit 1'd — a self-inflicted failure that doesn't map to any real host-side regression. Pivot the smoke to what we can verify without a richer fixture: - bundle imports cleanly (catches esbuild externals / ESM resolution changes) - `mod.default.register` is a callable function (catches missing default export + register-shape changes) A "register against the real openclaw plugin loader" check would be the right way to catch Martian-Engineering#555-class regressions on host-version bumps, but that needs a richer fixture than CI can stub up cheaply. Note in the comment block. Refs: Martian-Engineering#570, Martian-Engineering#555.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…rding Address review on Martian-Engineering#574: * test/manifest.test.ts: discover `src/tools/lcm-*-tool.ts` files dynamically via directory scan (was a hard-coded TOOL_FACTORY_FILES list). Adding a new tool no longer requires updating this test. Loosen the registerTool factory matcher to accept arrow-block bodies (`(ctx) => { return createXTool(...) }`), arrow-expression bodies, and async arrows — so a refactor to a different arrow shape doesn't fail the drift guard spuriously. * .github/workflows/ci.yml: add `npm prune --omit=dev` between build and openclaw install, so the smoke import resolves `@mariozechner/pi-*` from `openclaw@latest`'s transitive deps rather than from the pinned 0.66.1 devDependency we ship for local builds. Catches install-time mismatches that would otherwise hide behind the pinned versions. * .changeset/manifest-peerdep-windows-guards.md: the workflow's smoke job no longer claims to call `plugin.register(...)` and assert registerTool wiring (that path requires more host-runtime fixture than is reasonable to maintain — see Martian-Engineering#555 for the regression class). The changeset now describes the actual scope: bundle import, latest `openclaw` co-installed, callable `register` export. Manifest drift is covered by the dedicated unit test. * .changeset/retroactive-510-bootstrap-ingest-protections.md: explicit "@jalehman" credit in the body so the next changesets-rendered release note attributes Martian-Engineering#510 to its real author rather than to the PR introducing the retroactive entry. Test count unchanged at 836.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
`test/config.test.ts > "declares context-engine kind so OpenClaw core binds the contextEngine slot on install"` already covers the `manifest.kind === "context-engine"` invariant — and that single assertion also satisfies the Windows-installer hook-pack-detector concern from Martian-Engineering#451 since the `kind` field is the same discriminator in both cases. Replaced the duplicate manifest.test.ts assertion with a comment pointing readers to the canonical location to avoid the maintenance burden of updating two tests if the kind ever changes again. Addresses review on Martian-Engineering#574.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - Tighten `peerDependencies` for `@mariozechner/pi-*` from `*` to `>=0.66 <1`, and `openclaw` from `*` to `>=2026.2.17 <2026.6.0`, so the next major silently mismatches at install-time rather than at runtime. | ||
| - Add an upper bound (`<2026.6.0`) and a `tested: ["2026.5.2"]` array to `package.json#openclaw.compat`, so `openclaw plugins doctor` can flag known-incompatible host versions. | ||
| - Add a CI smoke job that builds the bundle, installs `openclaw@latest` alongside, and verifies the bundle still imports cleanly with a callable `register` export. (A deeper smoke that drives `plugin.register(...)` against a stub api turned out to require more host-runtime fixture than is reasonable to maintain in CI; the deeper "register against the real openclaw plugin loader" check is followup work — see #555 for the regression class that would warrant it.) | ||
| - The Windows installer's hook-pack detector (#451) already saw `kind: "context-engine"` in the manifest; this is now covered by an explicit assertion in the manifest drift test. |
| # Smoke-install the plugin against the latest published openclaw to catch | ||
| # bundle-level breakage (esbuild externals, ESM resolution, missing default | ||
| # export) before users hit it. Calling `plugin.register(...)` against a | ||
| # stub api would require a richer fixture than a unit-test stub can | ||
| # reasonably provide, so the deeper "register against a real loader" check | ||
| # is followup work — see #555 for the kind of failure that would warrant | ||
| # it. This v0 smoke verifies the bundle loads and exposes the expected | ||
| # registerable plugin shape with `openclaw@latest` present alongside. |
Five sub-fixes bundled because they all touch the same review surface (
package.json,openclaw.plugin.json, CI yaml, changesets). Closes #570 (manifest/peerdep guards + Windows install) and #571 (retroactive #510 changelog).Sub-items
C2 — manifest drift CI guard (#570)
test/manifest.test.ts(3 new tests) asserts:openclaw.plugin.json#contracts.toolsmatches the canonicalname:strings insrc/tools/lcm-{grep,describe,expand,expand-query}-tool.ts.api.registerTool(...)call sites insrc/plugin/index.tsequalscontracts.tools.length, and each factory name (createLcmGrepTooletc.) snake_cases to the corresponding declared tool.manifest.kind === "context-engine"(covers F13 below).Background: PR #555 hand-listed the four
lcm_*tool names in the manifest because OpenClaw 2026.5.2+ rejects undeclaredregisterToolcalls — silently. The next added/renamed tool would re-introduce that failure mode without an explicit guard.C3 — peerdep + compat upper bounds (#570)
package.json#peerDependencies:@mariozechner/pi-*from"*"to">=0.66 <1"(current pi-ai is 0.72.x, sub-1.0 family);openclawfrom"*"to">=2026.2.17 <2026.6.0".package.json#openclaw.compat:pluginApiupper bound added (<2026.6.0); newtested: ["2026.5.2"]array soopenclaw plugins doctorhas a concrete CI-exercised host list.C3 — CI matrix against
openclaw@latest(#570).github/workflows/ci.ymlgains asmoke-latest-openclawjob that:npm install --no-save openclaw@latest.dist/index.js, callsplugin.register(stubApi), and asserts at least 4registerToolfactories were observed.This is intentionally a v0 smoke pass — start small, catch the obvious breakage classes that #555 represents. A full
plugin-inspectorrun is out of scope and tracked as followup work.F13 — Windows install (#451)
openclaw.plugin.jsonalready declares"kind": "context-engine"(added in an earlier PR), which is what the Windows installer's hook-pack detector reads to disambiguatekind-less plugins. The new manifest test pins this with an explicit assertion so a future refactor can't silently drop it.C1 — retroactive changelog entry for #510 (#571)
.changeset/retroactive-510-bootstrap-ingest-protections.mdcredits jalehman for PR #510, which was in the v0.9.2…v0.9.3 commit delta but missing from the release notes.version-pr.ymlwill fold this into v0.9.4's notes with correct author attribution.Test count
test/manifest.test.ts)Build is clean (
dist/index.js660.1kb, esbuild 24ms).Followups (out of scope here)
openclaw plugin-inspectoronce that command exists / is publicly documented.pluginApiupper bound forward as new OpenClaw monthly tags are exercised in CI (updatetested:array each release).Refs #497, #501, #527, #555, #483, #451, #384, #447, #492, #510, #511, #521.