mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 08:10:44 +00:00
fix(catalog): preserve channel ClawHub specs
This commit is contained in:
@@ -21,6 +21,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
- Plugins/externalization: pin beta-only official launch packages for ACPX, Google Chat, and LINE to explicit npm beta specs so catalog-driven installs do not trip the prerelease safety guard while npm `latest` still points at beta. Thanks @vincentkoc.
|
||||
- CLI/doctor: keep missing-plugin repair from overriding official catalog metadata with runtime fallbacks, so ACPX repairs preserve the beta npm spec during the externalization rollout. Thanks @vincentkoc.
|
||||
- Plugins/catalog: preserve ClawHub install specs when generating the packaged channel catalog so future storepack-first channel plugins keep their remote source instead of becoming npm-only. Thanks @vincentkoc.
|
||||
- Control UI/Talk: fix Talk (OpenAI Realtime WebRTC) CORS failure by stripping server-side-only attribution headers (`originator`, `version`, `User-Agent`) from browser offer headers; `api.openai.com/v1/realtime/calls` only allows `authorization` and `content-type` in its CORS preflight, so forwarding these headers caused the browser SDP exchange to fail. Fixes #76435. Thanks @hclsys.
|
||||
- CLI/logs: auto-reconnect `openclaw logs --follow` on transient gateway disconnects (WebSocket close, timeout, connection drop) with bounded exponential backoff (up to 8 retries, capped at 30 s) and stderr retry warnings, while still exiting immediately on non-recoverable auth or configuration errors. Fixes #74782. (#75059) Thanks @shashank-poola.
|
||||
- Plugins/onboarding: trust optional official plugin and web-search installs selected from the official catalog so npm security scanning treats them like other source-linked official install paths. Thanks @vincentkoc.
|
||||
|
||||
@@ -9,16 +9,20 @@ export const OFFICIAL_CHANNEL_CATALOG_RELATIVE_PATH = "dist/channel-catalog.json
|
||||
|
||||
function toCatalogInstall(value, packageName) {
|
||||
const install = isRecord(value) ? value : {};
|
||||
const clawhubSpec = trimString(install.clawhubSpec);
|
||||
const npmSpec = trimString(install.npmSpec) || packageName;
|
||||
if (!npmSpec) {
|
||||
if (!clawhubSpec && !npmSpec) {
|
||||
return null;
|
||||
}
|
||||
const defaultChoice = trimString(install.defaultChoice);
|
||||
const minHostVersion = trimString(install.minHostVersion);
|
||||
const expectedIntegrity = trimString(install.expectedIntegrity);
|
||||
return {
|
||||
npmSpec,
|
||||
...(defaultChoice === "npm" || defaultChoice === "local" ? { defaultChoice } : {}),
|
||||
...(clawhubSpec ? { clawhubSpec } : {}),
|
||||
...(npmSpec ? { npmSpec } : {}),
|
||||
...(defaultChoice === "clawhub" || defaultChoice === "npm" || defaultChoice === "local"
|
||||
? { defaultChoice }
|
||||
: {}),
|
||||
...(minHostVersion ? { minHostVersion } : {}),
|
||||
...(expectedIntegrity ? { expectedIntegrity } : {}),
|
||||
...(install.allowInvalidConfigRecovery === true ? { allowInvalidConfigRecovery: true } : {}),
|
||||
|
||||
@@ -168,6 +168,40 @@ describe("buildOfficialChannelCatalog", () => {
|
||||
expect(installSource.warnings).toEqual(["npm-spec-floating", "npm-spec-missing-integrity"]);
|
||||
});
|
||||
|
||||
it("preserves ClawHub specs when generating publishable channel catalog entries", () => {
|
||||
const repoRoot = makeRepoRoot("openclaw-official-channel-catalog-clawhub-");
|
||||
writeJson(path.join(repoRoot, "extensions", "storepack-chat", "package.json"), {
|
||||
name: "@openclaw/storepack-chat",
|
||||
openclaw: {
|
||||
channel: {
|
||||
id: "storepack-chat",
|
||||
label: "Storepack Chat",
|
||||
selectionLabel: "Storepack Chat",
|
||||
docsPath: "/channels/storepack-chat",
|
||||
blurb: "storepack-first channel",
|
||||
},
|
||||
install: {
|
||||
clawhubSpec: "clawhub:@openclaw/storepack-chat",
|
||||
npmSpec: "@openclaw/storepack-chat",
|
||||
defaultChoice: "clawhub",
|
||||
},
|
||||
release: {
|
||||
publishToNpm: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const entry = buildOfficialChannelCatalog({ repoRoot }).entries.find(
|
||||
(candidate) => candidate.openclaw?.channel?.id === "storepack-chat",
|
||||
);
|
||||
|
||||
expect(entry?.openclaw?.install).toEqual({
|
||||
clawhubSpec: "clawhub:@openclaw/storepack-chat",
|
||||
npmSpec: "@openclaw/storepack-chat",
|
||||
defaultChoice: "clawhub",
|
||||
});
|
||||
});
|
||||
|
||||
it("writes the official catalog under dist", () => {
|
||||
const repoRoot = makeRepoRoot("openclaw-official-channel-catalog-write-");
|
||||
writeJson(path.join(repoRoot, "extensions", "whatsapp", "package.json"), {
|
||||
|
||||
Reference in New Issue
Block a user