fix(plugins): forward install records to channel catalog registry#77269
Conversation
|
Codex review: needs real behavior proof before merge. Summary Reproducibility: yes. by source inspection. Current main omits Real behavior proof Next step before merge Security Review detailsBest possible solution: Land the narrow ledger-forwarding and catalog metadata patch after accepted real behavior proof is attached, the branch is mergeable, and targeted plus changed-lane checks are green. Do we have a high-confidence way to reproduce the issue? Yes, by source inspection. Current main omits Is this the best way to solve the issue? Yes for the code direction: forwarding the existing read-only ledger records in this catalog path is the narrow maintainable fix. The PR is not merge-ready until real behavior proof and mergeability are resolved. Acceptance criteria:
What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 7188e4f4ad87. |
d889b57 to
d23cadb
Compare
06d36bb to
c11cedf
Compare
c11cedf to
60188c7
Compare
`listChannelCatalogEntries` invoked `discoverOpenClawPlugins` without forwarding `installRecords`, so npm-installed channel plugins recorded in `~/.openclaw/plugins/installs.json` were absent from the CLI channel catalog. `openclaw channels add --channel <id>` and `openclaw channels login --channel <id>` therefore reported "Unsupported channel" / "Unknown channel" for any third-party plugin even when its ledger entry was healthy. Bundled plugins (qqbot, telegram, etc.) reach the same catalog via the stock discovery path, which is why they were unaffected. Lazy-load the persisted ledger via `loadInstalledPluginIndexInstallRecordsSync` when the caller does not specify `origin === "bundled"`, and forward the records to discovery. Bundled-only callers continue to skip the disk read; callers that already loaded records (e.g. tests, batch flows) can pass them explicitly. Reader failures fall back silently to "no install records", preserving prior behaviour. Also register `@tencent-weixin/openclaw-weixin` in `scripts/lib/official-external-channel-catalog.json` so the channel appears in onboarding flows that consult the catalog directly. Co-authored-by: Cursor <[email protected]>
- Pin `@tencent-weixin/openclaw-weixin` to `2.4.1` and add `expectedIntegrity` so the third-party external catalog entry satisfies the `exact-with-integrity` policy enforced in `test/official-channel-catalog.test.ts`. - Add CHANGELOG entries for the install-records ledger fix in `channel-catalog-registry` and the new Weixin catalog entry. Co-authored-by: Cursor <[email protected]>
Importing `loadInstalledPluginIndexInstallRecordsSync` from `./installed-plugin-index-records.js` pulled in the store/config-state re-export chain, closing a runtime value cycle through `channels/bundled-channel-catalog-read.ts` -> `plugins/channel-catalog-registry.ts` -> `plugins/installed-plugin-index-records.ts` -> `plugins/installed-plugin-index-store.ts` -> `plugins/config-state.ts` -> `plugins/config-normalization-shared.ts` -> `channels/ids.ts` -> `channels/bundled-channel-catalog-read.ts`. That tripped `pnpm check:import-cycles` and produced module-init TDZ errors like `ReferenceError: Cannot access 'OFFICIAL_CHANNEL_CATALOG_RELATIVE_PATH' before initialization` across many CI shards. Switch the import to the lower-level `./installed-plugin-index-record-reader.js`, which only depends on filesystem helpers and path resolution, and update the unit-test mock target to match. Functional behaviour is unchanged; the same reader function is re-exported from the records module. Co-authored-by: Cursor <[email protected]>
60188c7 to
d06034b
Compare
|
Merged via squash.
Thanks @pumpkinxing1! |
Summary
listChannelCatalogEntriesinsrc/plugins/channel-catalog-registry.tscallsdiscoverOpenClawPluginswithout forwardinginstallRecords. As a result, channels installed viaopenclaw plugins install <npm-spec>are absent from the CLI channel catalog—openclaw channels add --channel <id>andopenclaw channels login --channel <id>reportUnsupported channel: <id>/Unknown channel: <id>even though the ledger entry under~/.openclaw/plugins/installs.jsonis healthy.stockdiscovery path and were unaffected, which masked the regression.listChannelCatalogEntriesnow lazy-loads the persisted plugin install ledger vialoadInstalledPluginIndexInstallRecordsSyncwhen the caller does not specifyorigin === "bundled", and forwards the records to discovery. Bundled-only callers continue to skip the disk read. Callers that already hold a record map can pass it via the new optionalinstallRecordsparameter to skip the lazy load. Reader errors fall back silently to "no install records" (no behavioural regression).discoverOpenClawPluginsconsumers (bundled-capability-runtime.ts,bundled-sources.ts,config-contracts.ts) are untouched—they target bundled-only paths or pre-load records elsewhere. No public manifest/contract types changed.manifest-registry.ts,loader.ts, andinstalled-plugin-index-registry.tswere already forwardinginstallRecordscorrectly; this PR only reaches feature parity for the channel-catalog-registry path.This PR also registers `@tencent-weixin/openclaw-weixin` in `scripts/lib/official-external-channel-catalog.json` so the channel appears in onboarding flows that consult the catalog directly (mirroring the WeCom and Yuanbao entries).
Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
Root Cause
Regression Test Plan
User-visible / Behavior Changes
Diagram
```text
Before:
channels add/login → listChannelCatalogEntries → discoverOpenClawPlugins({ workspaceDir, env })
^ no installRecords; npm-installed plugins invisible to catalog
After:
channels add/login → listChannelCatalogEntries
├─ if origin !== "bundled": loadInstalledPluginIndexInstallRecordsSync()
└─ discoverOpenClawPlugins({ workspaceDir, env, installRecords })
^ npm-installed plugins discoverable
```
Security Impact
Repro + Verification
Environment
Steps
Expected
Actual
Evidence
Human Verification
Review Conversations
Compatibility / Migration
Risks and Mitigations