From a1e0c9ea0917842feaeed7939ac88ec14cdcedc3 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 27 Jul 2026 20:20:13 -0400 Subject: [PATCH] refactor(packages): DM-policy contract suite, dead routes, package folds (#114776) * test(channels): share DM policy contract suite * refactor(memory): remove dead host CLI routes * refactor(acp): use canonical normalization helpers * refactor(web): fold provider runtime into core * refactor(packages): remove dead runtime exports * chore(knip): drop retired ACP entry roots --- ...etwork-ssrf-boundary-critical-security.yml | 2 +- ...edia-runtime-boundary-critical-quality.yml | 2 +- .oxlintrc.json | 1 - config/knip.config.ts | 3 - extensions/discord/src/setup-surface.test.ts | 59 ++------ extensions/googlechat/src/setup.test.ts | 89 ++---------- extensions/imessage/src/targets.test.ts | 93 ++---------- extensions/line/src/setup-surface.test.ts | 107 ++------------ extensions/signal/src/core.test.ts | 89 ++---------- extensions/slack/src/setup-surface.test.ts | 61 ++------ extensions/telegram/src/setup-surface.test.ts | 87 ++--------- .../tsconfig.package-boundary.paths.json | 9 -- extensions/xai/tsconfig.json | 9 -- extensions/zalo/src/setup-surface.test.ts | 108 ++------------ extensions/zalouser/src/setup-surface.test.ts | 94 ++---------- packages/acp-core/package.json | 17 +-- packages/acp-core/src/index.ts | 3 - packages/acp-core/src/normalize-text.ts | 3 - packages/acp-core/src/numeric-options.ts | 11 -- packages/acp-core/src/record-shared.ts | 3 - .../src/runtime/session-identifiers.ts | 6 +- .../acp-core/src/runtime/session-identity.ts | 2 +- packages/acp-core/src/session.ts | 2 +- packages/memory-host-sdk/package.json | 2 - packages/memory-host-sdk/src/engine.ts | 7 - .../src/host/openclaw-runtime-cli.ts | 19 --- .../src/host/openclaw-runtime.ts | 8 - packages/memory-host-sdk/src/runtime-cli.ts | 11 -- packages/web-content-core/package.json | 19 --- pnpm-lock.yaml | 2 - scripts/run-node-watch-paths.mjs | 1 - src/acp/approval-classifier.ts | 2 +- src/acp/control-plane/runtime-options.ts | 8 +- src/acp/event-ledger.ts | 2 +- src/acp/event-mapper.ts | 2 +- src/acp/persistent-bindings.types.ts | 8 +- src/agents/tools/web-fetch.ts | 2 +- src/plugin-sdk/channel-test-helpers.ts | 1 + .../test-helpers/channel-contract-suites.ts | 137 ++++++++++++++++++ ...tension-package-project-boundaries.test.ts | 3 - .../contracts/plugin-sdk-subpaths.test.ts | 1 - src/plugins/sdk-alias.test.ts | 3 - src/web-fetch/runtime.ts | 14 +- src/web-search/runtime.ts | 12 +- .../web}/provider-runtime-shared.test.ts | 2 +- .../web}/provider-runtime-shared.ts | 4 +- test/scripts/oxlint-config.test.ts | 1 - tsconfig.json | 7 - tsdown.config.ts | 3 - 49 files changed, 288 insertions(+), 853 deletions(-) delete mode 100644 packages/acp-core/src/normalize-text.ts delete mode 100644 packages/acp-core/src/numeric-options.ts delete mode 100644 packages/acp-core/src/record-shared.ts delete mode 100644 packages/memory-host-sdk/src/engine.ts delete mode 100644 packages/memory-host-sdk/src/host/openclaw-runtime-cli.ts delete mode 100644 packages/memory-host-sdk/src/runtime-cli.ts delete mode 100644 packages/web-content-core/package.json rename {packages/web-content-core/src => src/web}/provider-runtime-shared.test.ts (97%) rename {packages/web-content-core/src => src/web}/provider-runtime-shared.ts (98%) diff --git a/.github/codeql/codeql-network-ssrf-boundary-critical-security.yml b/.github/codeql/codeql-network-ssrf-boundary-critical-security.yml index 9eb01f78fafa..32e817b4f8c6 100644 --- a/.github/codeql/codeql-network-ssrf-boundary-critical-security.yml +++ b/.github/codeql/codeql-network-ssrf-boundary-critical-security.yml @@ -20,7 +20,7 @@ paths: - src/agents/tools/web-shared.ts - src/plugin-sdk/ssrf-policy.ts - src/web-fetch - - packages/web-content-core/src/provider-runtime-shared.ts + - src/web/provider-runtime-shared.ts - packages/memory-host-sdk/src/host/ssrf-policy.ts - packages/net-policy/src diff --git a/.github/codeql/codeql-web-media-runtime-boundary-critical-quality.yml b/.github/codeql/codeql-web-media-runtime-boundary-critical-quality.yml index 6cfa5331198c..a805a8844d35 100644 --- a/.github/codeql/codeql-web-media-runtime-boundary-critical-quality.yml +++ b/.github/codeql/codeql-web-media-runtime-boundary-critical-quality.yml @@ -16,7 +16,7 @@ query-filters: paths: - src/web-fetch - src/web-search - - packages/web-content-core/src/provider-runtime-shared.ts + - src/web/provider-runtime-shared.ts - src/media - src/media-understanding - src/image-generation diff --git a/.oxlintrc.json b/.oxlintrc.json index 62d4682d4f1e..b69b28663e19 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -243,7 +243,6 @@ "packages/terminal-core/**/*.ts", "packages/normalization-core/**/*.ts", "packages/model-catalog-core/**/*.ts", - "packages/web-content-core/**/*.ts", "packages/agent-core/**/*.ts", "packages/acp-core/**/*.ts", "packages/ai/**/*.ts", diff --git a/config/knip.config.ts b/config/knip.config.ts index bdacb1f0ff37..4a94979bf809 100644 --- a/config/knip.config.ts +++ b/config/knip.config.ts @@ -562,10 +562,7 @@ const config = { "packages/acp-core": { entry: [ "src/index.ts!", - "src/normalize-text.ts!", "src/meta.ts!", - "src/numeric-options.ts!", - "src/record-shared.ts!", "src/session.ts!", "src/session-interaction-mode.ts!", "src/session-lineage-meta.ts!", diff --git a/extensions/discord/src/setup-surface.test.ts b/extensions/discord/src/setup-surface.test.ts index 05cfd8ab4a0e..d7453a2c3f2b 100644 --- a/extensions/discord/src/setup-surface.test.ts +++ b/extensions/discord/src/setup-surface.test.ts @@ -1,4 +1,5 @@ // Discord tests cover setup surface plugin behavior. +import { installChannelDmPolicyContractSuite } from "openclaw/plugin-sdk/channel-test-helpers"; import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts"; import { describe, expect, it } from "vitest"; import { createDiscordSetupWizardBase } from "./setup-core.js"; @@ -19,55 +20,17 @@ const discordSetupWizard = createDiscordSetupWizardBase({ }); describe("discordSetupWizard.dmPolicy", () => { - it("reads the named-account DM policy instead of the channel root", () => { - expect( - discordSetupWizard.dmPolicy?.getCurrent( - { - channels: { - discord: { - dmPolicy: "disabled", - accounts: { - alerts: { - dmPolicy: "allowlist", - token: "discord-token", - }, - }, - }, - }, - } as OpenClawConfig, - "alerts", - ), - ).toBe("allowlist"); - }); - - it("reports account-scoped config keys for named accounts", () => { - expect(discordSetupWizard.dmPolicy?.resolveConfigKeys?.({}, "alerts")).toEqual({ - policyKey: "channels.discord.accounts.alerts.dmPolicy", - allowFromKey: "channels.discord.accounts.alerts.allowFrom", - }); - }); - - it('writes open policy state to the named account and preserves inherited allowFrom with "*"', () => { - const next = discordSetupWizard.dmPolicy?.setPolicy( + installChannelDmPolicyContractSuite({ + dmPolicy: discordSetupWizard.dmPolicy!, + cases: [ { - channels: { - discord: { - allowFrom: ["123"], - accounts: { - alerts: { - token: "discord-token", - }, - }, - }, - }, - } as OpenClawConfig, - "open", - "alerts", - ); - - expect(next?.channels?.discord?.dmPolicy).toBeUndefined(); - expect(next?.channels?.discord?.accounts?.alerts?.dmPolicy).toBe("open"); - expect(next?.channels?.discord?.accounts?.alerts?.allowFrom).toEqual(["123", "*"]); + name: "Discord named accounts", + channel: "discord", + accountId: "alerts", + accountConfig: { token: "discord-token" }, + inheritedAllowFrom: ["123"], + }, + ], }); }); diff --git a/extensions/googlechat/src/setup.test.ts b/extensions/googlechat/src/setup.test.ts index 444bc14655cd..bc17d87bfbb2 100644 --- a/extensions/googlechat/src/setup.test.ts +++ b/extensions/googlechat/src/setup.test.ts @@ -6,6 +6,7 @@ import { createStartAccountContext, expectLifecyclePatch, expectPendingUntilAbort, + installChannelDmPolicyContractSuite, startAccountAndTrackLifecycle, } from "openclaw/plugin-sdk/channel-test-helpers"; import { @@ -252,25 +253,18 @@ describe("googlechat setup", () => { expect(result.cfg.channels?.googlechat?.audience).toBe("https://example.com/googlechat"); }); - it("reads the named-account DM policy instead of the channel root", () => { - expect( - googlechatSetupWizard.dmPolicy?.getCurrent( - { - channels: { - googlechat: { - dmPolicy: "disabled", - accounts: { - alerts: { - serviceAccount: { client_email: "bot@example.com" }, - dmPolicy: "allowlist", - }, - }, - }, - }, - } as OpenClawConfig, - "alerts", - ), - ).toBe("allowlist"); + installChannelDmPolicyContractSuite({ + dmPolicy: googlechatSetupWizard.dmPolicy!, + cases: [ + { + name: "Google Chat named accounts", + channel: "googlechat", + accountId: "alerts", + accountConfig: { serviceAccount: { client_email: "bot@example.com" } }, + inheritedAllowFrom: ["users/123"], + defaultAccount: {}, + }, + ], }); it("reports configured state for the selected account instead of any account", async () => { @@ -318,40 +312,6 @@ describe("googlechat setup", () => { expect(status.configured).toBe(false); }); - it("reports account-scoped config keys for named accounts", () => { - expect(googlechatSetupWizard.dmPolicy?.resolveConfigKeys?.({}, "alerts")).toEqual({ - policyKey: "channels.googlechat.accounts.alerts.dmPolicy", - allowFromKey: "channels.googlechat.accounts.alerts.allowFrom", - }); - }); - - it("uses configured defaultAccount for omitted DM policy account context", () => { - const cfg = { - channels: { - googlechat: { - defaultAccount: "alerts", - dmPolicy: "disabled", - accounts: { - alerts: { - serviceAccount: { client_email: "bot@example.com" }, - dmPolicy: "allowlist", - }, - }, - }, - }, - } as OpenClawConfig; - - expect(googlechatSetupWizard.dmPolicy?.getCurrent(cfg)).toBe("allowlist"); - expect(googlechatSetupWizard.dmPolicy?.resolveConfigKeys?.(cfg)).toEqual({ - policyKey: "channels.googlechat.accounts.alerts.dmPolicy", - allowFromKey: "channels.googlechat.accounts.alerts.allowFrom", - }); - - const next = googlechatSetupWizard.dmPolicy?.setPolicy(cfg, "open"); - expect(next?.channels?.googlechat?.dmPolicy).toBe("disabled"); - expect(next?.channels?.googlechat?.accounts?.alerts?.dmPolicy).toBe("open"); - }); - it("uses configured defaultAccount for omitted allowFrom prompt context", async () => { const prompter = createTestWizardPrompter({ note: vi.fn(async () => {}), @@ -380,29 +340,6 @@ describe("googlechat setup", () => { expect(next?.channels?.googlechat?.accounts?.alerts?.allowFrom).toEqual(["users/123456789"]); }); - it('writes open DM policy to the named account and preserves inherited allowFrom with "*"', () => { - const next = googlechatSetupWizard.dmPolicy?.setPolicy( - { - channels: { - googlechat: { - allowFrom: ["users/123"], - accounts: { - alerts: { - serviceAccount: { client_email: "bot@example.com" }, - }, - }, - }, - }, - } as OpenClawConfig, - "open", - "alerts", - ); - - expect(next?.channels?.googlechat?.dmPolicy).toBeUndefined(); - expect(next?.channels?.googlechat?.accounts?.alerts?.dmPolicy).toBe("open"); - expect(next?.channels?.googlechat?.accounts?.alerts?.allowFrom).toEqual(["users/123", "*"]); - }); - it("keeps startAccount pending until abort, then unregisters", async () => { const unregister = vi.fn(); hoisted.startGoogleChatMonitor.mockResolvedValue(unregister); diff --git a/extensions/imessage/src/targets.test.ts b/extensions/imessage/src/targets.test.ts index d584c77a2c36..b01fbf263ea7 100644 --- a/extensions/imessage/src/targets.test.ts +++ b/extensions/imessage/src/targets.test.ts @@ -1,5 +1,6 @@ -import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts"; // Imessage tests cover targets plugin behavior. +import { installChannelDmPolicyContractSuite } from "openclaw/plugin-sdk/channel-test-helpers"; +import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts"; import { describe, expect, it } from "vitest"; import { resolveIMessageGroupRequireMention, @@ -254,86 +255,20 @@ describe("parseIMessageAllowFromEntries", () => { }); }); - it("reads the named-account DM policy instead of the channel root", () => { - expect( - imessageDmPolicy.getCurrent( - { - channels: { - imessage: { - dmPolicy: "disabled", - accounts: { - work: { - cliPath: "imsg", - dmPolicy: "allowlist", - }, - }, - }, - }, - }, - "work", - ), - ).toBe("allowlist"); - }); - - it("reports account-scoped config keys for named accounts", () => { - expect(imessageDmPolicy.resolveConfigKeys?.({ channels: { imessage: {} } }, "work")).toEqual({ - policyKey: "channels.imessage.accounts.work.dmPolicy", - allowFromKey: "channels.imessage.accounts.work.allowFrom", - }); - }); - - it('writes open policy state to the named account and stores inherited allowFrom with "*"', () => { - const next = imessageDmPolicy.setPolicy( + installChannelDmPolicyContractSuite({ + dmPolicy: imessageDmPolicy, + cases: [ { - channels: { - imessage: { - allowFrom: ["+15555550123"], - accounts: { - work: { - cliPath: "imsg", - }, - }, - }, + name: "iMessage named accounts", + channel: "imessage", + accountId: "work", + accountConfig: { cliPath: "imsg" }, + inheritedAllowFrom: ["+15555550123"], + defaultAccount: { + rootAllowFrom: ["+15555550123"], + accountAllowFrom: ["chat_id:123"], }, }, - "open", - "work", - ); - - expect(next.channels?.imessage?.dmPolicy).toBeUndefined(); - expect(next.channels?.imessage?.allowFrom).toEqual(["+15555550123"]); - expect(next.channels?.imessage?.accounts?.work?.dmPolicy).toBe("open"); - expect(next.channels?.imessage?.accounts?.work?.allowFrom).toEqual(["+15555550123", "*"]); - }); - - it("uses the configured default account for omitted-account DM policy reads, keys, and writes", () => { - const cfg = { - channels: { - imessage: { - allowFrom: ["+15555550123"], - defaultAccount: "work", - accounts: { - work: { - cliPath: "imsg", - dmPolicy: "allowlist" as const, - allowFrom: ["chat_id:123"], - }, - }, - }, - }, - }; - - expect(imessageDmPolicy.getCurrent(cfg)).toBe("allowlist"); - expect(imessageDmPolicy.resolveConfigKeys?.(cfg)).toEqual({ - policyKey: "channels.imessage.accounts.work.dmPolicy", - allowFromKey: "channels.imessage.accounts.work.allowFrom", - }); - - const next = imessageDmPolicy.setPolicy(cfg, "open"); - - expect(next.channels?.imessage?.dmPolicy).toBeUndefined(); - expect(next.channels?.imessage?.allowFrom).toEqual(["+15555550123"]); - expect(next.channels?.imessage?.accounts?.work?.dmPolicy).toBe("open"); - expect(next.channels?.imessage?.accounts?.work?.allowFrom).toEqual(["chat_id:123", "*"]); + ], }); }); diff --git a/extensions/line/src/setup-surface.test.ts b/extensions/line/src/setup-surface.test.ts index fb0c265ab355..db8b8996fb45 100644 --- a/extensions/line/src/setup-surface.test.ts +++ b/extensions/line/src/setup-surface.test.ts @@ -1,7 +1,10 @@ // Line tests cover setup surface plugin behavior. import { readFileSync } from "node:fs"; import path from "node:path"; -import { createStartAccountContext } from "openclaw/plugin-sdk/channel-test-helpers"; +import { + createStartAccountContext, + installChannelDmPolicyContractSuite, +} from "openclaw/plugin-sdk/channel-test-helpers"; import { createPluginSetupWizardConfigure, createTestWizardPrompter, @@ -186,98 +189,18 @@ describe("line setup wizard", () => { expect(result.cfg.channels?.line?.channelSecret).toBe("line-secret"); }); - it("reads the named-account DM policy instead of the channel root", () => { - expect( - lineSetupWizard.dmPolicy?.getCurrent( - { - channels: { - line: { - dmPolicy: "disabled", - accounts: { - work: { - channelAccessToken: "token", - channelSecret: "secret", - dmPolicy: "allowlist", - }, - }, - }, - }, - } as OpenClawConfig, - "work", - ), - ).toBe("allowlist"); - }); - - it("reports account-scoped config keys for named accounts", () => { - expect(lineSetupWizard.dmPolicy?.resolveConfigKeys?.({} as OpenClawConfig, "work")).toEqual({ - policyKey: "channels.line.accounts.work.dmPolicy", - allowFromKey: "channels.line.accounts.work.allowFrom", - }); - }); - - it("uses configured defaultAccount for omitted DM policy account context", () => { - const cfg = { - channels: { - line: { - defaultAccount: "work", - dmPolicy: "disabled", - allowFrom: ["Uroot"], - accounts: { - work: { - channelAccessToken: "token", - channelSecret: "secret", - dmPolicy: "allowlist", - }, - }, - }, - }, - } as OpenClawConfig; - - expect(lineSetupWizard.dmPolicy?.getCurrent(cfg)).toBe("allowlist"); - expect(lineSetupWizard.dmPolicy?.resolveConfigKeys?.(cfg)).toEqual({ - policyKey: "channels.line.accounts.work.dmPolicy", - allowFromKey: "channels.line.accounts.work.allowFrom", - }); - - const next = lineSetupWizard.dmPolicy?.setPolicy(cfg, "open"); - const workAccount = next?.channels?.line?.accounts?.work as - | { - dmPolicy?: string; - } - | undefined; - expect(next?.channels?.line?.dmPolicy).toBe("disabled"); - expect(workAccount?.dmPolicy).toBe("open"); - }); - - it('writes open policy state to the named account and preserves inherited allowFrom with "*"', () => { - const next = lineSetupWizard.dmPolicy?.setPolicy( + installChannelDmPolicyContractSuite({ + dmPolicy: lineSetupWizard.dmPolicy!, + cases: [ { - channels: { - line: { - allowFrom: ["Uroot"], - accounts: { - work: { - channelAccessToken: "token", - channelSecret: "secret", - }, - }, - }, - }, - } as OpenClawConfig, - "open", - "work", - ); - - const workAccount = next?.channels?.line?.accounts?.work as - | { - dmPolicy?: string; - allowFrom?: string[]; - } - | undefined; - expect(next?.channels?.line?.dmPolicy).toBeUndefined(); - expect(next?.channels?.line?.allowFrom).toEqual(["Uroot"]); - expect(workAccount?.dmPolicy).toBe("open"); - expect(workAccount?.allowFrom).toEqual(["Uroot", "*"]); + name: "LINE named accounts", + channel: "line", + accountId: "work", + accountConfig: { channelAccessToken: "token", channelSecret: "secret" }, + inheritedAllowFrom: ["Uroot"], + defaultAccount: { rootAllowFrom: ["Uroot"] }, + }, + ], }); it("uses configured defaultAccount for omitted setup configured state", async () => { diff --git a/extensions/signal/src/core.test.ts b/extensions/signal/src/core.test.ts index eece4ee04f8c..1f58c8b71e6b 100644 --- a/extensions/signal/src/core.test.ts +++ b/extensions/signal/src/core.test.ts @@ -4,6 +4,7 @@ import { createMessageReceiptFromOutboundResults, verifyChannelMessageAdapterCapabilityProofs, } from "openclaw/plugin-sdk/channel-outbound"; +import { installChannelDmPolicyContractSuite } from "openclaw/plugin-sdk/channel-test-helpers"; import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts"; import { createPluginSetupWizardStatus, @@ -1270,84 +1271,18 @@ describe("signal setup parsing", () => { ]); }); - it("reads the named-account DM policy instead of the channel root", () => { - expect( - signalDmPolicy.getCurrent( - { - channels: { - signal: { - dmPolicy: "disabled", - accounts: { - work: { - account: "+15555550123", - dmPolicy: "allowlist", - }, - }, - }, - }, - }, - "work", - ), - ).toBe("allowlist"); - }); - - it("reports account-scoped config keys for named accounts", () => { - expect(signalDmPolicy.resolveConfigKeys?.({ channels: { signal: {} } }, "work")).toEqual({ - policyKey: "channels.signal.accounts.work.dmPolicy", - allowFromKey: "channels.signal.accounts.work.allowFrom", - }); - }); - - it("uses configured defaultAccount for omitted DM policy account context", () => { - const cfg: OpenClawConfig = { - channels: { - signal: { - defaultAccount: "work", - dmPolicy: "disabled", - allowFrom: ["+15555550123"], - accounts: { - work: { - account: "+15555550999", - dmPolicy: "allowlist", - }, - }, - }, + installChannelDmPolicyContractSuite({ + dmPolicy: signalDmPolicy, + cases: [ + { + name: "Signal named accounts", + channel: "signal", + accountId: "work", + accountConfig: { account: "+15555550999" }, + inheritedAllowFrom: ["+15555550123"], + defaultAccount: { rootAllowFrom: ["+15555550123"] }, }, - }; - - expect(signalDmPolicy.getCurrent(cfg)).toBe("allowlist"); - expect(signalDmPolicy.resolveConfigKeys?.(cfg)).toEqual({ - policyKey: "channels.signal.accounts.work.dmPolicy", - allowFromKey: "channels.signal.accounts.work.allowFrom", - }); - - const next = signalDmPolicy.setPolicy(cfg, "open"); - expect(next.channels?.signal?.dmPolicy).toBe("disabled"); - expect(next.channels?.signal?.allowFrom).toEqual(["+15555550123"]); - expect(next.channels?.signal?.accounts?.work?.dmPolicy).toBe("open"); - expect(next.channels?.signal?.accounts?.work?.allowFrom).toEqual(["+15555550123", "*"]); - }); - - it('writes open policy state to the named account and stores inherited allowFrom with "*"', () => { - const cfg: OpenClawConfig = { - channels: { - signal: { - allowFrom: ["+15555550123"], - accounts: { - work: { - account: "+15555550999", - }, - }, - }, - }, - }; - - const next = signalDmPolicy.setPolicy(cfg, "open", "work"); - - expect(next.channels?.signal?.dmPolicy).toBeUndefined(); - expect(next.channels?.signal?.allowFrom).toEqual(["+15555550123"]); - expect(next.channels?.signal?.accounts?.work?.dmPolicy).toBe("open"); - expect(next.channels?.signal?.accounts?.work?.allowFrom).toEqual(["+15555550123", "*"]); + ], }); }); /* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */ diff --git a/extensions/slack/src/setup-surface.test.ts b/extensions/slack/src/setup-surface.test.ts index c0df5ee2a2b5..98fd99754992 100644 --- a/extensions/slack/src/setup-surface.test.ts +++ b/extensions/slack/src/setup-surface.test.ts @@ -1,3 +1,4 @@ +import { installChannelDmPolicyContractSuite } from "openclaw/plugin-sdk/channel-test-helpers"; // Slack tests cover setup surface plugin behavior. import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts"; import { @@ -427,57 +428,17 @@ describe("slackSetupWizard.prepare", () => { }); describe("slackSetupWizard.dmPolicy", () => { - it("reads the named-account DM policy instead of the channel root", () => { - expect( - slackSetupWizard.dmPolicy?.getCurrent( - { - channels: { - slack: { - dmPolicy: "disabled", - accounts: { - alerts: { - dmPolicy: "allowlist", - botToken: "xoxb-alerts", - appToken: "xapp-alerts", - }, - }, - }, - }, - } as OpenClawConfig, - "alerts", - ), - ).toBe("allowlist"); - }); - - it("reports account-scoped config keys for named accounts", () => { - expect(slackSetupWizard.dmPolicy?.resolveConfigKeys?.({}, "alerts")).toEqual({ - policyKey: "channels.slack.accounts.alerts.dmPolicy", - allowFromKey: "channels.slack.accounts.alerts.allowFrom", - }); - }); - - it('writes open policy state to the named account and preserves inherited allowFrom with "*"', () => { - const next = slackSetupWizard.dmPolicy?.setPolicy( + installChannelDmPolicyContractSuite({ + dmPolicy: slackSetupWizard.dmPolicy!, + cases: [ { - channels: { - slack: { - allowFrom: ["U123"], - accounts: { - alerts: { - botToken: "xoxb-alerts", - appToken: "xapp-alerts", - }, - }, - }, - }, - } as OpenClawConfig, - "open", - "alerts", - ); - - expect(next?.channels?.slack?.dmPolicy).toBeUndefined(); - expect(next?.channels?.slack?.accounts?.alerts?.dmPolicy).toBe("open"); - expect(next?.channels?.slack?.accounts?.alerts?.allowFrom).toEqual(["U123", "*"]); + name: "Slack named accounts", + channel: "slack", + accountId: "alerts", + accountConfig: { botToken: "xoxb-alerts", appToken: "xapp-alerts" }, + inheritedAllowFrom: ["U123"], + }, + ], }); }); diff --git a/extensions/telegram/src/setup-surface.test.ts b/extensions/telegram/src/setup-surface.test.ts index 3233eef2db9d..e3f20801160c 100644 --- a/extensions/telegram/src/setup-surface.test.ts +++ b/extensions/telegram/src/setup-surface.test.ts @@ -1,5 +1,5 @@ // Telegram tests cover setup surface plugin behavior. -import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts"; +import { installChannelDmPolicyContractSuite } from "openclaw/plugin-sdk/channel-test-helpers"; import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/setup"; import { describe, expect, it, vi } from "vitest"; import { promptTelegramAllowFromForAccount, telegramSetupAdapter } from "./setup-core.js"; @@ -98,81 +98,18 @@ describe("telegram DM access warning helpers", () => { }); describe("telegramSetupDmPolicy", () => { - it("reads the named-account DM policy instead of the channel root", () => { - expect( - telegramSetupDmPolicy.getCurrent?.( - { - channels: { - telegram: { - dmPolicy: "disabled", - accounts: { - alerts: { - dmPolicy: "allowlist", - botToken: "tok", - }, - }, - }, - }, - }, - "alerts", - ), - ).toBe("allowlist"); - }); - - it("reports account-scoped config keys for named accounts", () => { - expect(telegramSetupDmPolicy.resolveConfigKeys?.({}, "alerts")).toEqual({ - policyKey: "channels.telegram.accounts.alerts.dmPolicy", - allowFromKey: "channels.telegram.accounts.alerts.allowFrom", - }); - }); - - it("uses configured defaultAccount for omitted DM policy account context", () => { - const cfg: OpenClawConfig = { - channels: { - telegram: { - defaultAccount: "alerts", - dmPolicy: "disabled", - allowFrom: ["123"], - accounts: { - alerts: { - dmPolicy: "allowlist", - botToken: "tok", - }, - }, - }, + installChannelDmPolicyContractSuite({ + dmPolicy: telegramSetupDmPolicy, + cases: [ + { + name: "Telegram named accounts", + channel: "telegram", + accountId: "alerts", + accountConfig: { botToken: "tok" }, + inheritedAllowFrom: ["123"], + defaultAccount: { rootAllowFrom: ["123"] }, }, - }; - - expect(telegramSetupDmPolicy.getCurrent?.(cfg)).toBe("allowlist"); - expect(telegramSetupDmPolicy.resolveConfigKeys?.(cfg)).toEqual({ - policyKey: "channels.telegram.accounts.alerts.dmPolicy", - allowFromKey: "channels.telegram.accounts.alerts.allowFrom", - }); - - const next = telegramSetupDmPolicy.setPolicy?.(cfg, "open"); - expect(next?.channels?.telegram?.dmPolicy).toBe("disabled"); - expect(next?.channels?.telegram?.accounts?.alerts?.dmPolicy).toBe("open"); - }); - - it('writes open policy state to the named account and preserves inherited allowFrom with "*"', () => { - const cfg: OpenClawConfig = { - channels: { - telegram: { - allowFrom: ["123"], - accounts: { - alerts: { - botToken: "tok", - }, - }, - }, - }, - }; - - const next = telegramSetupDmPolicy.setPolicy?.(cfg, "open", "alerts"); - - expect(next?.channels?.telegram?.dmPolicy).toBeUndefined(); - expect(next?.channels?.telegram?.accounts?.alerts?.dmPolicy).toBe("open"); - expect(next?.channels?.telegram?.accounts?.alerts?.allowFrom).toEqual(["123", "*"]); + ], }); }); diff --git a/extensions/tsconfig.package-boundary.paths.json b/extensions/tsconfig.package-boundary.paths.json index 5061818d7993..099a44ce7b64 100644 --- a/extensions/tsconfig.package-boundary.paths.json +++ b/extensions/tsconfig.package-boundary.paths.json @@ -752,18 +752,9 @@ "@openclaw/acp-core": [ "../dist/plugin-sdk/packages/acp-core/src/index.d.ts" ], - "@openclaw/acp-core/normalize-text": [ - "../dist/plugin-sdk/packages/acp-core/src/normalize-text.d.ts" - ], "@openclaw/acp-core/meta": [ "../dist/plugin-sdk/packages/acp-core/src/meta.d.ts" ], - "@openclaw/acp-core/numeric-options": [ - "../dist/plugin-sdk/packages/acp-core/src/numeric-options.d.ts" - ], - "@openclaw/acp-core/record-shared": [ - "../dist/plugin-sdk/packages/acp-core/src/record-shared.d.ts" - ], "@openclaw/acp-core/session": [ "../dist/plugin-sdk/packages/acp-core/src/session.d.ts" ], diff --git a/extensions/xai/tsconfig.json b/extensions/xai/tsconfig.json index 885512cd2dd8..072b7680aab5 100644 --- a/extensions/xai/tsconfig.json +++ b/extensions/xai/tsconfig.json @@ -732,18 +732,9 @@ "@openclaw/acp-core": [ "../../dist/plugin-sdk/packages/acp-core/src/index.d.ts" ], - "@openclaw/acp-core/normalize-text": [ - "../../dist/plugin-sdk/packages/acp-core/src/normalize-text.d.ts" - ], "@openclaw/acp-core/meta": [ "../../dist/plugin-sdk/packages/acp-core/src/meta.d.ts" ], - "@openclaw/acp-core/numeric-options": [ - "../../dist/plugin-sdk/packages/acp-core/src/numeric-options.d.ts" - ], - "@openclaw/acp-core/record-shared": [ - "../../dist/plugin-sdk/packages/acp-core/src/record-shared.d.ts" - ], "@openclaw/acp-core/session": [ "../../dist/plugin-sdk/packages/acp-core/src/session.d.ts" ], diff --git a/extensions/zalo/src/setup-surface.test.ts b/extensions/zalo/src/setup-surface.test.ts index 20b9fa1dc3bc..444a4905157c 100644 --- a/extensions/zalo/src/setup-surface.test.ts +++ b/extensions/zalo/src/setup-surface.test.ts @@ -1,5 +1,6 @@ // Zalo tests cover setup surface plugin behavior. import { adaptScopedAccountAccessor } from "openclaw/plugin-sdk/channel-config-helpers"; +import { installChannelDmPolicyContractSuite } from "openclaw/plugin-sdk/channel-test-helpers"; import { createPluginSetupWizardConfigure, createTestWizardPrompter, @@ -70,103 +71,18 @@ describe("zalo setup wizard", () => { expect(zaloConfig.webhookUrl).toBeUndefined(); }); - it("reads the named-account DM policy instead of the channel root", () => { - expect( - zaloDmPolicy.getCurrent( - { - channels: { - zalo: { - dmPolicy: "disabled", - accounts: { - work: { - botToken: "12345689:abc-xyz", - dmPolicy: "allowlist", - }, - }, - }, - }, - } as OpenClawConfig, - "work", - ), - ).toBe("allowlist"); - }); - - it("reports account-scoped config keys for named accounts", () => { - expect(zaloDmPolicy.resolveConfigKeys?.({} as OpenClawConfig, "work")).toEqual({ - policyKey: "channels.zalo.accounts.work.dmPolicy", - allowFromKey: "channels.zalo.accounts.work.allowFrom", - }); - }); - - it("uses configured defaultAccount for omitted DM policy account context", () => { - const cfg = { - channels: { - zalo: { - defaultAccount: "work", - dmPolicy: "disabled", - allowFrom: ["123456789"], - accounts: { - work: { - botToken: "12345689:abc-xyz", - dmPolicy: "allowlist", - }, - }, - }, - }, - } as OpenClawConfig; - - expect(zaloDmPolicy.getCurrent(cfg)).toBe("allowlist"); - expect(zaloDmPolicy.resolveConfigKeys?.(cfg)).toEqual({ - policyKey: "channels.zalo.accounts.work.dmPolicy", - allowFromKey: "channels.zalo.accounts.work.allowFrom", - }); - - const next = zaloDmPolicy.setPolicy(cfg, "open"); - const zaloConfig = next.channels?.zalo; - if (!zaloConfig) { - throw new Error("expected Zalo config"); - } - expect(zaloConfig.dmPolicy).toBe("disabled"); - const workAccount = next.channels?.zalo?.accounts?.work as - | { dmPolicy?: string; allowFrom?: Array } - | undefined; - if (!workAccount) { - throw new Error("expected Zalo work account"); - } - expect(workAccount.dmPolicy).toBe("open"); - }); - - it('writes open policy state to the named account and preserves inherited allowFrom with "*"', () => { - const next = zaloDmPolicy.setPolicy( + installChannelDmPolicyContractSuite({ + dmPolicy: zaloDmPolicy, + cases: [ { - channels: { - zalo: { - allowFrom: ["123456789"], - accounts: { - work: { - botToken: "12345689:abc-xyz", - }, - }, - }, - }, - } as OpenClawConfig, - "open", - "work", - ); - - const zaloConfig = next.channels?.zalo; - if (!zaloConfig) { - throw new Error("expected Zalo config"); - } - expect(zaloConfig.dmPolicy).toBeUndefined(); - const workAccount = next.channels?.zalo?.accounts?.work as - | { dmPolicy?: string; allowFrom?: Array } - | undefined; - if (!workAccount) { - throw new Error("expected Zalo work account"); - } - expect(workAccount.dmPolicy).toBe("open"); - expect(workAccount.allowFrom).toEqual(["123456789", "*"]); + name: "Zalo named accounts", + channel: "zalo", + accountId: "work", + accountConfig: { botToken: "12345689:abc-xyz" }, + inheritedAllowFrom: ["123456789"], + defaultAccount: { rootAllowFrom: ["123456789"] }, + }, + ], }); it("uses configured defaultAccount for omitted setup configured state", async () => { diff --git a/extensions/zalouser/src/setup-surface.test.ts b/extensions/zalouser/src/setup-surface.test.ts index 63a529573767..aa5ad31cd6ab 100644 --- a/extensions/zalouser/src/setup-surface.test.ts +++ b/extensions/zalouser/src/setup-surface.test.ts @@ -1,4 +1,5 @@ // Zalouser tests cover setup surface plugin behavior. +import { installChannelDmPolicyContractSuite } from "openclaw/plugin-sdk/channel-test-helpers"; import { createPluginSetupWizardConfigure, createTestWizardPrompter, @@ -374,91 +375,18 @@ describe("zalouser setup wizard", () => { expect(result.cfg.plugins?.allow).toEqual(["telegram", "zalouser"]); }); - it("reads the named-account DM policy instead of the channel root", () => { - expect( - zalouserSetupWizard.dmPolicy?.getCurrent( - { - channels: { - zalouser: { - dmPolicy: "disabled", - accounts: { - work: { - profile: "work", - dmPolicy: "allowlist", - }, - }, - }, - }, - } as OpenClawConfig, - "work", - ), - ).toBe("allowlist"); - }); - - it("reports account-scoped config keys for named accounts", () => { - expect(zalouserSetupWizard.dmPolicy?.resolveConfigKeys?.({} as OpenClawConfig, "work")).toEqual( + installChannelDmPolicyContractSuite({ + dmPolicy: zalouserSetupWizard.dmPolicy!, + cases: [ { - policyKey: "channels.zalouser.accounts.work.dmPolicy", - allowFromKey: "channels.zalouser.accounts.work.allowFrom", + name: "Zalo Personal named accounts", + channel: "zalouser", + accountId: "work", + accountConfig: { profile: "work" }, + inheritedAllowFrom: ["123456789"], + defaultAccount: { rootAllowFrom: ["123456789"] }, }, - ); - }); - - it("uses configured defaultAccount for omitted DM policy account context", () => { - const cfg = { - channels: { - zalouser: { - defaultAccount: "work", - dmPolicy: "disabled", - allowFrom: ["123456789"], - accounts: { - work: { - dmPolicy: "allowlist", - profile: "work-profile", - }, - }, - }, - }, - } as OpenClawConfig; - - expect(zalouserSetupWizard.dmPolicy?.getCurrent(cfg)).toBe("allowlist"); - expect(zalouserSetupWizard.dmPolicy?.resolveConfigKeys?.(cfg)).toEqual({ - policyKey: "channels.zalouser.accounts.work.dmPolicy", - allowFromKey: "channels.zalouser.accounts.work.allowFrom", - }); - - const next = zalouserSetupWizard.dmPolicy?.setPolicy(cfg, "open"); - expect(next?.channels?.zalouser?.dmPolicy).toBe("disabled"); - const workAccount = next?.channels?.zalouser?.accounts?.work as - | { dmPolicy?: string; allowFrom?: Array } - | undefined; - expect(workAccount?.dmPolicy).toBe("open"); - }); - - it('writes open policy state to the named account and preserves inherited allowFrom with "*"', () => { - const next = zalouserSetupWizard.dmPolicy?.setPolicy( - { - channels: { - zalouser: { - allowFrom: ["123456789"], - accounts: { - work: { - profile: "work", - }, - }, - }, - }, - } as OpenClawConfig, - "open", - "work", - ); - - expect(next?.channels?.zalouser?.dmPolicy).toBeUndefined(); - const workAccount = next?.channels?.zalouser?.accounts?.work as - | { dmPolicy?: string; allowFrom?: Array } - | undefined; - expect(workAccount?.dmPolicy).toBe("open"); - expect(workAccount?.allowFrom).toEqual(["123456789", "*"]); + ], }); it("shows the account-scoped current DM policy in quickstart notes", async () => { diff --git a/packages/acp-core/package.json b/packages/acp-core/package.json index 648722954327..dfdd76559caf 100644 --- a/packages/acp-core/package.json +++ b/packages/acp-core/package.json @@ -14,26 +14,11 @@ "import": "./dist/index.mjs", "default": "./dist/index.mjs" }, - "./normalize-text": { - "types": "./dist/normalize-text.d.mts", - "import": "./dist/normalize-text.mjs", - "default": "./dist/normalize-text.mjs" - }, "./meta": { "types": "./dist/meta.d.mts", "import": "./dist/meta.mjs", "default": "./dist/meta.mjs" }, - "./numeric-options": { - "types": "./dist/numeric-options.d.mts", - "import": "./dist/numeric-options.mjs", - "default": "./dist/numeric-options.mjs" - }, - "./record-shared": { - "types": "./dist/record-shared.d.mts", - "import": "./dist/record-shared.mjs", - "default": "./dist/record-shared.mjs" - }, "./session": { "types": "./dist/session.d.mts", "import": "./dist/session.mjs", @@ -84,6 +69,6 @@ "@openclaw/normalization-core": "workspace:*" }, "scripts": { - "build": "tsdown src/index.ts src/error-format.ts src/meta.ts src/normalize-text.ts src/numeric-options.ts src/record-shared.ts src/session.ts src/session-interaction-mode.ts src/session-lineage-meta.ts src/types.ts src/runtime/error-text.ts src/runtime/errors.ts src/runtime/session-identifiers.ts src/runtime/session-identity.ts src/runtime/types.ts --no-config --platform node --format esm --dts --out-dir dist --clean" + "build": "tsdown src/index.ts src/error-format.ts src/meta.ts src/session.ts src/session-interaction-mode.ts src/session-lineage-meta.ts src/types.ts src/runtime/error-text.ts src/runtime/errors.ts src/runtime/session-identifiers.ts src/runtime/session-identity.ts src/runtime/types.ts --no-config --platform node --format esm --dts --out-dir dist --clean" } } diff --git a/packages/acp-core/src/index.ts b/packages/acp-core/src/index.ts index e81b991bd9ce..acf23e0738ed 100644 --- a/packages/acp-core/src/index.ts +++ b/packages/acp-core/src/index.ts @@ -2,9 +2,6 @@ export * from "./error-format.js"; export * from "./meta.js"; -export * from "./normalize-text.js"; -export * from "./numeric-options.js"; -export * from "./record-shared.js"; export * from "./session-interaction-mode.js"; export * from "./session-lineage-meta.js"; export * from "./session.js"; diff --git a/packages/acp-core/src/normalize-text.ts b/packages/acp-core/src/normalize-text.ts deleted file mode 100644 index 0725ac92bbed..000000000000 --- a/packages/acp-core/src/normalize-text.ts +++ /dev/null @@ -1,3 +0,0 @@ -// ACP text normalization facade shared with older imports. - -export { normalizeOptionalString as normalizeText } from "@openclaw/normalization-core/string-coerce"; diff --git a/packages/acp-core/src/numeric-options.ts b/packages/acp-core/src/numeric-options.ts deleted file mode 100644 index 53a49c16ee31..000000000000 --- a/packages/acp-core/src/numeric-options.ts +++ /dev/null @@ -1,11 +0,0 @@ -// ACP Core module implements numeric options behavior. -import { resolveIntegerOption as resolveSharedIntegerOption } from "@openclaw/normalization-core/number-coercion"; - -/** Resolves ACP integer options through the shared normalization contract. */ -export function resolveIntegerOption( - value: number | undefined, - fallback: number, - params: { min: number }, -): number { - return resolveSharedIntegerOption(value, fallback, params); -} diff --git a/packages/acp-core/src/record-shared.ts b/packages/acp-core/src/record-shared.ts deleted file mode 100644 index 0a9cb347425d..000000000000 --- a/packages/acp-core/src/record-shared.ts +++ /dev/null @@ -1,3 +0,0 @@ -// ACP record normalization facade shared with older imports. - -export { asOptionalRecord as asRecord } from "@openclaw/normalization-core/record-coerce"; diff --git a/packages/acp-core/src/runtime/session-identifiers.ts b/packages/acp-core/src/runtime/session-identifiers.ts index 75b8ef662d56..3a77bacd9c5e 100644 --- a/packages/acp-core/src/runtime/session-identifiers.ts +++ b/packages/acp-core/src/runtime/session-identifiers.ts @@ -1,6 +1,8 @@ // ACP Core module implements session identifiers behavior. -import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; -import { normalizeText } from "../normalize-text.js"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString as normalizeText, +} from "@openclaw/normalization-core/string-coerce"; import type { SessionAcpIdentity, SessionAcpMeta } from "../types.js"; import { isSessionIdentityPending, resolveSessionIdentityFromMeta } from "./session-identity.js"; diff --git a/packages/acp-core/src/runtime/session-identity.ts b/packages/acp-core/src/runtime/session-identity.ts index eb0633dbdd7d..6ae8dcdf8c66 100644 --- a/packages/acp-core/src/runtime/session-identity.ts +++ b/packages/acp-core/src/runtime/session-identity.ts @@ -1,5 +1,5 @@ // ACP Core module implements session identity behavior. -import { normalizeText } from "../normalize-text.js"; +import { normalizeOptionalString as normalizeText } from "@openclaw/normalization-core/string-coerce"; import type { SessionAcpIdentity, SessionAcpIdentitySource, SessionAcpMeta } from "../types.js"; import type { AcpRuntimeHandle, AcpRuntimeStatus } from "./types.js"; diff --git a/packages/acp-core/src/session.ts b/packages/acp-core/src/session.ts index dedcd0f8c74f..26e37e95546b 100644 --- a/packages/acp-core/src/session.ts +++ b/packages/acp-core/src/session.ts @@ -1,6 +1,6 @@ // ACP Core module implements session behavior. import { randomUUID } from "node:crypto"; -import { resolveIntegerOption } from "./numeric-options.js"; +import { resolveIntegerOption } from "@openclaw/normalization-core/number-coercion"; import type { AcpSession } from "./types.js"; export type AcpSessionStore = { diff --git a/packages/memory-host-sdk/package.json b/packages/memory-host-sdk/package.json index 457d4813f84b..8fde14e63889 100644 --- a/packages/memory-host-sdk/package.json +++ b/packages/memory-host-sdk/package.json @@ -13,9 +13,7 @@ }, "exports": { "./runtime-core": "./src/runtime-core.ts", - "./runtime-cli": "./src/runtime-cli.ts", "./runtime-files": "./src/runtime-files.ts", - "./engine": "./src/engine.ts", "./engine-foundation": "./src/engine-foundation.ts", "./engine-storage": "./src/engine-storage.ts", "./engine-embeddings": "./src/engine-embeddings.ts", diff --git a/packages/memory-host-sdk/src/engine.ts b/packages/memory-host-sdk/src/engine.ts deleted file mode 100644 index a18fef9e8bae..000000000000 --- a/packages/memory-host-sdk/src/engine.ts +++ /dev/null @@ -1,7 +0,0 @@ -// Aggregate workspace contract for the memory engine surface. -// Keep focused subpaths preferred for new code. - -export * from "./engine-foundation.js"; -export * from "./engine-storage.js"; -export * from "./engine-embeddings.js"; -export * from "./engine-qmd.js"; diff --git a/packages/memory-host-sdk/src/host/openclaw-runtime-cli.ts b/packages/memory-host-sdk/src/host/openclaw-runtime-cli.ts deleted file mode 100644 index 192b761e3d41..000000000000 --- a/packages/memory-host-sdk/src/host/openclaw-runtime-cli.ts +++ /dev/null @@ -1,19 +0,0 @@ -// Narrow CLI/runtime facade re-exported for memory host helpers. - -export { - colorize, - defaultRuntime, - formatDocsLink, - formatErrorMessage, - formatHelpExamples, - isRich, - isVerbose, - resolveCommandSecretRefsViaGateway, - setVerbose, - shortenHomeInString, - shortenHomePath, - theme, - withManager, - withProgress, - withProgressTotals, -} from "./openclaw-runtime.js"; diff --git a/packages/memory-host-sdk/src/host/openclaw-runtime.ts b/packages/memory-host-sdk/src/host/openclaw-runtime.ts index b0fcb9afee14..31f1604be740 100644 --- a/packages/memory-host-sdk/src/host/openclaw-runtime.ts +++ b/packages/memory-host-sdk/src/host/openclaw-runtime.ts @@ -36,11 +36,7 @@ export { } from "../../../../src/auto-reply/tokens.js"; // CLI/runtime/config helpers. -export { formatErrorMessage, withManager } from "../../../../src/cli/cli-utils.js"; -export { resolveCommandSecretRefsViaGateway } from "../../../../src/cli/command-secret-gateway.js"; -export { formatHelpExamples } from "../../../../src/cli/help-format.js"; export { parseDurationMs } from "../../../../src/cli/parse-duration.js"; -export { withProgress, withProgressTotals } from "../../../../src/cli/progress.js"; export { parseNonNegativeByteSize } from "../../../../src/config/byte-size.js"; export { getRuntimeConfig, @@ -102,7 +98,6 @@ export { } from "../../../../src/config/types.secrets.js"; export type { SecretInput } from "../../../../src/config/types.secrets.js"; export type { MemorySearchConfig } from "../../../../src/config/types.tools.js"; -export { isVerbose, setVerbose } from "../../../../src/globals.js"; // IO, network, and logging helpers. export { isExecCompletionEvent } from "../../../../src/infra/heartbeat-events-filter.js"; @@ -160,13 +155,10 @@ export type { export type { OpenClawPluginApi } from "../../../../src/plugins/types.js"; // Shared session/text utilities. -export { defaultRuntime } from "../../../../src/runtime.js"; export { parseAgentSessionKey } from "../../../../src/routing/session-key.js"; export { hasInterSessionUserProvenance } from "../../../../src/sessions/input-provenance.js"; export { isCronRunSessionKey } from "../../../../src/sessions/session-key-utils.js"; export { onSessionTranscriptUpdate } from "../../../../src/sessions/transcript-events.js"; -export { formatDocsLink } from "../../../terminal-core/src/links.js"; -export { colorize, isRich, theme } from "../../../terminal-core/src/theme.js"; export { CHARS_PER_TOKEN_ESTIMATE, estimateStringChars } from "../../../../src/utils/cjk-chars.js"; export { runTasksWithConcurrency } from "../../../../src/utils/run-with-concurrency.js"; export { splitShellArgs } from "../../../../src/utils/shell-argv.js"; diff --git a/packages/memory-host-sdk/src/runtime-cli.ts b/packages/memory-host-sdk/src/runtime-cli.ts deleted file mode 100644 index a5386e335429..000000000000 --- a/packages/memory-host-sdk/src/runtime-cli.ts +++ /dev/null @@ -1,11 +0,0 @@ -// Focused runtime contract for memory CLI/UI helpers. - -export { formatErrorMessage, withManager } from "./host/openclaw-runtime-cli.js"; -export { formatHelpExamples } from "./host/openclaw-runtime-cli.js"; -export { resolveCommandSecretRefsViaGateway } from "./host/openclaw-runtime-cli.js"; -export { withProgress, withProgressTotals } from "./host/openclaw-runtime-cli.js"; -export { defaultRuntime } from "./host/openclaw-runtime-cli.js"; -export { formatDocsLink } from "./host/openclaw-runtime-cli.js"; -export { colorize, isRich, theme } from "./host/openclaw-runtime-cli.js"; -export { isVerbose, setVerbose } from "./host/openclaw-runtime-cli.js"; -export { shortenHomeInString, shortenHomePath } from "./host/openclaw-runtime-cli.js"; diff --git a/packages/web-content-core/package.json b/packages/web-content-core/package.json deleted file mode 100644 index 233abe7542f1..000000000000 --- a/packages/web-content-core/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "@openclaw/web-content-core", - "version": "0.0.0-private", - "private": true, - "files": [ - "dist" - ], - "type": "module", - "exports": { - "./provider-runtime-shared": { - "types": "./dist/provider-runtime-shared.d.mts", - "import": "./dist/provider-runtime-shared.mjs", - "default": "./dist/provider-runtime-shared.mjs" - } - }, - "scripts": { - "build": "tsdown src/provider-runtime-shared.ts --no-config --platform node --format esm --dts --out-dir dist --clean" - } -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f4b056cd0848..968cdd24086c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2311,8 +2311,6 @@ importers: specifier: workspace:* version: link:../normalization-core - packages/web-content-core: {} - packages/workboard-contract: {} ui: diff --git a/scripts/run-node-watch-paths.mjs b/scripts/run-node-watch-paths.mjs index cc6d3c538838..2e7318f8ad8a 100644 --- a/scripts/run-node-watch-paths.mjs +++ b/scripts/run-node-watch-paths.mjs @@ -20,7 +20,6 @@ const RUN_NODE_PACKAGE_SOURCE_ROOTS = [ "packages/retry/src", "packages/acp-core/src", "packages/terminal-core/src", - "packages/web-content-core/src", "packages/net-policy/src", ]; diff --git a/src/acp/approval-classifier.ts b/src/acp/approval-classifier.ts index c3e0c5dbde75..44357a24bc6c 100644 --- a/src/acp/approval-classifier.ts +++ b/src/acp/approval-classifier.ts @@ -1,7 +1,7 @@ /** Classifies ACP tool permission requests into auto-approved and prompt-required risk buckets. */ import { homedir } from "node:os"; import path from "node:path"; -import { asRecord } from "@openclaw/acp-core/record-shared"; +import { asOptionalRecord as asRecord } from "@openclaw/normalization-core/record-coerce"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, diff --git a/src/acp/control-plane/runtime-options.ts b/src/acp/control-plane/runtime-options.ts index 73726e2d37a5..e151465fc432 100644 --- a/src/acp/control-plane/runtime-options.ts +++ b/src/acp/control-plane/runtime-options.ts @@ -1,12 +1,14 @@ /** Validation and normalization for ACP session runtime options and config controls. */ import { isAbsolute } from "node:path"; -import { normalizeText } from "@openclaw/acp-core/normalize-text"; -import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; +import { + normalizeLowercaseStringOrEmpty, + normalizeOptionalString as normalizeText, +} from "@openclaw/normalization-core/string-coerce"; import type { AcpSessionRuntimeOptions, SessionAcpMeta } from "../../config/sessions/types.js"; import { parseStrictPositiveInteger } from "../../infra/parse-finite-number.js"; import { AcpRuntimeError } from "../runtime/errors.js"; -export { normalizeText } from "@openclaw/acp-core/normalize-text"; +export { normalizeOptionalString as normalizeText } from "@openclaw/normalization-core/string-coerce"; const MAX_RUNTIME_MODE_LENGTH = 64; const MAX_MODEL_LENGTH = 200; diff --git a/src/acp/event-ledger.ts b/src/acp/event-ledger.ts index 185cae2b65fa..da5093b91385 100644 --- a/src/acp/event-ledger.ts +++ b/src/acp/event-ledger.ts @@ -1,7 +1,7 @@ /** Persistent/replayable ACP event ledger implementations for session rehydration. */ import type { DatabaseSync } from "node:sqlite"; import type { ContentBlock, SessionUpdate } from "@agentclientprotocol/sdk"; -import { resolveIntegerOption } from "@openclaw/acp-core/numeric-options"; +import { resolveIntegerOption } from "@openclaw/normalization-core/number-coercion"; import { openOpenClawStateDatabase, type OpenClawStateDatabaseOptions, diff --git a/src/acp/event-mapper.ts b/src/acp/event-mapper.ts index 473f450f3b68..c027aefe17c7 100644 --- a/src/acp/event-mapper.ts +++ b/src/acp/event-mapper.ts @@ -5,8 +5,8 @@ import type { ToolCallLocation, ToolKind, } from "@agentclientprotocol/sdk"; -import { asRecord } from "@openclaw/acp-core/record-shared"; import { hasHttpUrlPrefix } from "@openclaw/net-policy/url-protocol"; +import { asOptionalRecord as asRecord } from "@openclaw/normalization-core/record-coerce"; import { hasNonEmptyString, normalizeLowercaseStringOrEmpty, diff --git a/src/acp/persistent-bindings.types.ts b/src/acp/persistent-bindings.types.ts index a91a2ba5d673..b2d5cca5c791 100644 --- a/src/acp/persistent-bindings.types.ts +++ b/src/acp/persistent-bindings.types.ts @@ -1,14 +1,16 @@ /** Types and normalization helpers for configured channel-to-ACP persistent bindings. */ -import { normalizeText } from "@openclaw/acp-core/normalize-text"; import type { AcpRuntimeSessionMode } from "@openclaw/acp-core/runtime/types"; -import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce"; +import { + normalizeOptionalLowercaseString, + normalizeOptionalString as normalizeText, +} from "@openclaw/normalization-core/string-coerce"; import type { ChannelId } from "../channels/plugins/types.public.js"; import { sha256HexPrefix } from "../infra/crypto-digest.js"; import type { SessionBindingRecord } from "../infra/outbound/session-binding-service.js"; import { normalizeAccountId, resolveAgentIdFromSessionKey } from "../routing/session-key.js"; import { sanitizeAgentId } from "../routing/session-key.js"; -export { normalizeText } from "@openclaw/acp-core/normalize-text"; +export { normalizeOptionalString as normalizeText } from "@openclaw/normalization-core/string-coerce"; export type ConfiguredAcpBindingChannel = ChannelId; diff --git a/src/agents/tools/web-fetch.ts b/src/agents/tools/web-fetch.ts index 086b46b629d4..5f9abc40a3e3 100644 --- a/src/agents/tools/web-fetch.ts +++ b/src/agents/tools/web-fetch.ts @@ -11,7 +11,6 @@ import { } from "@openclaw/normalization-core/string-coerce"; import { truncateUtf16Safe } from "@openclaw/normalization-core/utf16-slice"; import { Type } from "typebox"; -import { resolveWebProviderConfig } from "../../../packages/web-content-core/src/provider-runtime-shared.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { SsrFBlockedError, type LookupFn, type SsrFPolicy } from "../../infra/net/ssrf.js"; import { logDebug } from "../../logger.js"; @@ -22,6 +21,7 @@ import { wrapExternalContent, wrapWebContent } from "../../security/external-con import { createLazyImportLoader } from "../../shared/lazy-promise.js"; import { isRecord } from "../../utils.js"; import { extractReadableContent } from "../../web-fetch/content-extractors.runtime.js"; +import { resolveWebProviderConfig } from "../../web/provider-runtime-shared.js"; import { stringEnum } from "../schema/string-enum.js"; import { writePrivateTempFile } from "../sessions/tools/private-temp-file.js"; import { formatFullOutputFooter } from "../sessions/tools/tool-contracts.js"; diff --git a/src/plugin-sdk/channel-test-helpers.ts b/src/plugin-sdk/channel-test-helpers.ts index b8f3362436ab..726613680bad 100644 --- a/src/plugin-sdk/channel-test-helpers.ts +++ b/src/plugin-sdk/channel-test-helpers.ts @@ -4,6 +4,7 @@ export { expectDirectoryIds, type DirectoryListFn } from "./test-helpers/directo export { expectChannelPluginContract, installChannelActionsContractSuite, + installChannelDmPolicyContractSuite, installChannelPluginContractSuite, installChannelSetupContractSuite, installChannelStatusContractSuite, diff --git a/src/plugin-sdk/test-helpers/channel-contract-suites.ts b/src/plugin-sdk/test-helpers/channel-contract-suites.ts index 076d2f8e01c2..3af6ed19c993 100644 --- a/src/plugin-sdk/test-helpers/channel-contract-suites.ts +++ b/src/plugin-sdk/test-helpers/channel-contract-suites.ts @@ -1,5 +1,6 @@ // Channel contract suites provide reusable expectations for channel plugin test coverage. import { expect, it } from "vitest"; +import type { ChannelSetupDmPolicy } from "../../channels/plugins/setup-wizard-types.js"; import type { ChannelAccountSnapshot, ChannelAccountState, @@ -172,6 +173,142 @@ export function installChannelSetupContractSuite< } } +type ChannelDmPolicyConfig = { + dmPolicy?: unknown; + allowFrom?: unknown; + accounts?: Record; +}; + +type ChannelDmPolicyContractCase = { + name: string; + channel: string; + accountId: string; + accountConfig: Record; + inheritedAllowFrom: ReadonlyArray; + defaultAccount?: { + rootAllowFrom?: ReadonlyArray; + accountAllowFrom?: ReadonlyArray; + }; +}; + +function createDmPolicyContractConfig(params: { + testCase: ChannelDmPolicyContractCase; + mode: "read" | "write" | "default"; +}): OpenClawConfig { + const { testCase } = params; + const defaultAccount = params.mode === "default" ? testCase.defaultAccount : undefined; + const account = { + ...testCase.accountConfig, + ...(params.mode === "write" ? {} : { dmPolicy: "allowlist" }), + ...(defaultAccount?.accountAllowFrom + ? { allowFrom: [...defaultAccount.accountAllowFrom] } + : {}), + }; + const rootAllowFrom = + params.mode === "write" ? testCase.inheritedAllowFrom : defaultAccount?.rootAllowFrom; + return { + channels: { + [testCase.channel]: { + ...(params.mode === "write" ? {} : { dmPolicy: "disabled" }), + ...(params.mode === "default" ? { defaultAccount: testCase.accountId } : {}), + ...(rootAllowFrom ? { allowFrom: [...rootAllowFrom] } : {}), + accounts: { [testCase.accountId]: account }, + }, + }, + } as OpenClawConfig; +} + +function addExpectedWildcard(values: ReadonlyArray | undefined) { + return values?.includes("*") ? [...values] : [...(values ?? []), "*"]; +} + +function resolveDmPolicyConfig( + cfg: OpenClawConfig, + channel: string, + accountId: string, +): { channel: ChannelDmPolicyConfig; account: ChannelDmPolicyConfig } { + const channels = cfg.channels as Record | undefined; + const channelConfig = channels?.[channel]; + const accountConfig = channelConfig?.accounts?.[accountId]; + expect(channelConfig).toBeDefined(); + expect(accountConfig).toBeDefined(); + return { channel: channelConfig!, account: accountConfig! }; +} + +function expectOpenDmPolicyPatch(params: { + dmPolicy: ChannelSetupDmPolicy; + cfg: OpenClawConfig; + channel: string; + accountId?: string; + resolvedAccountId: string; + expectedAllowFrom: readonly unknown[]; +}) { + const before = resolveDmPolicyConfig(params.cfg, params.channel, params.resolvedAccountId); + const beforeRootPolicy = before.channel.dmPolicy; + const beforeRootAllowFrom = Array.isArray(before.channel.allowFrom) + ? [...before.channel.allowFrom] + : before.channel.allowFrom; + const next = params.dmPolicy.setPolicy(params.cfg, "open", params.accountId); + const after = resolveDmPolicyConfig(next, params.channel, params.resolvedAccountId); + + expect(after.channel.dmPolicy).toBe(beforeRootPolicy); + expect(after.channel.allowFrom).toEqual(beforeRootAllowFrom); + expect(after.account.dmPolicy).toBe("open"); + expect(after.account.allowFrom).toEqual(params.expectedAllowFrom); +} + +export function installChannelDmPolicyContractSuite(params: { + dmPolicy: ChannelSetupDmPolicy; + cases: readonly ChannelDmPolicyContractCase[]; +}) { + for (const testCase of params.cases) { + it(`dm policy contract: ${testCase.name} reads the named-account policy`, () => { + expect(params.dmPolicy.channel).toBe(testCase.channel); + const cfg = createDmPolicyContractConfig({ testCase, mode: "read" }); + expect(params.dmPolicy.getCurrent(cfg, testCase.accountId)).toBe("allowlist"); + }); + + it(`dm policy contract: ${testCase.name} reports account-scoped config keys`, () => { + expect(params.dmPolicy.resolveConfigKeys?.({}, testCase.accountId)).toEqual({ + policyKey: `channels.${testCase.channel}.accounts.${testCase.accountId}.dmPolicy`, + allowFromKey: `channels.${testCase.channel}.accounts.${testCase.accountId}.allowFrom`, + }); + }); + + it(`dm policy contract: ${testCase.name} writes open policy with inherited allowFrom`, () => { + expectOpenDmPolicyPatch({ + dmPolicy: params.dmPolicy, + cfg: createDmPolicyContractConfig({ testCase, mode: "write" }), + channel: testCase.channel, + accountId: testCase.accountId, + resolvedAccountId: testCase.accountId, + expectedAllowFrom: addExpectedWildcard(testCase.inheritedAllowFrom), + }); + }); + + const defaultAccount = testCase.defaultAccount; + if (defaultAccount) { + it(`dm policy contract: ${testCase.name} uses defaultAccount when accountId is omitted`, () => { + const cfg = createDmPolicyContractConfig({ testCase, mode: "default" }); + expect(params.dmPolicy.getCurrent(cfg)).toBe("allowlist"); + expect(params.dmPolicy.resolveConfigKeys?.(cfg)).toEqual({ + policyKey: `channels.${testCase.channel}.accounts.${testCase.accountId}.dmPolicy`, + allowFromKey: `channels.${testCase.channel}.accounts.${testCase.accountId}.allowFrom`, + }); + expectOpenDmPolicyPatch({ + dmPolicy: params.dmPolicy, + cfg, + channel: testCase.channel, + resolvedAccountId: testCase.accountId, + expectedAllowFrom: addExpectedWildcard( + defaultAccount.accountAllowFrom ?? defaultAccount.rootAllowFrom, + ), + }); + }); + } + } +} + type ChannelStatusContractCase = { name: string; cfg: OpenClawConfig; diff --git a/src/plugins/contracts/extension-package-project-boundaries.test.ts b/src/plugins/contracts/extension-package-project-boundaries.test.ts index da6e77de13ea..5c9f963f19c8 100644 --- a/src/plugins/contracts/extension-package-project-boundaries.test.ts +++ b/src/plugins/contracts/extension-package-project-boundaries.test.ts @@ -45,14 +45,12 @@ type PackageJson = { devDependencies?: Record; }; const MEMORY_HOST_SDK_EXPORTS = [ - "./engine", "./engine-embeddings", "./engine-foundation", "./engine-qmd", "./engine-storage", "./multimodal", "./query", - "./runtime-cli", "./runtime-core", "./runtime-files", "./secret", @@ -66,7 +64,6 @@ const MEMORY_HOST_SDK_ALLOWED_CORE_BRIDGE_FILES = [ ] as const; const MEMORY_HOST_SDK_RUNTIME_ADAPTER_FILES = [ "packages/memory-host-sdk/src/host/openclaw-runtime-agent.ts", - "packages/memory-host-sdk/src/host/openclaw-runtime-cli.ts", "packages/memory-host-sdk/src/host/openclaw-runtime-config.ts", "packages/memory-host-sdk/src/host/openclaw-runtime-io.ts", "packages/memory-host-sdk/src/host/openclaw-runtime-memory.ts", diff --git a/src/plugins/contracts/plugin-sdk-subpaths.test.ts b/src/plugins/contracts/plugin-sdk-subpaths.test.ts index 25f8e5d708fe..b1bcc5c5c23d 100644 --- a/src/plugins/contracts/plugin-sdk-subpaths.test.ts +++ b/src/plugins/contracts/plugin-sdk-subpaths.test.ts @@ -764,7 +764,6 @@ describe("plugin-sdk subpath exports", () => { }); expectSourceContract("memory-core-host-runtime-cli", { mentions: ["defaultRuntime", "withManager", "withProgressTotals"], - omits: ['export * from "../../packages/memory-host-sdk/src/runtime-cli.js";'], }); expectSourceContract("memory-core-host-runtime-files", { mentions: ["listMemoryFiles", "normalizeExtraMemoryPaths", "MemorySearchResult"], diff --git a/src/plugins/sdk-alias.test.ts b/src/plugins/sdk-alias.test.ts index 5b0477c4a21e..85a255399abd 100644 --- a/src/plugins/sdk-alias.test.ts +++ b/src/plugins/sdk-alias.test.ts @@ -1528,9 +1528,6 @@ describe("plugin sdk alias helpers", () => { expect(fs.realpathSync(aliases["@openclaw/media-generation-core/catalog"] ?? "")).toBe( fs.realpathSync(mediaGenerationCore.distFile), ); - expect(fs.realpathSync(aliases["@openclaw/acp-core/normalize-text"] ?? "")).toBe( - fs.realpathSync(acpCoreRootDistFile), - ); expect(fs.realpathSync(aliases["@openclaw/normalization-core/record-coerce"] ?? "")).toBe( fs.realpathSync(normalizationCoreRootDistFile), ); diff --git a/src/web-fetch/runtime.ts b/src/web-fetch/runtime.ts index 48d87fac4111..f8576bd24b0f 100644 --- a/src/web-fetch/runtime.ts +++ b/src/web-fetch/runtime.ts @@ -1,13 +1,6 @@ /** Runtime provider selection and tool construction for the `web_fetch` tool. */ import { createHash } from "node:crypto"; import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; -import { - hasWebProviderEntryCredential, - providerRequiresCredential, - readWebProviderEnvValue, - resolveWebProviderConfig, - resolveWebProviderDefinition, -} from "../../packages/web-content-core/src/provider-runtime-shared.js"; import type { OpenClawConfig } from "../config/types.js"; import { logVerbose } from "../globals.js"; import { getActivePluginRegistryVersion } from "../plugins/runtime.js"; @@ -22,6 +15,13 @@ import { import { sortWebFetchProvidersForAutoDetect } from "../plugins/web-fetch-providers.shared.js"; import { getActiveRuntimeWebToolsMetadata } from "../secrets/runtime-web-tools-state.js"; import type { RuntimeWebFetchMetadata } from "../secrets/runtime-web-tools.types.js"; +import { + hasWebProviderEntryCredential, + providerRequiresCredential, + readWebProviderEnvValue, + resolveWebProviderConfig, + resolveWebProviderDefinition, +} from "../web/provider-runtime-shared.js"; // Runtime provider selection for the web_fetch tool. It resolves config, // credentials, runtime metadata, and sandbox-safe bundled provider scopes. diff --git a/src/web-search/runtime.ts b/src/web-search/runtime.ts index fd283098d0ba..ff18a9bfe2de 100644 --- a/src/web-search/runtime.ts +++ b/src/web-search/runtime.ts @@ -4,12 +4,6 @@ import { normalizeOptionalLowercaseString, } from "@openclaw/normalization-core/string-coerce"; import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; -import { - hasWebProviderEntryCredential, - providerRequiresCredential, - readWebProviderEnvValue, - resolveWebProviderConfig, -} from "../../packages/web-content-core/src/provider-runtime-shared.js"; import { resolveDefaultAgentDir } from "../agents/agent-scope-config.js"; import { hasAuthProfileForProvider } from "../agents/tools/model-config.helpers.js"; import { @@ -28,6 +22,12 @@ import { import { sortWebSearchProvidersForAutoDetect } from "../plugins/web-search-providers.shared.js"; import { getActiveRuntimeWebToolsMetadata } from "../secrets/runtime-web-tools-state.js"; import type { RuntimeWebSearchMetadata } from "../secrets/runtime-web-tools.types.js"; +import { + hasWebProviderEntryCredential, + providerRequiresCredential, + readWebProviderEnvValue, + resolveWebProviderConfig, +} from "../web/provider-runtime-shared.js"; import { executeWebSearchCandidates } from "./runtime-execution.js"; import type { ResolveWebSearchDefinitionParams, diff --git a/packages/web-content-core/src/provider-runtime-shared.test.ts b/src/web/provider-runtime-shared.test.ts similarity index 97% rename from packages/web-content-core/src/provider-runtime-shared.test.ts rename to src/web/provider-runtime-shared.test.ts index 5311709165af..4edc11718d52 100644 --- a/packages/web-content-core/src/provider-runtime-shared.test.ts +++ b/src/web/provider-runtime-shared.test.ts @@ -1,4 +1,4 @@ -// Web Content Core tests cover provider runtime shared behavior. +// Web provider runtime tests cover shared config, credential, and definition resolution. import { describe, expect, it } from "vitest"; import { hasWebProviderEntryCredential, diff --git a/packages/web-content-core/src/provider-runtime-shared.ts b/src/web/provider-runtime-shared.ts similarity index 98% rename from packages/web-content-core/src/provider-runtime-shared.ts rename to src/web/provider-runtime-shared.ts index 56aa302616c0..e4179cb851a7 100644 --- a/packages/web-content-core/src/provider-runtime-shared.ts +++ b/src/web/provider-runtime-shared.ts @@ -1,5 +1,5 @@ -// Web Content Core module implements provider runtime shared behavior. -export type WebProviderConfigSource = { +// Shared web provider config, credential, and definition resolution. +type WebProviderConfigSource = { tools?: { web?: { search?: unknown; diff --git a/test/scripts/oxlint-config.test.ts b/test/scripts/oxlint-config.test.ts index cdc929d0709e..ba7fed69e5e2 100644 --- a/test/scripts/oxlint-config.test.ts +++ b/test/scripts/oxlint-config.test.ts @@ -183,7 +183,6 @@ describe("oxlint config", () => { "packages/terminal-core/**/*.ts", "packages/normalization-core/**/*.ts", "packages/model-catalog-core/**/*.ts", - "packages/web-content-core/**/*.ts", "packages/agent-core/**/*.ts", "packages/acp-core/**/*.ts", "packages/ai/**/*.ts", diff --git a/tsconfig.json b/tsconfig.json index 1d4f65f1b904..a1c9c4485ffd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -180,9 +180,6 @@ "@openclaw/workboard-contract": ["./packages/workboard-contract/src/index.ts"], "@openclaw/acp-core": ["./packages/acp-core/src/index.ts"], "@openclaw/acp-core/meta": ["./packages/acp-core/src/meta.ts"], - "@openclaw/acp-core/numeric-options": ["./packages/acp-core/src/numeric-options.ts"], - "@openclaw/acp-core/normalize-text": ["./packages/acp-core/src/normalize-text.ts"], - "@openclaw/acp-core/record-shared": ["./packages/acp-core/src/record-shared.ts"], "@openclaw/acp-core/session": ["./packages/acp-core/src/session.ts"], "@openclaw/acp-core/session-interaction-mode": [ "./packages/acp-core/src/session-interaction-mode.ts" @@ -247,10 +244,6 @@ "@openclaw/net-policy/url-protocol": ["./packages/net-policy/src/url-protocol.ts"], "@openclaw/net-policy/url-userinfo": ["./packages/net-policy/src/url-userinfo.ts"], "@openclaw/net-policy/*": ["./packages/net-policy/src/*"], - "@openclaw/web-content-core/provider-runtime-shared": [ - "./packages/web-content-core/src/provider-runtime-shared.ts" - ], - "@openclaw/web-content-core/*": ["./packages/web-content-core/src/*"], "@openclaw/speech-core": ["./packages/speech-core/runtime-api.ts"], "@openclaw/speech-core/runtime-api": ["./packages/speech-core/runtime-api.ts"], "@openclaw/speech-core/speaker": ["./packages/speech-core/speaker.ts"], diff --git a/tsdown.config.ts b/tsdown.config.ts index 3af8b81b3007..26f261a8ae40 100644 --- a/tsdown.config.ts +++ b/tsdown.config.ts @@ -565,9 +565,6 @@ const configs = [ neverBundle: shouldExternalizeTerminalCoreDependency, }, }), - nodeWorkspacePackageBuildConfig("web-content-core", { - outDir: "packages/web-content-core/dist", - }), nodeWorkspacePackageBuildConfig("speech-core", { entry: buildSpeechCoreDistEntries(), deps: {