refactor: remove channel shim directories, point all imports to extensions (#45967)

* refactor: remove channel shim directories, point all imports to extensions

Delete the 6 backward-compat shim directories (src/telegram, src/discord,
src/slack, src/signal, src/imessage, src/web) that were re-exporting from
extensions. Update all 112+ source files to import directly from
extensions/{channel}/src/ instead of through the shims.

Also:
- Move src/channels/telegram/ (allow-from, api) to extensions/telegram/src/
- Fix outbound adapters to use resolveOutboundSendDep (fixes 5 pre-existing TS errors)
- Update cross-extension imports (src/web/media.js → extensions/whatsapp/src/media.js)
- Update vitest, tsdown, knip, labeler, and script configs for new paths
- Update guard test allowlists for extension paths

After this, src/ has zero channel-specific implementation code — only the
generic plugin framework remains.

* fix: update raw-fetch guard allowlist line numbers after shim removal

* refactor: document direct extension channel imports

* test: mock transcript module in delivery helpers
This commit is contained in:
scoootscooob 2026-03-14 03:43:07 -07:00 committed by GitHub
parent 5682ec37fa
commit 439c21e078
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
534 changed files with 524 additions and 1088 deletions

6
.github/labeler.yml vendored
View File

@ -6,7 +6,6 @@
"channel: discord": "channel: discord":
- changed-files: - changed-files:
- any-glob-to-any-file: - any-glob-to-any-file:
- "src/discord/**"
- "extensions/discord/**" - "extensions/discord/**"
- "docs/channels/discord.md" - "docs/channels/discord.md"
"channel: irc": "channel: irc":
@ -28,7 +27,6 @@
"channel: imessage": "channel: imessage":
- changed-files: - changed-files:
- any-glob-to-any-file: - any-glob-to-any-file:
- "src/imessage/**"
- "extensions/imessage/**" - "extensions/imessage/**"
- "docs/channels/imessage.md" - "docs/channels/imessage.md"
"channel: line": "channel: line":
@ -64,19 +62,16 @@
"channel: signal": "channel: signal":
- changed-files: - changed-files:
- any-glob-to-any-file: - any-glob-to-any-file:
- "src/signal/**"
- "extensions/signal/**" - "extensions/signal/**"
- "docs/channels/signal.md" - "docs/channels/signal.md"
"channel: slack": "channel: slack":
- changed-files: - changed-files:
- any-glob-to-any-file: - any-glob-to-any-file:
- "src/slack/**"
- "extensions/slack/**" - "extensions/slack/**"
- "docs/channels/slack.md" - "docs/channels/slack.md"
"channel: telegram": "channel: telegram":
- changed-files: - changed-files:
- any-glob-to-any-file: - any-glob-to-any-file:
- "src/telegram/**"
- "extensions/telegram/**" - "extensions/telegram/**"
- "docs/channels/telegram.md" - "docs/channels/telegram.md"
"channel: tlon": "channel: tlon":
@ -96,7 +91,6 @@
"channel: whatsapp-web": "channel: whatsapp-web":
- changed-files: - changed-files:
- any-glob-to-any-file: - any-glob-to-any-file:
- "src/web/**"
- "extensions/whatsapp/**" - "extensions/whatsapp/**"
- "docs/channels/whatsapp.md" - "docs/channels/whatsapp.md"
"channel: zalo": "channel: zalo":

View File

@ -7,6 +7,7 @@ Docs: https://docs.openclaw.ai
### Changes ### Changes
- Placeholder: replace with the first 2026.3.14 user-facing change. - Placeholder: replace with the first 2026.3.14 user-facing change.
- Refactor/channels: remove the legacy channel shim directories and point channel-specific imports directly at the extension-owned implementations. (#45967) thanks @scoootscooob.
## 2026.3.13 ## 2026.3.13

View File

@ -55,7 +55,7 @@ import { executePluginCommand, matchPluginCommand } from "../../../../src/plugin
import type { ResolvedAgentRoute } from "../../../../src/routing/resolve-route.js"; import type { ResolvedAgentRoute } from "../../../../src/routing/resolve-route.js";
import { chunkItems } from "../../../../src/utils/chunk-items.js"; import { chunkItems } from "../../../../src/utils/chunk-items.js";
import { withTimeout } from "../../../../src/utils/with-timeout.js"; import { withTimeout } from "../../../../src/utils/with-timeout.js";
import { loadWebMedia } from "../../../../src/web/media.js"; import { loadWebMedia } from "../../../whatsapp/src/media.js";
import { resolveDiscordMaxLinesPerMessage } from "../accounts.js"; import { resolveDiscordMaxLinesPerMessage } from "../accounts.js";
import { chunkDiscordTextWithMode } from "../chunk.js"; import { chunkDiscordTextWithMode } from "../chunk.js";
import { import {

View File

@ -1,6 +1,7 @@
import { sendTextMediaPayload } from "../../../src/channels/plugins/outbound/direct-text-media.js"; import { sendTextMediaPayload } from "../../../src/channels/plugins/outbound/direct-text-media.js";
import type { ChannelOutboundAdapter } from "../../../src/channels/plugins/types.js"; import type { ChannelOutboundAdapter } from "../../../src/channels/plugins/types.js";
import type { OpenClawConfig } from "../../../src/config/config.js"; import type { OpenClawConfig } from "../../../src/config/config.js";
import { resolveOutboundSendDep } from "../../../src/infra/outbound/deliver.js";
import type { OutboundIdentity } from "../../../src/infra/outbound/identity.js"; import type { OutboundIdentity } from "../../../src/infra/outbound/identity.js";
import { getThreadBindingManager, type ThreadBindingRecord } from "./monitor/thread-bindings.js"; import { getThreadBindingManager, type ThreadBindingRecord } from "./monitor/thread-bindings.js";
import { normalizeDiscordOutboundTarget } from "./normalize.js"; import { normalizeDiscordOutboundTarget } from "./normalize.js";
@ -93,7 +94,8 @@ export const discordOutbound: ChannelOutboundAdapter = {
return { channel: "discord", ...webhookResult }; return { channel: "discord", ...webhookResult };
} }
} }
const send = deps?.sendDiscord ?? sendMessageDiscord; const send =
resolveOutboundSendDep<typeof sendMessageDiscord>(deps, "discord") ?? sendMessageDiscord;
const target = resolveDiscordOutboundTarget({ to, threadId }); const target = resolveDiscordOutboundTarget({ to, threadId });
const result = await send(target, text, { const result = await send(target, text, {
verbose: false, verbose: false,
@ -116,7 +118,8 @@ export const discordOutbound: ChannelOutboundAdapter = {
threadId, threadId,
silent, silent,
}) => { }) => {
const send = deps?.sendDiscord ?? sendMessageDiscord; const send =
resolveOutboundSendDep<typeof sendMessageDiscord>(deps, "discord") ?? sendMessageDiscord;
const target = resolveDiscordOutboundTarget({ to, threadId }); const target = resolveDiscordOutboundTarget({ to, threadId });
const result = await send(target, text, { const result = await send(target, text, {
verbose: false, verbose: false,

View File

@ -7,7 +7,7 @@ import {
import { ChannelType, Routes } from "discord-api-types/v10"; import { ChannelType, Routes } from "discord-api-types/v10";
import { loadConfig, type OpenClawConfig } from "../../../src/config/config.js"; import { loadConfig, type OpenClawConfig } from "../../../src/config/config.js";
import { recordChannelActivity } from "../../../src/infra/channel-activity.js"; import { recordChannelActivity } from "../../../src/infra/channel-activity.js";
import { loadWebMedia } from "../../../src/web/media.js"; import { loadWebMedia } from "../../whatsapp/src/media.js";
import { resolveDiscordAccount } from "./accounts.js"; import { resolveDiscordAccount } from "./accounts.js";
import { registerDiscordComponentEntries } from "./components-registry.js"; import { registerDiscordComponentEntries } from "./components-registry.js";
import { import {

View File

@ -1,5 +1,5 @@
import { Routes } from "discord-api-types/v10"; import { Routes } from "discord-api-types/v10";
import { loadWebMediaRaw } from "../../../src/web/media.js"; import { loadWebMediaRaw } from "../../whatsapp/src/media.js";
import { normalizeEmojiName, resolveDiscordRest } from "./send.shared.js"; import { normalizeEmojiName, resolveDiscordRest } from "./send.shared.js";
import type { DiscordEmojiUpload, DiscordReactOpts, DiscordStickerUpload } from "./send.types.js"; import type { DiscordEmojiUpload, DiscordReactOpts, DiscordStickerUpload } from "./send.types.js";
import { DISCORD_MAX_EMOJI_BYTES, DISCORD_MAX_STICKER_BYTES } from "./send.types.js"; import { DISCORD_MAX_EMOJI_BYTES, DISCORD_MAX_STICKER_BYTES } from "./send.types.js";

View File

@ -14,7 +14,7 @@ import { maxBytesForKind } from "../../../src/media/constants.js";
import { extensionForMime } from "../../../src/media/mime.js"; import { extensionForMime } from "../../../src/media/mime.js";
import { unlinkIfExists } from "../../../src/media/temp-files.js"; import { unlinkIfExists } from "../../../src/media/temp-files.js";
import type { PollInput } from "../../../src/polls.js"; import type { PollInput } from "../../../src/polls.js";
import { loadWebMediaRaw } from "../../../src/web/media.js"; import { loadWebMediaRaw } from "../../whatsapp/src/media.js";
import { resolveDiscordAccount } from "./accounts.js"; import { resolveDiscordAccount } from "./accounts.js";
import { rewriteDiscordKnownMentions } from "./mentions.js"; import { rewriteDiscordKnownMentions } from "./mentions.js";
import { import {

View File

@ -18,7 +18,7 @@ import {
normalizePollInput, normalizePollInput,
type PollInput, type PollInput,
} from "../../../src/polls.js"; } from "../../../src/polls.js";
import { loadWebMedia } from "../../../src/web/media.js"; import { loadWebMedia } from "../../whatsapp/src/media.js";
import { resolveDiscordAccount } from "./accounts.js"; import { resolveDiscordAccount } from "./accounts.js";
import { chunkDiscordTextWithMode } from "./chunk.js"; import { chunkDiscordTextWithMode } from "./chunk.js";
import { createDiscordClient, resolveDiscordRest } from "./client.js"; import { createDiscordClient, resolveDiscordRest } from "./client.js";

View File

@ -12,7 +12,7 @@ import {
fetchWithSsrFGuard, fetchWithSsrFGuard,
withTrustedEnvProxyGuardedFetchMode, withTrustedEnvProxyGuardedFetchMode,
} from "../../../src/infra/net/fetch-guard.js"; } from "../../../src/infra/net/fetch-guard.js";
import { loadWebMedia } from "../../../src/web/media.js"; import { loadWebMedia } from "../../whatsapp/src/media.js";
import type { SlackTokenSource } from "./accounts.js"; import type { SlackTokenSource } from "./accounts.js";
import { resolveSlackAccount } from "./accounts.js"; import { resolveSlackAccount } from "./accounts.js";
import { buildSlackBlocksFallbackText } from "./blocks-fallback.js"; import { buildSlackBlocksFallbackText } from "./blocks-fallback.js";

View File

@ -1,5 +1,5 @@
import { describe, expect, it, vi } from "vitest"; import { describe, expect, it, vi } from "vitest";
import { fetchTelegramChatId } from "./api.js"; import { fetchTelegramChatId } from "./api-fetch.js";
describe("fetchTelegramChatId", () => { describe("fetchTelegramChatId", () => {
const cases = [ const cases = [

View File

@ -20,7 +20,7 @@ export function getLoadWebMediaMock(): AnyMock {
return loadWebMedia; return loadWebMedia;
} }
vi.mock("../../../src/web/media.js", () => ({ vi.mock("../../whatsapp/src/media.js", () => ({
loadWebMedia, loadWebMedia,
})); }));

View File

@ -20,7 +20,7 @@ import { buildOutboundMediaLoadOptions } from "../../../../src/media/load-option
import { isGifMedia, kindFromMime } from "../../../../src/media/mime.js"; import { isGifMedia, kindFromMime } from "../../../../src/media/mime.js";
import { getGlobalHookRunner } from "../../../../src/plugins/hook-runner-global.js"; import { getGlobalHookRunner } from "../../../../src/plugins/hook-runner-global.js";
import type { RuntimeEnv } from "../../../../src/runtime.js"; import type { RuntimeEnv } from "../../../../src/runtime.js";
import { loadWebMedia } from "../../../../src/web/media.js"; import { loadWebMedia } from "../../../whatsapp/src/media.js";
import type { TelegramInlineButtons } from "../button-types.js"; import type { TelegramInlineButtons } from "../button-types.js";
import { splitTelegramCaption } from "../caption.js"; import { splitTelegramCaption } from "../caption.js";
import { import {

View File

@ -13,7 +13,6 @@ import {
setOnboardingChannelEnabled, setOnboardingChannelEnabled,
splitOnboardingEntries, splitOnboardingEntries,
} from "../../../src/channels/plugins/onboarding/helpers.js"; } from "../../../src/channels/plugins/onboarding/helpers.js";
import { fetchTelegramChatId } from "../../../src/channels/telegram/api.js";
import { formatCliCommand } from "../../../src/cli/command-format.js"; import { formatCliCommand } from "../../../src/cli/command-format.js";
import type { OpenClawConfig } from "../../../src/config/config.js"; import type { OpenClawConfig } from "../../../src/config/config.js";
import { hasConfiguredSecretInput } from "../../../src/config/types.secrets.js"; import { hasConfiguredSecretInput } from "../../../src/config/types.secrets.js";
@ -26,6 +25,7 @@ import {
resolveDefaultTelegramAccountId, resolveDefaultTelegramAccountId,
resolveTelegramAccount, resolveTelegramAccount,
} from "./accounts.js"; } from "./accounts.js";
import { fetchTelegramChatId } from "./api-fetch.js";
const channel = "telegram" as const; const channel = "telegram" as const;

View File

@ -4,7 +4,10 @@ import {
sendPayloadMediaSequence, sendPayloadMediaSequence,
} from "../../../src/channels/plugins/outbound/direct-text-media.js"; } from "../../../src/channels/plugins/outbound/direct-text-media.js";
import type { ChannelOutboundAdapter } from "../../../src/channels/plugins/types.js"; import type { ChannelOutboundAdapter } from "../../../src/channels/plugins/types.js";
import type { OutboundSendDeps } from "../../../src/infra/outbound/deliver.js"; import {
resolveOutboundSendDep,
type OutboundSendDeps,
} from "../../../src/infra/outbound/deliver.js";
import type { TelegramInlineButtons } from "./button-types.js"; import type { TelegramInlineButtons } from "./button-types.js";
import { markdownToTelegramHtmlChunks } from "./format.js"; import { markdownToTelegramHtmlChunks } from "./format.js";
import { parseTelegramReplyToMessageId, parseTelegramThreadId } from "./outbound-params.js"; import { parseTelegramReplyToMessageId, parseTelegramThreadId } from "./outbound-params.js";
@ -30,7 +33,8 @@ function resolveTelegramSendContext(params: {
accountId?: string; accountId?: string;
}; };
} { } {
const send = params.deps?.sendTelegram ?? sendMessageTelegram; const send =
resolveOutboundSendDep<TelegramSendFn>(params.deps, "telegram") ?? sendMessageTelegram;
return { return {
send, send,
baseOpts: { baseOpts: {

View File

@ -40,7 +40,7 @@ type TelegramSendTestMocks = {
maybePersistResolvedTelegramTarget: MockFn; maybePersistResolvedTelegramTarget: MockFn;
}; };
vi.mock("../../../src/web/media.js", () => ({ vi.mock("../../whatsapp/src/media.js", () => ({
loadWebMedia, loadWebMedia,
})); }));

View File

@ -19,7 +19,7 @@ import type { MediaKind } from "../../../src/media/constants.js";
import { buildOutboundMediaLoadOptions } from "../../../src/media/load-options.js"; import { buildOutboundMediaLoadOptions } from "../../../src/media/load-options.js";
import { isGifMedia, kindFromMime } from "../../../src/media/mime.js"; import { isGifMedia, kindFromMime } from "../../../src/media/mime.js";
import { normalizePollInput, type PollInput } from "../../../src/polls.js"; import { normalizePollInput, type PollInput } from "../../../src/polls.js";
import { loadWebMedia } from "../../../src/web/media.js"; import { loadWebMedia } from "../../whatsapp/src/media.js";
import { type ResolvedTelegramAccount, resolveTelegramAccount } from "./accounts.js"; import { type ResolvedTelegramAccount, resolveTelegramAccount } from "./accounts.js";
import { withTelegramApiErrorLogging } from "./api-logging.js"; import { withTelegramApiErrorLogging } from "./api-logging.js";
import { buildTelegramThreadParams, buildTypingThreadParams } from "./bot/helpers.js"; import { buildTelegramThreadParams, buildTypingThreadParams } from "./bot/helpers.js";

View File

@ -4,11 +4,11 @@ import path from "node:path";
import sharp from "sharp"; import sharp from "sharp";
import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from "vitest"; import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from "vitest";
import { resolveStateDir } from "../../../src/config/paths.js"; import { resolveStateDir } from "../../../src/config/paths.js";
import { sendVoiceMessageDiscord } from "../../../src/discord/send.js";
import { resolvePreferredOpenClawTmpDir } from "../../../src/infra/tmp-openclaw-dir.js"; import { resolvePreferredOpenClawTmpDir } from "../../../src/infra/tmp-openclaw-dir.js";
import { optimizeImageToPng } from "../../../src/media/image-ops.js"; import { optimizeImageToPng } from "../../../src/media/image-ops.js";
import { mockPinnedHostnameResolution } from "../../../src/test-helpers/ssrf.js"; import { mockPinnedHostnameResolution } from "../../../src/test-helpers/ssrf.js";
import { captureEnv } from "../../../src/test-utils/env.js"; import { captureEnv } from "../../../src/test-utils/env.js";
import { sendVoiceMessageDiscord } from "../../discord/src/send.js";
import { import {
LocalMediaAccessError, LocalMediaAccessError,
loadWebMedia, loadWebMedia,

View File

@ -2,8 +2,9 @@ import { chunkText } from "../../../src/auto-reply/chunk.js";
import { sendTextMediaPayload } from "../../../src/channels/plugins/outbound/direct-text-media.js"; import { sendTextMediaPayload } from "../../../src/channels/plugins/outbound/direct-text-media.js";
import type { ChannelOutboundAdapter } from "../../../src/channels/plugins/types.js"; import type { ChannelOutboundAdapter } from "../../../src/channels/plugins/types.js";
import { shouldLogVerbose } from "../../../src/globals.js"; import { shouldLogVerbose } from "../../../src/globals.js";
import { resolveOutboundSendDep } from "../../../src/infra/outbound/deliver.js";
import { resolveWhatsAppOutboundTarget } from "../../../src/whatsapp/resolve-outbound-target.js"; import { resolveWhatsAppOutboundTarget } from "../../../src/whatsapp/resolve-outbound-target.js";
import { sendPollWhatsApp } from "./send.js"; import { sendMessageWhatsApp, sendPollWhatsApp } from "./send.js";
function trimLeadingWhitespace(text: string | undefined): string { function trimLeadingWhitespace(text: string | undefined): string {
return text?.trimStart() ?? ""; return text?.trimStart() ?? "";
@ -40,7 +41,9 @@ export const whatsappOutbound: ChannelOutboundAdapter = {
if (!normalizedText) { if (!normalizedText) {
return { channel: "whatsapp", messageId: "" }; return { channel: "whatsapp", messageId: "" };
} }
const send = deps?.sendWhatsApp ?? (await import("./send.js")).sendMessageWhatsApp; const send =
resolveOutboundSendDep<typeof sendMessageWhatsApp>(deps, "whatsapp") ??
(await import("./send.js")).sendMessageWhatsApp;
const result = await send(to, normalizedText, { const result = await send(to, normalizedText, {
verbose: false, verbose: false,
cfg, cfg,
@ -51,7 +54,9 @@ export const whatsappOutbound: ChannelOutboundAdapter = {
}, },
sendMedia: async ({ cfg, to, text, mediaUrl, mediaLocalRoots, accountId, deps, gifPlayback }) => { sendMedia: async ({ cfg, to, text, mediaUrl, mediaLocalRoots, accountId, deps, gifPlayback }) => {
const normalizedText = trimLeadingWhitespace(text); const normalizedText = trimLeadingWhitespace(text);
const send = deps?.sendWhatsApp ?? (await import("./send.js")).sendMessageWhatsApp; const send =
resolveOutboundSendDep<typeof sendMessageWhatsApp>(deps, "whatsapp") ??
(await import("./send.js")).sendMessageWhatsApp;
const result = await send(to, normalizedText, { const result = await send(to, normalizedText, {
verbose: false, verbose: false,
cfg, cfg,

View File

@ -9,8 +9,8 @@ const rootEntries = [
"src/channels/plugins/actions/discord.ts!", "src/channels/plugins/actions/discord.ts!",
"src/channels/plugins/actions/signal.ts!", "src/channels/plugins/actions/signal.ts!",
"src/channels/plugins/actions/telegram.ts!", "src/channels/plugins/actions/telegram.ts!",
"src/telegram/audit.ts!", "extensions/telegram/src/audit.ts!",
"src/telegram/token.ts!", "extensions/telegram/src/token.ts!",
"src/line/accounts.ts!", "src/line/accounts.ts!",
"src/line/send.ts!", "src/line/send.ts!",
"src/line/template-messages.ts!", "src/line/template-messages.ts!",
@ -69,8 +69,8 @@ const config = {
"src/gateway/live-tool-probe-utils.ts", "src/gateway/live-tool-probe-utils.ts",
"src/gateway/server.auth.shared.ts", "src/gateway/server.auth.shared.ts",
"src/shared/text/assistant-visible-text.ts", "src/shared/text/assistant-visible-text.ts",
"src/telegram/bot/reply-threading.ts", "extensions/telegram/src/bot/reply-threading.ts",
"src/telegram/draft-chunking.ts", "extensions/telegram/src/draft-chunking.ts",
"extensions/msteams/src/conversation-store-memory.ts", "extensions/msteams/src/conversation-store-memory.ts",
"extensions/msteams/src/polls-store-memory.ts", "extensions/msteams/src/polls-store-memory.ts",
"extensions/voice-call/src/providers/index.ts", "extensions/voice-call/src/providers/index.ts",

View File

@ -5,9 +5,9 @@ import ts from "typescript";
import { runCallsiteGuard } from "./lib/callsite-guard.mjs"; import { runCallsiteGuard } from "./lib/callsite-guard.mjs";
import { runAsScript, toLine, unwrapExpression } from "./lib/ts-guard-utils.mjs"; import { runAsScript, toLine, unwrapExpression } from "./lib/ts-guard-utils.mjs";
const sourceRoots = ["src/gateway", "src/discord/voice"]; const sourceRoots = ["src/gateway", "extensions/discord/src/voice"];
const enforcedFiles = new Set([ const enforcedFiles = new Set([
"src/discord/voice/manager.ts", "extensions/discord/src/voice/manager.ts",
"src/gateway/openai-http.ts", "src/gateway/openai-http.ts",
"src/gateway/openresponses-http.ts", "src/gateway/openresponses-http.ts",
"src/gateway/server-methods/agent.ts", "src/gateway/server-methods/agent.ts",

View File

@ -4,18 +4,7 @@ import ts from "typescript";
import { runCallsiteGuard } from "./lib/callsite-guard.mjs"; import { runCallsiteGuard } from "./lib/callsite-guard.mjs";
import { runAsScript, toLine, unwrapExpression } from "./lib/ts-guard-utils.mjs"; import { runAsScript, toLine, unwrapExpression } from "./lib/ts-guard-utils.mjs";
const sourceRoots = [ const sourceRoots = ["src/channels", "src/routing", "src/line", "extensions"];
"src/telegram",
"src/discord",
"src/slack",
"src/signal",
"src/imessage",
"src/web",
"src/channels",
"src/routing",
"src/line",
"extensions",
];
// Temporary allowlist for legacy callsites. New raw fetch callsites in channel/plugin runtime // Temporary allowlist for legacy callsites. New raw fetch callsites in channel/plugin runtime
// code should be rejected and migrated to fetchWithSsrFGuard/shared channel helpers. // code should be rejected and migrated to fetchWithSsrFGuard/shared channel helpers.
@ -54,14 +43,14 @@ const allowedRawFetchCallsites = new Set([
"extensions/voice-call/src/providers/telnyx.ts:61", "extensions/voice-call/src/providers/telnyx.ts:61",
"extensions/voice-call/src/providers/tts-openai.ts:111", "extensions/voice-call/src/providers/tts-openai.ts:111",
"extensions/voice-call/src/providers/twilio/api.ts:23", "extensions/voice-call/src/providers/twilio/api.ts:23",
"src/channels/telegram/api.ts:8", "extensions/telegram/src/api-fetch.ts:8",
"src/discord/send.outbound.ts:347", "extensions/discord/src/send.outbound.ts:363",
"src/discord/voice-message.ts:264", "extensions/discord/src/voice-message.ts:268",
"src/discord/voice-message.ts:308", "extensions/discord/src/voice-message.ts:312",
"src/slack/monitor/media.ts:64", "extensions/slack/src/monitor/media.ts:55",
"src/slack/monitor/media.ts:68", "extensions/slack/src/monitor/media.ts:59",
"src/slack/monitor/media.ts:82", "extensions/slack/src/monitor/media.ts:73",
"src/slack/monitor/media.ts:108", "extensions/slack/src/monitor/media.ts:99",
]); ]);
function isRawFetchCall(expression) { function isRawFetchCall(expression) {

View File

@ -1,7 +1,7 @@
import { sendMessageTelegram } from "../../extensions/telegram/src/send.js";
import { loadConfig } from "../../src/config/config.js"; import { loadConfig } from "../../src/config/config.js";
import { matchPluginCommand, executePluginCommand } from "../../src/plugins/commands.js"; import { matchPluginCommand, executePluginCommand } from "../../src/plugins/commands.js";
import { loadOpenClawPlugins } from "../../src/plugins/loader.js"; import { loadOpenClawPlugins } from "../../src/plugins/loader.js";
import { sendMessageTelegram } from "../../src/telegram/send.js";
const args = process.argv.slice(2); const args = process.argv.slice(2);
const getArg = (flag: string, short?: string) => { const getArg = (flag: string, short?: string) => {

View File

@ -42,8 +42,8 @@ const unitIsolatedFilesRaw = [
"src/commands/agent.test.ts", "src/commands/agent.test.ts",
"src/media/store.test.ts", "src/media/store.test.ts",
"src/media/store.header-ext.test.ts", "src/media/store.header-ext.test.ts",
"src/web/media.test.ts", "extensions/whatsapp/src/media.test.ts",
"src/web/auto-reply.web-auto-reply.falls-back-text-media-send-fails.test.ts", "extensions/whatsapp/src/auto-reply.web-auto-reply.falls-back-text-media-send-fails.test.ts",
"src/browser/server.covers-additional-endpoint-branches.test.ts", "src/browser/server.covers-additional-endpoint-branches.test.ts",
"src/browser/server.post-tabs-open-profile-unknown-returns-404.test.ts", "src/browser/server.post-tabs-open-profile-unknown-returns-404.test.ts",
"src/browser/server.agent-contract-snapshot-endpoints.test.ts", "src/browser/server.agent-contract-snapshot-endpoints.test.ts",
@ -80,15 +80,15 @@ const unitIsolatedFilesRaw = [
"src/auto-reply/reply.triggers.trigger-handling.targets-active-session-native-stop.test.ts", "src/auto-reply/reply.triggers.trigger-handling.targets-active-session-native-stop.test.ts",
"src/auto-reply/reply.triggers.group-intro-prompts.test.ts", "src/auto-reply/reply.triggers.group-intro-prompts.test.ts",
"src/auto-reply/reply.triggers.trigger-handling.handles-inline-commands-strips-it-before-agent.test.ts", "src/auto-reply/reply.triggers.trigger-handling.handles-inline-commands-strips-it-before-agent.test.ts",
"src/web/auto-reply.web-auto-reply.compresses-common-formats-jpeg-cap.test.ts", "extensions/whatsapp/src/auto-reply.web-auto-reply.compresses-common-formats-jpeg-cap.test.ts",
// Setup-heavy bot bootstrap suite. // Setup-heavy bot bootstrap suite.
"src/telegram/bot.create-telegram-bot.test.ts", "extensions/telegram/src/bot.create-telegram-bot.test.ts",
// Medium-heavy bot behavior suite; move off unit-fast critical path. // Medium-heavy bot behavior suite; move off unit-fast critical path.
"src/telegram/bot.test.ts", "extensions/telegram/src/bot.test.ts",
// Slack slash registration tests are setup-heavy and can bottleneck unit-fast. // Slack slash registration tests are setup-heavy and can bottleneck unit-fast.
"src/slack/monitor/slash.test.ts", "extensions/slack/src/monitor/slash.test.ts",
// Uses process-level unhandledRejection listeners; keep it off vmForks to avoid cross-file leakage. // Uses process-level unhandledRejection listeners; keep it off vmForks to avoid cross-file leakage.
"src/imessage/monitor.shutdown.unhandled-rejection.test.ts", "extensions/imessage/src/monitor.shutdown.unhandled-rejection.test.ts",
// Mutates process.cwd() and mocks core module loaders; isolate from the shared fast lane. // Mutates process.cwd() and mocks core module loaders; isolate from the shared fast lane.
"src/infra/git-commit.test.ts", "src/infra/git-commit.test.ts",
]; ];
@ -303,7 +303,13 @@ const passthroughRequiresSingleRun = passthroughOptionArgs.some((arg) => {
const [flag] = arg.split("=", 1); const [flag] = arg.split("=", 1);
return SINGLE_RUN_ONLY_FLAGS.has(flag); return SINGLE_RUN_ONLY_FLAGS.has(flag);
}); });
const channelPrefixes = ["src/telegram/", "src/discord/", "src/web/", "src/browser/", "src/line/"]; const channelPrefixes = [
"extensions/telegram/",
"extensions/discord/",
"extensions/whatsapp/",
"src/browser/",
"src/line/",
];
const baseConfigPrefixes = ["src/agents/", "src/auto-reply/", "src/commands/", "test/", "ui/"]; const baseConfigPrefixes = ["src/agents/", "src/auto-reply/", "src/commands/", "test/", "ui/"];
const normalizeRepoPath = (value) => value.split(path.sep).join("/"); const normalizeRepoPath = (value) => value.split(path.sep).join("/");
const walkTestFiles = (rootDir) => { const walkTestFiles = (rootDir) => {

View File

@ -7,6 +7,9 @@ import {
estimateTokens, estimateTokens,
SessionManager, SessionManager,
} from "@mariozechner/pi-coding-agent"; } from "@mariozechner/pi-coding-agent";
import { resolveSignalReactionLevel } from "../../../extensions/signal/src/reaction-level.js";
import { resolveTelegramInlineButtonsScope } from "../../../extensions/telegram/src/inline-buttons.js";
import { resolveTelegramReactionLevel } from "../../../extensions/telegram/src/reaction-level.js";
import { resolveHeartbeatPrompt } from "../../auto-reply/heartbeat.js"; import { resolveHeartbeatPrompt } from "../../auto-reply/heartbeat.js";
import type { ReasoningLevel, ThinkLevel } from "../../auto-reply/thinking.js"; import type { ReasoningLevel, ThinkLevel } from "../../auto-reply/thinking.js";
import { resolveChannelCapabilities } from "../../config/channel-capabilities.js"; import { resolveChannelCapabilities } from "../../config/channel-capabilities.js";
@ -23,9 +26,6 @@ import { getGlobalHookRunner } from "../../plugins/hook-runner-global.js";
import { type enqueueCommand, enqueueCommandInLane } from "../../process/command-queue.js"; import { type enqueueCommand, enqueueCommandInLane } from "../../process/command-queue.js";
import { isCronSessionKey, isSubagentSessionKey } from "../../routing/session-key.js"; import { isCronSessionKey, isSubagentSessionKey } from "../../routing/session-key.js";
import { emitSessionTranscriptUpdate } from "../../sessions/transcript-events.js"; import { emitSessionTranscriptUpdate } from "../../sessions/transcript-events.js";
import { resolveSignalReactionLevel } from "../../signal/reaction-level.js";
import { resolveTelegramInlineButtonsScope } from "../../telegram/inline-buttons.js";
import { resolveTelegramReactionLevel } from "../../telegram/reaction-level.js";
import { buildTtsSystemPromptHint } from "../../tts/tts.js"; import { buildTtsSystemPromptHint } from "../../tts/tts.js";
import { resolveUserPath } from "../../utils.js"; import { resolveUserPath } from "../../utils.js";
import { normalizeMessageChannel } from "../../utils/message-channel.js"; import { normalizeMessageChannel } from "../../utils/message-channel.js";

View File

@ -7,6 +7,9 @@ import {
DefaultResourceLoader, DefaultResourceLoader,
SessionManager, SessionManager,
} from "@mariozechner/pi-coding-agent"; } from "@mariozechner/pi-coding-agent";
import { resolveSignalReactionLevel } from "../../../../extensions/signal/src/reaction-level.js";
import { resolveTelegramInlineButtonsScope } from "../../../../extensions/telegram/src/inline-buttons.js";
import { resolveTelegramReactionLevel } from "../../../../extensions/telegram/src/reaction-level.js";
import { resolveHeartbeatPrompt } from "../../../auto-reply/heartbeat.js"; import { resolveHeartbeatPrompt } from "../../../auto-reply/heartbeat.js";
import { resolveChannelCapabilities } from "../../../config/channel-capabilities.js"; import { resolveChannelCapabilities } from "../../../config/channel-capabilities.js";
import type { OpenClawConfig } from "../../../config/config.js"; import type { OpenClawConfig } from "../../../config/config.js";
@ -24,9 +27,6 @@ import type {
} from "../../../plugins/types.js"; } from "../../../plugins/types.js";
import { isCronSessionKey, isSubagentSessionKey } from "../../../routing/session-key.js"; import { isCronSessionKey, isSubagentSessionKey } from "../../../routing/session-key.js";
import { joinPresentTextSegments } from "../../../shared/text/join-segments.js"; import { joinPresentTextSegments } from "../../../shared/text/join-segments.js";
import { resolveSignalReactionLevel } from "../../../signal/reaction-level.js";
import { resolveTelegramInlineButtonsScope } from "../../../telegram/inline-buttons.js";
import { resolveTelegramReactionLevel } from "../../../telegram/reaction-level.js";
import { buildTtsSystemPromptHint } from "../../../tts/tts.js"; import { buildTtsSystemPromptHint } from "../../../tts/tts.js";
import { resolveUserPath } from "../../../utils.js"; import { resolveUserPath } from "../../../utils.js";
import { normalizeMessageChannel } from "../../../utils/message-channel.js"; import { normalizeMessageChannel } from "../../../utils/message-channel.js";

View File

@ -1,8 +1,8 @@
import path from "node:path"; import path from "node:path";
import { fileURLToPath } from "node:url"; import { fileURLToPath } from "node:url";
import type { ImageContent } from "@mariozechner/pi-ai"; import type { ImageContent } from "@mariozechner/pi-ai";
import { loadWebMedia } from "../../../../extensions/whatsapp/src/media.js";
import { resolveUserPath } from "../../../utils.js"; import { resolveUserPath } from "../../../utils.js";
import { loadWebMedia } from "../../../web/media.js";
import type { ImageSanitizationLimits } from "../../image-sanitization.js"; import type { ImageSanitizationLimits } from "../../image-sanitization.js";
import { import {
createSandboxBridgeReadFile, createSandboxBridgeReadFile,

View File

@ -1,6 +1,5 @@
import type { AgentToolResult } from "@mariozechner/pi-agent-core"; import type { AgentToolResult } from "@mariozechner/pi-agent-core";
import type { DiscordActionConfig } from "../../config/config.js"; import { getPresence } from "../../../extensions/discord/src/monitor/presence-cache.js";
import { getPresence } from "../../discord/monitor/presence-cache.js";
import { import {
addRoleDiscord, addRoleDiscord,
createChannelDiscord, createChannelDiscord,
@ -20,7 +19,8 @@ import {
setChannelPermissionDiscord, setChannelPermissionDiscord,
uploadEmojiDiscord, uploadEmojiDiscord,
uploadStickerDiscord, uploadStickerDiscord,
} from "../../discord/send.js"; } from "../../../extensions/discord/src/send.js";
import type { DiscordActionConfig } from "../../config/config.js";
import { import {
type ActionGate, type ActionGate,
jsonResult, jsonResult,

View File

@ -1,7 +1,5 @@
import type { AgentToolResult } from "@mariozechner/pi-agent-core"; import type { AgentToolResult } from "@mariozechner/pi-agent-core";
import type { DiscordActionConfig } from "../../config/config.js"; import { readDiscordComponentSpec } from "../../../extensions/discord/src/components.js";
import type { OpenClawConfig } from "../../config/config.js";
import { readDiscordComponentSpec } from "../../discord/components.js";
import { import {
createThreadDiscord, createThreadDiscord,
deleteMessageDiscord, deleteMessageDiscord,
@ -23,9 +21,14 @@ import {
sendStickerDiscord, sendStickerDiscord,
sendVoiceMessageDiscord, sendVoiceMessageDiscord,
unpinMessageDiscord, unpinMessageDiscord,
} from "../../discord/send.js"; } from "../../../extensions/discord/src/send.js";
import type { DiscordSendComponents, DiscordSendEmbeds } from "../../discord/send.shared.js"; import type {
import { resolveDiscordChannelId } from "../../discord/targets.js"; DiscordSendComponents,
DiscordSendEmbeds,
} from "../../../extensions/discord/src/send.shared.js";
import { resolveDiscordChannelId } from "../../../extensions/discord/src/targets.js";
import type { DiscordActionConfig } from "../../config/config.js";
import type { OpenClawConfig } from "../../config/config.js";
import { readBooleanParam } from "../../plugin-sdk/boolean-param.js"; import { readBooleanParam } from "../../plugin-sdk/boolean-param.js";
import { resolvePollMaxSelections } from "../../polls.js"; import { resolvePollMaxSelections } from "../../polls.js";
import { withNormalizedTimestamp } from "../date-time.js"; import { withNormalizedTimestamp } from "../date-time.js";

View File

@ -13,7 +13,7 @@ const discordSendMocks = vi.hoisted(() => ({
const { banMemberDiscord, kickMemberDiscord, timeoutMemberDiscord, hasAnyGuildPermissionDiscord } = const { banMemberDiscord, kickMemberDiscord, timeoutMemberDiscord, hasAnyGuildPermissionDiscord } =
discordSendMocks; discordSendMocks;
vi.mock("../../discord/send.js", () => ({ vi.mock("../../../extensions/discord/src/send.js", () => ({
...discordSendMocks, ...discordSendMocks,
})); }));

View File

@ -1,11 +1,11 @@
import type { AgentToolResult } from "@mariozechner/pi-agent-core"; import type { AgentToolResult } from "@mariozechner/pi-agent-core";
import type { DiscordActionConfig } from "../../config/config.js";
import { import {
banMemberDiscord, banMemberDiscord,
hasAnyGuildPermissionDiscord, hasAnyGuildPermissionDiscord,
kickMemberDiscord, kickMemberDiscord,
timeoutMemberDiscord, timeoutMemberDiscord,
} from "../../discord/send.js"; } from "../../../extensions/discord/src/send.js";
import type { DiscordActionConfig } from "../../config/config.js";
import { type ActionGate, jsonResult, readStringParam } from "./common.js"; import { type ActionGate, jsonResult, readStringParam } from "./common.js";
import { import {
isDiscordModerationAction, isDiscordModerationAction,

View File

@ -1,7 +1,10 @@
import type { GatewayPlugin } from "@buape/carbon/gateway"; import type { GatewayPlugin } from "@buape/carbon/gateway";
import { beforeEach, describe, expect, it, vi } from "vitest"; import { beforeEach, describe, expect, it, vi } from "vitest";
import {
clearGateways,
registerGateway,
} from "../../../extensions/discord/src/monitor/gateway-registry.js";
import type { DiscordActionConfig } from "../../config/config.js"; import type { DiscordActionConfig } from "../../config/config.js";
import { clearGateways, registerGateway } from "../../discord/monitor/gateway-registry.js";
import type { ActionGate } from "./common.js"; import type { ActionGate } from "./common.js";
import { handleDiscordPresenceAction } from "./discord-actions-presence.js"; import { handleDiscordPresenceAction } from "./discord-actions-presence.js";

View File

@ -1,7 +1,7 @@
import type { Activity, UpdatePresenceData } from "@buape/carbon/gateway"; import type { Activity, UpdatePresenceData } from "@buape/carbon/gateway";
import type { AgentToolResult } from "@mariozechner/pi-agent-core"; import type { AgentToolResult } from "@mariozechner/pi-agent-core";
import { getGateway } from "../../../extensions/discord/src/monitor/gateway-registry.js";
import type { DiscordActionConfig } from "../../config/config.js"; import type { DiscordActionConfig } from "../../config/config.js";
import { getGateway } from "../../discord/monitor/gateway-registry.js";
import { type ActionGate, jsonResult, readStringParam } from "./common.js"; import { type ActionGate, jsonResult, readStringParam } from "./common.js";
const ACTIVITY_TYPE_MAP: Record<string, number> = { const ACTIVITY_TYPE_MAP: Record<string, number> = {

View File

@ -67,7 +67,7 @@ const {
timeoutMemberDiscord, timeoutMemberDiscord,
} = discordSendMocks; } = discordSendMocks;
vi.mock("../../discord/send.js", () => ({ vi.mock("../../../extensions/discord/src/send.js", () => ({
...discordSendMocks, ...discordSendMocks,
})); }));

View File

@ -1,6 +1,6 @@
import type { AgentToolResult } from "@mariozechner/pi-agent-core"; import type { AgentToolResult } from "@mariozechner/pi-agent-core";
import { createDiscordActionGate } from "../../../extensions/discord/src/accounts.js";
import type { OpenClawConfig } from "../../config/config.js"; import type { OpenClawConfig } from "../../config/config.js";
import { createDiscordActionGate } from "../../discord/accounts.js";
import { readStringParam } from "./common.js"; import { readStringParam } from "./common.js";
import { handleDiscordGuildAction } from "./discord-actions-guild.js"; import { handleDiscordGuildAction } from "./discord-actions-guild.js";
import { handleDiscordMessagingAction } from "./discord-actions-messaging.js"; import { handleDiscordMessagingAction } from "./discord-actions-messaging.js";

View File

@ -1,8 +1,8 @@
import { type Context, complete } from "@mariozechner/pi-ai"; import { type Context, complete } from "@mariozechner/pi-ai";
import { Type } from "@sinclair/typebox"; import { Type } from "@sinclair/typebox";
import { loadWebMedia } from "../../../extensions/whatsapp/src/media.js";
import type { OpenClawConfig } from "../../config/config.js"; import type { OpenClawConfig } from "../../config/config.js";
import { resolveUserPath } from "../../utils.js"; import { resolveUserPath } from "../../utils.js";
import { loadWebMedia } from "../../web/media.js";
import { isMinimaxVlmModel, isMinimaxVlmProvider, minimaxUnderstandImage } from "../minimax-vlm.js"; import { isMinimaxVlmModel, isMinimaxVlmProvider, minimaxUnderstandImage } from "../minimax-vlm.js";
import { import {
coerceImageAssistantText, coerceImageAssistantText,

View File

@ -1,6 +1,6 @@
import { type Api, type Model } from "@mariozechner/pi-ai"; import { type Api, type Model } from "@mariozechner/pi-ai";
import { getDefaultLocalRoots } from "../../../extensions/whatsapp/src/media.js";
import type { OpenClawConfig } from "../../config/config.js"; import type { OpenClawConfig } from "../../config/config.js";
import { getDefaultLocalRoots } from "../../web/media.js";
import type { ImageModelConfig } from "./image-tool.helpers.js"; import type { ImageModelConfig } from "./image-tool.helpers.js";
import { getApiKeyForModel, normalizeWorkspaceDir, requireApiKey } from "./tool-runtime.helpers.js"; import { getApiKeyForModel, normalizeWorkspaceDir, requireApiKey } from "./tool-runtime.helpers.js";

View File

@ -131,7 +131,7 @@ async function stubPdfToolInfra(
modelFound?: boolean; modelFound?: boolean;
}, },
) { ) {
const webMedia = await import("../../web/media.js"); const webMedia = await import("../../../extensions/whatsapp/src/media.js");
const loadSpy = vi.spyOn(webMedia, "loadWebMediaRaw").mockResolvedValue(FAKE_PDF_MEDIA as never); const loadSpy = vi.spyOn(webMedia, "loadWebMediaRaw").mockResolvedValue(FAKE_PDF_MEDIA as never);
const modelDiscovery = await import("../pi-model-discovery.js"); const modelDiscovery = await import("../pi-model-discovery.js");

View File

@ -1,9 +1,9 @@
import { type Context, complete } from "@mariozechner/pi-ai"; import { type Context, complete } from "@mariozechner/pi-ai";
import { Type } from "@sinclair/typebox"; import { Type } from "@sinclair/typebox";
import { loadWebMediaRaw } from "../../../extensions/whatsapp/src/media.js";
import type { OpenClawConfig } from "../../config/config.js"; import type { OpenClawConfig } from "../../config/config.js";
import { extractPdfContent, type PdfExtractedContent } from "../../media/pdf-extract.js"; import { extractPdfContent, type PdfExtractedContent } from "../../media/pdf-extract.js";
import { resolveUserPath } from "../../utils.js"; import { resolveUserPath } from "../../utils.js";
import { loadWebMediaRaw } from "../../web/media.js";
import { import {
coerceImageModelConfig, coerceImageModelConfig,
type ImageModelConfig, type ImageModelConfig,

View File

@ -17,7 +17,7 @@ const removeSlackReaction = vi.fn(async (..._args: unknown[]) => ({}));
const sendSlackMessage = vi.fn(async (..._args: unknown[]) => ({})); const sendSlackMessage = vi.fn(async (..._args: unknown[]) => ({}));
const unpinSlackMessage = vi.fn(async (..._args: unknown[]) => ({})); const unpinSlackMessage = vi.fn(async (..._args: unknown[]) => ({}));
vi.mock("../../slack/actions.js", () => ({ vi.mock("../../../extensions/slack/src/actions.js", () => ({
deleteSlackMessage: (...args: Parameters<typeof deleteSlackMessage>) => deleteSlackMessage: (...args: Parameters<typeof deleteSlackMessage>) =>
deleteSlackMessage(...args), deleteSlackMessage(...args),
downloadSlackFile: (...args: Parameters<typeof downloadSlackFile>) => downloadSlackFile(...args), downloadSlackFile: (...args: Parameters<typeof downloadSlackFile>) => downloadSlackFile(...args),

View File

@ -1,6 +1,5 @@
import type { AgentToolResult } from "@mariozechner/pi-agent-core"; import type { AgentToolResult } from "@mariozechner/pi-agent-core";
import type { OpenClawConfig } from "../../config/config.js"; import { resolveSlackAccount } from "../../../extensions/slack/src/accounts.js";
import { resolveSlackAccount } from "../../slack/accounts.js";
import { import {
deleteSlackMessage, deleteSlackMessage,
downloadSlackFile, downloadSlackFile,
@ -16,10 +15,11 @@ import {
removeSlackReaction, removeSlackReaction,
sendSlackMessage, sendSlackMessage,
unpinSlackMessage, unpinSlackMessage,
} from "../../slack/actions.js"; } from "../../../extensions/slack/src/actions.js";
import { parseSlackBlocksInput } from "../../slack/blocks-input.js"; import { parseSlackBlocksInput } from "../../../extensions/slack/src/blocks-input.js";
import { recordSlackThreadParticipation } from "../../slack/sent-thread-cache.js"; import { recordSlackThreadParticipation } from "../../../extensions/slack/src/sent-thread-cache.js";
import { parseSlackTarget, resolveSlackChannelId } from "../../slack/targets.js"; import { parseSlackTarget, resolveSlackChannelId } from "../../../extensions/slack/src/targets.js";
import type { OpenClawConfig } from "../../config/config.js";
import { withNormalizedTimestamp } from "../date-time.js"; import { withNormalizedTimestamp } from "../date-time.js";
import { import {
createActionGate, createActionGate,

View File

@ -30,7 +30,7 @@ const createForumTopicTelegram = vi.fn(async () => ({
})); }));
let envSnapshot: ReturnType<typeof captureEnv>; let envSnapshot: ReturnType<typeof captureEnv>;
vi.mock("../../telegram/send.js", () => ({ vi.mock("../../../extensions/telegram/src/send.js", () => ({
reactMessageTelegram: (...args: Parameters<typeof reactMessageTelegram>) => reactMessageTelegram: (...args: Parameters<typeof reactMessageTelegram>) =>
reactMessageTelegram(...args), reactMessageTelegram(...args),
sendMessageTelegram: (...args: Parameters<typeof sendMessageTelegram>) => sendMessageTelegram: (...args: Parameters<typeof sendMessageTelegram>) =>

View File

@ -1,17 +1,17 @@
import type { AgentToolResult } from "@mariozechner/pi-agent-core"; import type { AgentToolResult } from "@mariozechner/pi-agent-core";
import type { OpenClawConfig } from "../../config/config.js";
import { readBooleanParam } from "../../plugin-sdk/boolean-param.js";
import { resolvePollMaxSelections } from "../../polls.js";
import { import {
createTelegramActionGate, createTelegramActionGate,
resolveTelegramPollActionGateState, resolveTelegramPollActionGateState,
} from "../../telegram/accounts.js"; } from "../../../extensions/telegram/src/accounts.js";
import type { TelegramButtonStyle, TelegramInlineButtons } from "../../telegram/button-types.js"; import type {
TelegramButtonStyle,
TelegramInlineButtons,
} from "../../../extensions/telegram/src/button-types.js";
import { import {
resolveTelegramInlineButtonsScope, resolveTelegramInlineButtonsScope,
resolveTelegramTargetChatType, resolveTelegramTargetChatType,
} from "../../telegram/inline-buttons.js"; } from "../../../extensions/telegram/src/inline-buttons.js";
import { resolveTelegramReactionLevel } from "../../telegram/reaction-level.js"; import { resolveTelegramReactionLevel } from "../../../extensions/telegram/src/reaction-level.js";
import { import {
createForumTopicTelegram, createForumTopicTelegram,
deleteMessageTelegram, deleteMessageTelegram,
@ -20,9 +20,12 @@ import {
sendMessageTelegram, sendMessageTelegram,
sendPollTelegram, sendPollTelegram,
sendStickerTelegram, sendStickerTelegram,
} from "../../telegram/send.js"; } from "../../../extensions/telegram/src/send.js";
import { getCacheStats, searchStickers } from "../../telegram/sticker-cache.js"; import { getCacheStats, searchStickers } from "../../../extensions/telegram/src/sticker-cache.js";
import { resolveTelegramToken } from "../../telegram/token.js"; import { resolveTelegramToken } from "../../../extensions/telegram/src/token.js";
import type { OpenClawConfig } from "../../config/config.js";
import { readBooleanParam } from "../../plugin-sdk/boolean-param.js";
import { resolvePollMaxSelections } from "../../polls.js";
import { import {
jsonResult, jsonResult,
readNumberParam, readNumberParam,

View File

@ -1,6 +1,6 @@
import type { AgentToolResult } from "@mariozechner/pi-agent-core"; import type { AgentToolResult } from "@mariozechner/pi-agent-core";
import { sendReactionWhatsApp } from "../../../extensions/whatsapp/src/send.js";
import type { OpenClawConfig } from "../../config/config.js"; import type { OpenClawConfig } from "../../config/config.js";
import { sendReactionWhatsApp } from "../../web/outbound.js";
import { createActionGate, jsonResult, readReactionParams, readStringParam } from "./common.js"; import { createActionGate, jsonResult, readReactionParams, readStringParam } from "./common.js";
import { resolveAuthorizedWhatsAppOutboundTarget } from "./whatsapp-target-auth.js"; import { resolveAuthorizedWhatsAppOutboundTarget } from "./whatsapp-target-auth.js";

View File

@ -1,5 +1,5 @@
import { resolveWhatsAppAccount } from "../../../extensions/whatsapp/src/accounts.js";
import type { OpenClawConfig } from "../../config/config.js"; import type { OpenClawConfig } from "../../config/config.js";
import { resolveWhatsAppAccount } from "../../web/accounts.js";
import { resolveWhatsAppOutboundTarget } from "../../whatsapp/resolve-outbound-target.js"; import { resolveWhatsAppOutboundTarget } from "../../whatsapp/resolve-outbound-target.js";
import { ToolAuthorizationError } from "./common.js"; import { ToolAuthorizationError } from "./common.js";

View File

@ -101,7 +101,7 @@ export function getWebSessionMocks(): AnyMocks {
return webSessionMocks; return webSessionMocks;
} }
vi.mock("../web/session.js", () => webSessionMocks); vi.mock("../../extensions/whatsapp/src/session.js", () => webSessionMocks);
export const MAIN_SESSION_KEY = "agent:main:main"; export const MAIN_SESSION_KEY = "agent:main:main";

View File

@ -105,7 +105,7 @@ vi.mock("../../infra/outbound/session-binding-service.js", async (importOriginal
}); });
// Prevent transitive import chain from reaching discord/monitor which needs https-proxy-agent. // Prevent transitive import chain from reaching discord/monitor which needs https-proxy-agent.
vi.mock("../../discord/monitor/gateway-plugin.js", () => ({ vi.mock("../../../extensions/discord/src/monitor/gateway-plugin.js", () => ({
createDiscordGatewayPlugin: () => ({}), createDiscordGatewayPlugin: () => ({}),
})); }));

View File

@ -1,3 +1,11 @@
import { resolveDiscordAccount } from "../../../extensions/discord/src/accounts.js";
import { resolveDiscordUserAllowlist } from "../../../extensions/discord/src/resolve-users.js";
import { resolveIMessageAccount } from "../../../extensions/imessage/src/accounts.js";
import { resolveSignalAccount } from "../../../extensions/signal/src/accounts.js";
import { resolveSlackAccount } from "../../../extensions/slack/src/accounts.js";
import { resolveSlackUserAllowlist } from "../../../extensions/slack/src/resolve-users.js";
import { resolveTelegramAccount } from "../../../extensions/telegram/src/accounts.js";
import { resolveWhatsAppAccount } from "../../../extensions/whatsapp/src/accounts.js";
import { getChannelDock } from "../../channels/dock.js"; import { getChannelDock } from "../../channels/dock.js";
import { resolveExplicitConfigWriteTarget } from "../../channels/plugins/config-writes.js"; import { resolveExplicitConfigWriteTarget } from "../../channels/plugins/config-writes.js";
import { listPairingChannels } from "../../channels/plugins/pairing.js"; import { listPairingChannels } from "../../channels/plugins/pairing.js";
@ -9,9 +17,6 @@ import {
validateConfigObjectWithPlugins, validateConfigObjectWithPlugins,
writeConfigFile, writeConfigFile,
} from "../../config/config.js"; } from "../../config/config.js";
import { resolveDiscordAccount } from "../../discord/accounts.js";
import { resolveDiscordUserAllowlist } from "../../discord/resolve-users.js";
import { resolveIMessageAccount } from "../../imessage/accounts.js";
import { isBlockedObjectKey } from "../../infra/prototype-keys.js"; import { isBlockedObjectKey } from "../../infra/prototype-keys.js";
import { import {
addChannelAllowFromStoreEntry, addChannelAllowFromStoreEntry,
@ -24,11 +29,6 @@ import {
normalizeOptionalAccountId, normalizeOptionalAccountId,
} from "../../routing/session-key.js"; } from "../../routing/session-key.js";
import { normalizeStringEntries } from "../../shared/string-normalization.js"; import { normalizeStringEntries } from "../../shared/string-normalization.js";
import { resolveSignalAccount } from "../../signal/accounts.js";
import { resolveSlackAccount } from "../../slack/accounts.js";
import { resolveSlackUserAllowlist } from "../../slack/resolve-users.js";
import { resolveTelegramAccount } from "../../telegram/accounts.js";
import { resolveWhatsAppAccount } from "../../web/accounts.js";
import { rejectUnauthorizedCommand, requireCommandFlagEnabled } from "./command-gates.js"; import { rejectUnauthorizedCommand, requireCommandFlagEnabled } from "./command-gates.js";
import type { CommandHandler } from "./commands-types.js"; import type { CommandHandler } from "./commands-types.js";
import { resolveConfigWriteDeniedText } from "./config-write-authorization.js"; import { resolveConfigWriteDeniedText } from "./config-write-authorization.js";

View File

@ -1,9 +1,9 @@
import { callGateway } from "../../gateway/call.js";
import { logVerbose } from "../../globals.js";
import { import {
isTelegramExecApprovalApprover, isTelegramExecApprovalApprover,
isTelegramExecApprovalClientEnabled, isTelegramExecApprovalClientEnabled,
} from "../../telegram/exec-approvals.js"; } from "../../../extensions/telegram/src/exec-approvals.js";
import { callGateway } from "../../gateway/call.js";
import { logVerbose } from "../../globals.js";
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../../utils/message-channel.js"; import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../../utils/message-channel.js";
import { requireGatewayClientScopeForInternalChannel } from "./command-gates.js"; import { requireGatewayClientScopeForInternalChannel } from "./command-gates.js";
import type { CommandHandler } from "./commands-types.js"; import type { CommandHandler } from "./commands-types.js";

View File

@ -1,3 +1,10 @@
import {
buildModelsKeyboard,
buildProviderKeyboard,
calculateTotalPages,
getModelsPageSize,
type ProviderInfo,
} from "../../../extensions/telegram/src/model-buttons.js";
import { resolveAgentDir, resolveSessionAgentId } from "../../agents/agent-scope.js"; import { resolveAgentDir, resolveSessionAgentId } from "../../agents/agent-scope.js";
import { resolveModelAuthLabel } from "../../agents/model-auth-label.js"; import { resolveModelAuthLabel } from "../../agents/model-auth-label.js";
import { loadModelCatalog } from "../../agents/model-catalog.js"; import { loadModelCatalog } from "../../agents/model-catalog.js";
@ -10,13 +17,6 @@ import {
} from "../../agents/model-selection.js"; } from "../../agents/model-selection.js";
import type { OpenClawConfig } from "../../config/config.js"; import type { OpenClawConfig } from "../../config/config.js";
import type { SessionEntry } from "../../config/sessions.js"; import type { SessionEntry } from "../../config/sessions.js";
import {
buildModelsKeyboard,
buildProviderKeyboard,
calculateTotalPages,
getModelsPageSize,
type ProviderInfo,
} from "../../telegram/model-buttons.js";
import type { ReplyPayload } from "../types.js"; import type { ReplyPayload } from "../types.js";
import { rejectUnauthorizedCommand } from "./command-gates.js"; import { rejectUnauthorizedCommand } from "./command-gates.js";
import type { CommandHandler } from "./commands-types.js"; import type { CommandHandler } from "./commands-types.js";

View File

@ -19,8 +19,11 @@ const hoisted = vi.hoisted(() => {
}; };
}); });
vi.mock("../../discord/monitor/thread-bindings.js", async (importOriginal) => { vi.mock("../../../extensions/discord/src/monitor/thread-bindings.js", async (importOriginal) => {
const actual = await importOriginal<typeof import("../../discord/monitor/thread-bindings.js")>(); const actual =
await importOriginal<
typeof import("../../../extensions/discord/src/monitor/thread-bindings.js")
>();
return { return {
...actual, ...actual,
getThreadBindingManager: hoisted.getThreadBindingManagerMock, getThreadBindingManager: hoisted.getThreadBindingManagerMock,
@ -29,8 +32,9 @@ vi.mock("../../discord/monitor/thread-bindings.js", async (importOriginal) => {
}; };
}); });
vi.mock("../../telegram/thread-bindings.js", async (importOriginal) => { vi.mock("../../../extensions/telegram/src/thread-bindings.js", async (importOriginal) => {
const actual = await importOriginal<typeof import("../../telegram/thread-bindings.js")>(); const actual =
await importOriginal<typeof import("../../../extensions/telegram/src/thread-bindings.js")>();
return { return {
...actual, ...actual,
setTelegramThreadBindingIdleTimeoutBySessionKey: setTelegramThreadBindingIdleTimeoutBySessionKey:

View File

@ -1,6 +1,3 @@
import { resolveFastModeState } from "../../agents/fast-mode.js";
import { parseDurationMs } from "../../cli/parse-duration.js";
import { isRestartEnabled } from "../../config/commands.js";
import { import {
formatThreadBindingDurationLabel, formatThreadBindingDurationLabel,
getThreadBindingManager, getThreadBindingManager,
@ -10,16 +7,19 @@ import {
resolveThreadBindingMaxAgeMs, resolveThreadBindingMaxAgeMs,
setThreadBindingIdleTimeoutBySessionKey, setThreadBindingIdleTimeoutBySessionKey,
setThreadBindingMaxAgeBySessionKey, setThreadBindingMaxAgeBySessionKey,
} from "../../discord/monitor/thread-bindings.js"; } from "../../../extensions/discord/src/monitor/thread-bindings.js";
import {
setTelegramThreadBindingIdleTimeoutBySessionKey,
setTelegramThreadBindingMaxAgeBySessionKey,
} from "../../../extensions/telegram/src/thread-bindings.js";
import { resolveFastModeState } from "../../agents/fast-mode.js";
import { parseDurationMs } from "../../cli/parse-duration.js";
import { isRestartEnabled } from "../../config/commands.js";
import { logVerbose } from "../../globals.js"; import { logVerbose } from "../../globals.js";
import { getSessionBindingService } from "../../infra/outbound/session-binding-service.js"; import { getSessionBindingService } from "../../infra/outbound/session-binding-service.js";
import type { SessionBindingRecord } from "../../infra/outbound/session-binding-service.js"; import type { SessionBindingRecord } from "../../infra/outbound/session-binding-service.js";
import { scheduleGatewaySigusr1Restart, triggerOpenClawRestart } from "../../infra/restart.js"; import { scheduleGatewaySigusr1Restart, triggerOpenClawRestart } from "../../infra/restart.js";
import { loadCostUsageSummary, loadSessionCostSummary } from "../../infra/session-cost-usage.js"; import { loadCostUsageSummary, loadSessionCostSummary } from "../../infra/session-cost-usage.js";
import {
setTelegramThreadBindingIdleTimeoutBySessionKey,
setTelegramThreadBindingMaxAgeBySessionKey,
} from "../../telegram/thread-bindings.js";
import { formatTokenCount, formatUsd } from "../../utils/usage-format.js"; import { formatTokenCount, formatUsd } from "../../utils/usage-format.js";
import { parseActivationCommand } from "../group-activation.js"; import { parseActivationCommand } from "../group-activation.js";
import { parseSendPolicyCommand } from "../send-policy.js"; import { parseSendPolicyCommand } from "../send-policy.js";

View File

@ -10,7 +10,7 @@ export function installSubagentsCommandCoreMocks() {
}); });
// Prevent transitive import chain from reaching discord/monitor which needs https-proxy-agent. // Prevent transitive import chain from reaching discord/monitor which needs https-proxy-agent.
vi.mock("../../discord/monitor/gateway-plugin.js", () => ({ vi.mock("../../../extensions/discord/src/monitor/gateway-plugin.js", () => ({
createDiscordGatewayPlugin: () => ({}), createDiscordGatewayPlugin: () => ({}),
})); }));
} }

View File

@ -1,3 +1,4 @@
import { parseDiscordTarget } from "../../../../extensions/discord/src/targets.js";
import { resolveStoredSubagentCapabilities } from "../../../agents/subagent-capabilities.js"; import { resolveStoredSubagentCapabilities } from "../../../agents/subagent-capabilities.js";
import type { ResolvedSubagentController } from "../../../agents/subagent-control.js"; import type { ResolvedSubagentController } from "../../../agents/subagent-control.js";
import { import {
@ -16,7 +17,6 @@ import type {
loadSessionStore as loadSessionStoreFn, loadSessionStore as loadSessionStoreFn,
resolveStorePath as resolveStorePathFn, resolveStorePath as resolveStorePathFn,
} from "../../../config/sessions.js"; } from "../../../config/sessions.js";
import { parseDiscordTarget } from "../../../discord/targets.js";
import { callGateway } from "../../../gateway/call.js"; import { callGateway } from "../../../gateway/call.js";
import { formatTimeAgo } from "../../../infra/format-time/format-relative.ts"; import { formatTimeAgo } from "../../../infra/format-time/format-relative.ts";
import { parseAgentSessionKey } from "../../../routing/session-key.js"; import { parseAgentSessionKey } from "../../../routing/session-key.js";

View File

@ -1,3 +1,4 @@
import { buildBrowseProvidersButton } from "../../../extensions/telegram/src/model-buttons.js";
import { resolveAuthStorePathForDisplay } from "../../agents/auth-profiles.js"; import { resolveAuthStorePathForDisplay } from "../../agents/auth-profiles.js";
import { import {
type ModelAliasIndex, type ModelAliasIndex,
@ -8,7 +9,6 @@ import {
} from "../../agents/model-selection.js"; } from "../../agents/model-selection.js";
import type { OpenClawConfig } from "../../config/config.js"; import type { OpenClawConfig } from "../../config/config.js";
import type { SessionEntry } from "../../config/sessions.js"; import type { SessionEntry } from "../../config/sessions.js";
import { buildBrowseProvidersButton } from "../../telegram/model-buttons.js";
import { shortenHomePath } from "../../utils.js"; import { shortenHomePath } from "../../utils.js";
import { resolveSelectedAndActiveModel } from "../model-runtime.js"; import { resolveSelectedAndActiveModel } from "../model-runtime.js";
import type { ReplyPayload } from "../types.js"; import type { ReplyPayload } from "../types.js";

View File

@ -1,3 +1,4 @@
import { shouldSuppressLocalDiscordExecApprovalPrompt } from "../../../extensions/discord/src/exec-approvals.js";
import { resolveSessionAgentId } from "../../agents/agent-scope.js"; import { resolveSessionAgentId } from "../../agents/agent-scope.js";
import type { OpenClawConfig } from "../../config/config.js"; import type { OpenClawConfig } from "../../config/config.js";
import { import {
@ -7,7 +8,6 @@ import {
resolveStorePath, resolveStorePath,
type SessionEntry, type SessionEntry,
} from "../../config/sessions.js"; } from "../../config/sessions.js";
import { shouldSuppressLocalDiscordExecApprovalPrompt } from "../../discord/exec-approvals.js";
import { logVerbose } from "../../globals.js"; import { logVerbose } from "../../globals.js";
import { fireAndForgetHook } from "../../hooks/fire-and-forget.js"; import { fireAndForgetHook } from "../../hooks/fire-and-forget.js";
import { createInternalHookEvent, triggerInternalHook } from "../../hooks/internal-hooks.js"; import { createInternalHookEvent, triggerInternalHook } from "../../hooks/internal-hooks.js";

View File

@ -1,10 +1,10 @@
import { parseTelegramTarget } from "../../../extensions/telegram/src/targets.js";
import { isMessagingToolDuplicate } from "../../agents/pi-embedded-helpers.js"; import { isMessagingToolDuplicate } from "../../agents/pi-embedded-helpers.js";
import type { MessagingToolSend } from "../../agents/pi-embedded-runner.js"; import type { MessagingToolSend } from "../../agents/pi-embedded-runner.js";
import { normalizeChannelId } from "../../channels/plugins/index.js"; import { normalizeChannelId } from "../../channels/plugins/index.js";
import type { ReplyToMode } from "../../config/types.js"; import type { ReplyToMode } from "../../config/types.js";
import { normalizeTargetForProvider } from "../../infra/outbound/target-normalization.js"; import { normalizeTargetForProvider } from "../../infra/outbound/target-normalization.js";
import { normalizeOptionalAccountId } from "../../routing/account-id.js"; import { normalizeOptionalAccountId } from "../../routing/account-id.js";
import { parseTelegramTarget } from "../../telegram/targets.js";
import type { OriginatingChannelType } from "../templating.js"; import type { OriginatingChannelType } from "../templating.js";
import type { ReplyPayload } from "../types.js"; import type { ReplyPayload } from "../types.js";
import { extractReplyToTag } from "./reply-tags.js"; import { extractReplyToTag } from "./reply-tags.js";

View File

@ -29,19 +29,19 @@ const mocks = vi.hoisted(() => ({
deliverOutboundPayloads: vi.fn(), deliverOutboundPayloads: vi.fn(),
})); }));
vi.mock("../../discord/send.js", () => ({ vi.mock("../../../extensions/discord/src/send.js", () => ({
sendMessageDiscord: mocks.sendMessageDiscord, sendMessageDiscord: mocks.sendMessageDiscord,
})); }));
vi.mock("../../imessage/send.js", () => ({ vi.mock("../../../extensions/imessage/src/send.js", () => ({
sendMessageIMessage: mocks.sendMessageIMessage, sendMessageIMessage: mocks.sendMessageIMessage,
})); }));
vi.mock("../../signal/send.js", () => ({ vi.mock("../../../extensions/signal/src/send.js", () => ({
sendMessageSignal: mocks.sendMessageSignal, sendMessageSignal: mocks.sendMessageSignal,
})); }));
vi.mock("../../slack/send.js", () => ({ vi.mock("../../../extensions/slack/src/send.js", () => ({
sendMessageSlack: mocks.sendMessageSlack, sendMessageSlack: mocks.sendMessageSlack,
})); }));
vi.mock("../../telegram/send.js", () => ({ vi.mock("../../../extensions/telegram/src/send.js", () => ({
sendMessageTelegram: mocks.sendMessageTelegram, sendMessageTelegram: mocks.sendMessageTelegram,
})); }));
vi.mock("../../../extensions/whatsapp/src/send.js", () => ({ vi.mock("../../../extensions/whatsapp/src/send.js", () => ({

View File

@ -7,13 +7,13 @@
* across multiple providers. * across multiple providers.
*/ */
import { parseSlackBlocksInput } from "../../../extensions/slack/src/blocks-input.js";
import { isSlackInteractiveRepliesEnabled } from "../../../extensions/slack/src/interactive-replies.js";
import { resolveSessionAgentId } from "../../agents/agent-scope.js"; import { resolveSessionAgentId } from "../../agents/agent-scope.js";
import { resolveEffectiveMessagesConfig } from "../../agents/identity.js"; import { resolveEffectiveMessagesConfig } from "../../agents/identity.js";
import { normalizeChannelId } from "../../channels/plugins/index.js"; import { normalizeChannelId } from "../../channels/plugins/index.js";
import type { OpenClawConfig } from "../../config/config.js"; import type { OpenClawConfig } from "../../config/config.js";
import { buildOutboundSessionContext } from "../../infra/outbound/session-context.js"; import { buildOutboundSessionContext } from "../../infra/outbound/session-context.js";
import { parseSlackBlocksInput } from "../../slack/blocks-input.js";
import { isSlackInteractiveRepliesEnabled } from "../../slack/interactive-replies.js";
import { INTERNAL_MESSAGE_CHANNEL, normalizeMessageChannel } from "../../utils/message-channel.js"; import { INTERNAL_MESSAGE_CHANNEL, normalizeMessageChannel } from "../../utils/message-channel.js";
import type { OriginatingChannelType } from "../templating.js"; import type { OriginatingChannelType } from "../templating.js";
import type { ReplyPayload } from "../types.js"; import type { ReplyPayload } from "../types.js";

View File

@ -1,5 +1,5 @@
import { parseSlackBlocksInput } from "../../slack/blocks-input.js"; import { parseSlackBlocksInput } from "../../../extensions/slack/src/blocks-input.js";
import { truncateSlackText } from "../../slack/truncate.js"; import { truncateSlackText } from "../../../extensions/slack/src/truncate.js";
import type { ReplyPayload } from "../types.js"; import type { ReplyPayload } from "../types.js";
const SLACK_REPLY_BUTTON_ACTION_ID = "openclaw:reply_button"; const SLACK_REPLY_BUTTON_ACTION_ID = "openclaw:reply_button";

View File

@ -1,4 +1,4 @@
import { parseTelegramTarget } from "../../telegram/targets.js"; import { parseTelegramTarget } from "../../../extensions/telegram/src/targets.js";
type TelegramConversationParams = { type TelegramConversationParams = {
ctx: { ctx: {

View File

@ -1,10 +1,10 @@
import type { StickerMetadata } from "../../extensions/telegram/src/bot/types.js";
import type { ChannelId } from "../channels/plugins/types.js"; import type { ChannelId } from "../channels/plugins/types.js";
import type { import type {
MediaUnderstandingDecision, MediaUnderstandingDecision,
MediaUnderstandingOutput, MediaUnderstandingOutput,
} from "../media-understanding/types.js"; } from "../media-understanding/types.js";
import type { InputProvenance } from "../sessions/input-provenance.js"; import type { InputProvenance } from "../sessions/input-provenance.js";
import type { StickerMetadata } from "../telegram/bot/types.js";
import type { InternalMessageChannel } from "../utils/message-channel.js"; import type { InternalMessageChannel } from "../utils/message-channel.js";
import type { CommandArgs } from "./commands-registry.types.js"; import type { CommandArgs } from "./commands-registry.types.js";

View File

@ -9,17 +9,17 @@ export {
runWebHeartbeatOnce, runWebHeartbeatOnce,
type WebChannelStatus, type WebChannelStatus,
type WebMonitorTuning, type WebMonitorTuning,
} from "./web/auto-reply.js"; } from "../extensions/whatsapp/src/auto-reply.js";
export { export {
extractMediaPlaceholder, extractMediaPlaceholder,
extractText, extractText,
monitorWebInbox, monitorWebInbox,
type WebInboundMessage, type WebInboundMessage,
type WebListenerCloseReason, type WebListenerCloseReason,
} from "./web/inbound.js"; } from "../extensions/whatsapp/src/inbound.js";
export { loginWeb } from "./web/login.js"; export { loginWeb } from "../extensions/whatsapp/src/login.js";
export { loadWebMedia, optimizeImageToJpeg } from "./web/media.js"; export { loadWebMedia, optimizeImageToJpeg } from "../extensions/whatsapp/src/media.js";
export { sendMessageWhatsApp } from "./web/outbound.js"; export { sendMessageWhatsApp } from "../extensions/whatsapp/src/send.js";
export { export {
createWaSocket, createWaSocket,
formatError, formatError,
@ -30,4 +30,4 @@ export {
WA_WEB_AUTH_DIR, WA_WEB_AUTH_DIR,
waitForWaConnection, waitForWaConnection,
webAuthExists, webAuthExists,
} from "./web/session.js"; } from "../extensions/whatsapp/src/session.js";

View File

@ -1,8 +1,13 @@
import { inspectDiscordAccount } from "../../extensions/discord/src/account-inspect.js";
import { resolveSignalAccount } from "../../extensions/signal/src/accounts.js";
import { inspectSlackAccount } from "../../extensions/slack/src/account-inspect.js";
import { resolveSlackReplyToMode } from "../../extensions/slack/src/accounts.js";
import { buildSlackThreadingToolContext } from "../../extensions/slack/src/threading-tool-context.js";
import { inspectTelegramAccount } from "../../extensions/telegram/src/account-inspect.js";
import { import {
resolveChannelGroupRequireMention, resolveChannelGroupRequireMention,
resolveChannelGroupToolsPolicy, resolveChannelGroupToolsPolicy,
} from "../config/group-policy.js"; } from "../config/group-policy.js";
import { inspectDiscordAccount } from "../discord/account-inspect.js";
import { import {
formatAllowFromLowercase, formatAllowFromLowercase,
formatNormalizedAllowFromEntries, formatNormalizedAllowFromEntries,
@ -19,11 +24,6 @@ import {
} from "../plugin-sdk/channel-config-helpers.js"; } from "../plugin-sdk/channel-config-helpers.js";
import { requireActivePluginRegistry } from "../plugins/runtime.js"; import { requireActivePluginRegistry } from "../plugins/runtime.js";
import { normalizeAccountId } from "../routing/session-key.js"; import { normalizeAccountId } from "../routing/session-key.js";
import { resolveSignalAccount } from "../signal/accounts.js";
import { inspectSlackAccount } from "../slack/account-inspect.js";
import { resolveSlackReplyToMode } from "../slack/accounts.js";
import { buildSlackThreadingToolContext } from "../slack/threading-tool-context.js";
import { inspectTelegramAccount } from "../telegram/account-inspect.js";
import { normalizeE164 } from "../utils.js"; import { normalizeE164 } from "../utils.js";
import { import {
resolveDiscordGroupRequireMention, resolveDiscordGroupRequireMention,

View File

@ -15,7 +15,7 @@ vi.mock("../../../agents/tools/telegram-actions.js", () => ({
handleTelegramAction, handleTelegramAction,
})); }));
vi.mock("../../../signal/send-reactions.js", () => ({ vi.mock("../../../../extensions/signal/src/send-reactions.js", () => ({
sendReactionSignal, sendReactionSignal,
removeReactionSignal, removeReactionSignal,
})); }));

View File

@ -1,7 +1,13 @@
import {
listEnabledSignalAccounts,
resolveSignalAccount,
} from "../../../../extensions/signal/src/accounts.js";
import { resolveSignalReactionLevel } from "../../../../extensions/signal/src/reaction-level.js";
import {
sendReactionSignal,
removeReactionSignal,
} from "../../../../extensions/signal/src/send-reactions.js";
import { createActionGate, jsonResult, readStringParam } from "../../../agents/tools/common.js"; import { createActionGate, jsonResult, readStringParam } from "../../../agents/tools/common.js";
import { listEnabledSignalAccounts, resolveSignalAccount } from "../../../signal/accounts.js";
import { resolveSignalReactionLevel } from "../../../signal/reaction-level.js";
import { sendReactionSignal, removeReactionSignal } from "../../../signal/send-reactions.js";
import type { ChannelMessageActionAdapter, ChannelMessageActionName } from "../types.js"; import type { ChannelMessageActionAdapter, ChannelMessageActionName } from "../types.js";
import { resolveReactionMessageId } from "./reaction-message-id.js"; import { resolveReactionMessageId } from "./reaction-message-id.js";

View File

@ -1,9 +1,9 @@
import { inspectDiscordAccount } from "../../../extensions/discord/src/account-inspect.js";
import { inspectSlackAccount } from "../../../extensions/slack/src/account-inspect.js";
import { inspectTelegramAccount } from "../../../extensions/telegram/src/account-inspect.js";
import { resolveWhatsAppAccount } from "../../../extensions/whatsapp/src/accounts.js";
import type { OpenClawConfig } from "../../config/types.js"; import type { OpenClawConfig } from "../../config/types.js";
import { inspectDiscordAccount } from "../../discord/account-inspect.js";
import { mapAllowFromEntries } from "../../plugin-sdk/channel-config-helpers.js"; import { mapAllowFromEntries } from "../../plugin-sdk/channel-config-helpers.js";
import { inspectSlackAccount } from "../../slack/account-inspect.js";
import { inspectTelegramAccount } from "../../telegram/account-inspect.js";
import { resolveWhatsAppAccount } from "../../web/accounts.js";
import { isWhatsAppGroupJid, normalizeWhatsAppTarget } from "../../whatsapp/normalize.js"; import { isWhatsAppGroupJid, normalizeWhatsAppTarget } from "../../whatsapp/normalize.js";
import { applyDirectoryQueryAndLimit, toDirectoryEntries } from "./directory-config-helpers.js"; import { applyDirectoryQueryAndLimit, toDirectoryEntries } from "./directory-config-helpers.js";
import { normalizeSlackMessagingTarget } from "./normalize/slack.js"; import { normalizeSlackMessagingTarget } from "./normalize/slack.js";

View File

@ -1,3 +1,4 @@
import { inspectSlackAccount } from "../../../extensions/slack/src/account-inspect.js";
import type { OpenClawConfig } from "../../config/config.js"; import type { OpenClawConfig } from "../../config/config.js";
import { import {
resolveChannelGroupRequireMention, resolveChannelGroupRequireMention,
@ -11,7 +12,6 @@ import type {
} from "../../config/types.tools.js"; } from "../../config/types.tools.js";
import { resolveExactLineGroupConfigKey } from "../../line/group-keys.js"; import { resolveExactLineGroupConfigKey } from "../../line/group-keys.js";
import { normalizeAtHashSlug, normalizeHyphenSlug } from "../../shared/string-normalization.js"; import { normalizeAtHashSlug, normalizeHyphenSlug } from "../../shared/string-normalization.js";
import { inspectSlackAccount } from "../../slack/account-inspect.js";
import type { ChannelGroupContext } from "./types.js"; import type { ChannelGroupContext } from "./types.js";
type GroupMentionParams = ChannelGroupContext; type GroupMentionParams = ChannelGroupContext;

View File

@ -1,4 +1,4 @@
import { normalizeIMessageHandle } from "../../../imessage/targets.js"; import { normalizeIMessageHandle } from "../../../../extensions/imessage/src/targets.js";
import { looksLikeHandleOrPhoneTarget, trimMessagingTarget } from "./shared.js"; import { looksLikeHandleOrPhoneTarget, trimMessagingTarget } from "./shared.js";
// Service prefixes that indicate explicit delivery method; must be preserved during normalization // Service prefixes that indicate explicit delivery method; must be preserved during normalization

View File

@ -1,4 +1,4 @@
import { parseSlackTarget } from "../../../slack/targets.js"; import { parseSlackTarget } from "../../../../extensions/slack/src/targets.js";
export function normalizeSlackMessagingTarget(raw: string): string | undefined { export function normalizeSlackMessagingTarget(raw: string): string | undefined {
const target = parseSlackTarget(raw, { defaultKind: "channel" }); const target = parseSlackTarget(raw, { defaultKind: "channel" });

View File

@ -1,11 +1,11 @@
import { detectBinary } from "../../../commands/onboard-helpers.js";
import type { OpenClawConfig } from "../../../config/config.js";
import { import {
listIMessageAccountIds, listIMessageAccountIds,
resolveDefaultIMessageAccountId, resolveDefaultIMessageAccountId,
resolveIMessageAccount, resolveIMessageAccount,
} from "../../../imessage/accounts.js"; } from "../../../../extensions/imessage/src/accounts.js";
import { normalizeIMessageHandle } from "../../../imessage/targets.js"; import { normalizeIMessageHandle } from "../../../../extensions/imessage/src/targets.js";
import { detectBinary } from "../../../commands/onboard-helpers.js";
import type { OpenClawConfig } from "../../../config/config.js";
import { formatDocsLink } from "../../../terminal/links.js"; import { formatDocsLink } from "../../../terminal/links.js";
import type { WizardPrompter } from "../../../wizard/prompts.js"; import type { WizardPrompter } from "../../../wizard/prompts.js";
import type { ChannelOnboardingAdapter, ChannelOnboardingDmPolicy } from "../onboarding-types.js"; import type { ChannelOnboardingAdapter, ChannelOnboardingDmPolicy } from "../onboarding-types.js";

View File

@ -1,12 +1,12 @@
import { formatCliCommand } from "../../../cli/command-format.js";
import { detectBinary } from "../../../commands/onboard-helpers.js";
import { installSignalCli } from "../../../commands/signal-install.js";
import type { OpenClawConfig } from "../../../config/config.js";
import { import {
listSignalAccountIds, listSignalAccountIds,
resolveDefaultSignalAccountId, resolveDefaultSignalAccountId,
resolveSignalAccount, resolveSignalAccount,
} from "../../../signal/accounts.js"; } from "../../../../extensions/signal/src/accounts.js";
import { formatCliCommand } from "../../../cli/command-format.js";
import { detectBinary } from "../../../commands/onboard-helpers.js";
import { installSignalCli } from "../../../commands/signal-install.js";
import type { OpenClawConfig } from "../../../config/config.js";
import { formatDocsLink } from "../../../terminal/links.js"; import { formatDocsLink } from "../../../terminal/links.js";
import { normalizeE164 } from "../../../utils.js"; import { normalizeE164 } from "../../../utils.js";
import type { WizardPrompter } from "../../../wizard/prompts.js"; import type { WizardPrompter } from "../../../wizard/prompts.js";

View File

@ -1,14 +1,14 @@
import type { OpenClawConfig } from "../../../config/config.js"; import { inspectSlackAccount } from "../../../../extensions/slack/src/account-inspect.js";
import { hasConfiguredSecretInput } from "../../../config/types.secrets.js";
import { DEFAULT_ACCOUNT_ID } from "../../../routing/session-key.js";
import { inspectSlackAccount } from "../../../slack/account-inspect.js";
import { import {
listSlackAccountIds, listSlackAccountIds,
resolveDefaultSlackAccountId, resolveDefaultSlackAccountId,
resolveSlackAccount, resolveSlackAccount,
} from "../../../slack/accounts.js"; } from "../../../../extensions/slack/src/accounts.js";
import { resolveSlackChannelAllowlist } from "../../../slack/resolve-channels.js"; import { resolveSlackChannelAllowlist } from "../../../../extensions/slack/src/resolve-channels.js";
import { resolveSlackUserAllowlist } from "../../../slack/resolve-users.js"; import { resolveSlackUserAllowlist } from "../../../../extensions/slack/src/resolve-users.js";
import type { OpenClawConfig } from "../../../config/config.js";
import { hasConfiguredSecretInput } from "../../../config/types.secrets.js";
import { DEFAULT_ACCOUNT_ID } from "../../../routing/session-key.js";
import { formatDocsLink } from "../../../terminal/links.js"; import { formatDocsLink } from "../../../terminal/links.js";
import type { WizardPrompter } from "../../../wizard/prompts.js"; import type { WizardPrompter } from "../../../wizard/prompts.js";
import type { ChannelOnboardingAdapter, ChannelOnboardingDmPolicy } from "../onboarding-types.js"; import type { ChannelOnboardingAdapter, ChannelOnboardingDmPolicy } from "../onboarding-types.js";

View File

@ -1,4 +1,4 @@
import { sendMessageIMessage } from "../../../imessage/send.js"; import { sendMessageIMessage } from "../../../../extensions/imessage/src/send.js";
import { resolveOutboundSendDep, type OutboundSendDeps } from "../../../infra/outbound/deliver.js"; import { resolveOutboundSendDep, type OutboundSendDeps } from "../../../infra/outbound/deliver.js";
import { import {
createScopedChannelMediaMaxBytesResolver, createScopedChannelMediaMaxBytesResolver,

View File

@ -1,5 +1,5 @@
import { sendMessageSignal } from "../../../../extensions/signal/src/send.js";
import { resolveOutboundSendDep, type OutboundSendDeps } from "../../../infra/outbound/deliver.js"; import { resolveOutboundSendDep, type OutboundSendDeps } from "../../../infra/outbound/deliver.js";
import { sendMessageSignal } from "../../../signal/send.js";
import { import {
createScopedChannelMediaMaxBytesResolver, createScopedChannelMediaMaxBytesResolver,
createDirectTextMediaOutbound, createDirectTextMediaOutbound,

View File

@ -1,7 +1,7 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../../../config/config.js"; import type { OpenClawConfig } from "../../../config/config.js";
vi.mock("../../../slack/send.js", () => ({ vi.mock("../../../../extensions/slack/src/send.js", () => ({
sendMessageSlack: vi.fn().mockResolvedValue({ messageId: "1234.5678", channelId: "C123" }), sendMessageSlack: vi.fn().mockResolvedValue({ messageId: "1234.5678", channelId: "C123" }),
})); }));
@ -9,8 +9,8 @@ vi.mock("../../../plugins/hook-runner-global.js", () => ({
getGlobalHookRunner: vi.fn(), getGlobalHookRunner: vi.fn(),
})); }));
import { sendMessageSlack } from "../../../../extensions/slack/src/send.js";
import { getGlobalHookRunner } from "../../../plugins/hook-runner-global.js"; import { getGlobalHookRunner } from "../../../plugins/hook-runner-global.js";
import { sendMessageSlack } from "../../../slack/send.js";
import { slackOutbound } from "./slack.js"; import { slackOutbound } from "./slack.js";
type SlackSendTextCtx = { type SlackSendTextCtx = {

View File

@ -1,8 +1,8 @@
import { parseSlackBlocksInput } from "../../../../extensions/slack/src/blocks-input.js";
import { sendMessageSlack, type SlackSendIdentity } from "../../../../extensions/slack/src/send.js";
import { resolveOutboundSendDep } from "../../../infra/outbound/deliver.js"; import { resolveOutboundSendDep } from "../../../infra/outbound/deliver.js";
import type { OutboundIdentity } from "../../../infra/outbound/identity.js"; import type { OutboundIdentity } from "../../../infra/outbound/identity.js";
import { getGlobalHookRunner } from "../../../plugins/hook-runner-global.js"; import { getGlobalHookRunner } from "../../../plugins/hook-runner-global.js";
import { parseSlackBlocksInput } from "../../../slack/blocks-input.js";
import { sendMessageSlack, type SlackSendIdentity } from "../../../slack/send.js";
import type { ChannelOutboundAdapter } from "../types.js"; import type { ChannelOutboundAdapter } from "../types.js";
import { sendTextMediaPayload } from "./direct-text-media.js"; import { sendTextMediaPayload } from "./direct-text-media.js";

View File

@ -2,16 +2,16 @@ import fs from "node:fs";
import os from "node:os"; import os from "node:os";
import path from "node:path"; import path from "node:path";
import { afterEach, beforeEach, describe, expect, expectTypeOf, it } from "vitest"; import { afterEach, beforeEach, describe, expect, expectTypeOf, it } from "vitest";
import type { DiscordProbe } from "../../../extensions/discord/src/probe.js";
import type { DiscordTokenResolution } from "../../../extensions/discord/src/token.js";
import type { IMessageProbe } from "../../../extensions/imessage/src/probe.js";
import type { SignalProbe } from "../../../extensions/signal/src/probe.js";
import type { SlackProbe } from "../../../extensions/slack/src/probe.js";
import type { TelegramProbe } from "../../../extensions/telegram/src/probe.js";
import type { TelegramTokenResolution } from "../../../extensions/telegram/src/token.js";
import type { OpenClawConfig } from "../../config/config.js"; import type { OpenClawConfig } from "../../config/config.js";
import type { DiscordProbe } from "../../discord/probe.js";
import type { DiscordTokenResolution } from "../../discord/token.js";
import type { IMessageProbe } from "../../imessage/probe.js";
import type { LineProbeResult } from "../../line/types.js"; import type { LineProbeResult } from "../../line/types.js";
import { setActivePluginRegistry } from "../../plugins/runtime.js"; import { setActivePluginRegistry } from "../../plugins/runtime.js";
import type { SignalProbe } from "../../signal/probe.js";
import type { SlackProbe } from "../../slack/probe.js";
import type { TelegramProbe } from "../../telegram/probe.js";
import type { TelegramTokenResolution } from "../../telegram/token.js";
import { import {
createChannelTestPluginBase, createChannelTestPluginBase,
createMSTeamsTestPluginBase, createMSTeamsTestPluginBase,

View File

@ -1,7 +1,10 @@
import {
extractSlackToolSend,
listSlackMessageActions,
} from "../../../extensions/slack/src/message-actions.js";
import { resolveSlackChannelId } from "../../../extensions/slack/src/targets.js";
import { handleSlackAction, type SlackActionContext } from "../../agents/tools/slack-actions.js"; import { handleSlackAction, type SlackActionContext } from "../../agents/tools/slack-actions.js";
import { handleSlackMessageAction } from "../../plugin-sdk/slack-message-actions.js"; import { handleSlackMessageAction } from "../../plugin-sdk/slack-message-actions.js";
import { extractSlackToolSend, listSlackMessageActions } from "../../slack/message-actions.js";
import { resolveSlackChannelId } from "../../slack/targets.js";
import type { ChannelMessageActionAdapter } from "./types.js"; import type { ChannelMessageActionAdapter } from "./types.js";
export function createSlackActions(providerId: string): ChannelMessageActionAdapter { export function createSlackActions(providerId: string): ChannelMessageActionAdapter {

View File

@ -1,10 +1,16 @@
import type { OpenClawConfig } from "../config/config.js"; import {
import { inspectDiscordAccount, type InspectedDiscordAccount } from "../discord/account-inspect.js"; inspectDiscordAccount,
import { inspectSlackAccount, type InspectedSlackAccount } from "../slack/account-inspect.js"; type InspectedDiscordAccount,
} from "../../extensions/discord/src/account-inspect.js";
import {
inspectSlackAccount,
type InspectedSlackAccount,
} from "../../extensions/slack/src/account-inspect.js";
import { import {
inspectTelegramAccount, inspectTelegramAccount,
type InspectedTelegramAccount, type InspectedTelegramAccount,
} from "../telegram/account-inspect.js"; } from "../../extensions/telegram/src/account-inspect.js";
import type { OpenClawConfig } from "../config/config.js";
import type { ChannelId } from "./plugins/types.js"; import type { ChannelId } from "./plugins/types.js";
export type ReadOnlyInspectedAccount = export type ReadOnlyInspectedAccount =

View File

@ -1,3 +1,4 @@
import { isSlackInteractiveRepliesEnabled } from "../../extensions/slack/src/interactive-replies.js";
import { resolveEffectiveMessagesConfig, resolveIdentityName } from "../agents/identity.js"; import { resolveEffectiveMessagesConfig, resolveIdentityName } from "../agents/identity.js";
import { import {
extractShortModelName, extractShortModelName,
@ -5,7 +6,6 @@ import {
} from "../auto-reply/reply/response-prefix-template.js"; } from "../auto-reply/reply/response-prefix-template.js";
import type { GetReplyOptions } from "../auto-reply/types.js"; import type { GetReplyOptions } from "../auto-reply/types.js";
import type { OpenClawConfig } from "../config/config.js"; import type { OpenClawConfig } from "../config/config.js";
import { isSlackInteractiveRepliesEnabled } from "../slack/interactive-replies.js";
type ModelSelectionContext = Parameters<NonNullable<GetReplyOptions["onModelSelected"]>>[0]; type ModelSelectionContext = Parameters<NonNullable<GetReplyOptions["onModelSelected"]>>[0];

View File

@ -24,27 +24,27 @@ vi.mock("../channels/web/index.js", () => {
return { sendMessageWhatsApp: sendFns.whatsapp }; return { sendMessageWhatsApp: sendFns.whatsapp };
}); });
vi.mock("../telegram/send.js", () => { vi.mock("../../extensions/telegram/src/send.js", () => {
moduleLoads.telegram(); moduleLoads.telegram();
return { sendMessageTelegram: sendFns.telegram }; return { sendMessageTelegram: sendFns.telegram };
}); });
vi.mock("../discord/send.js", () => { vi.mock("../../extensions/discord/src/send.js", () => {
moduleLoads.discord(); moduleLoads.discord();
return { sendMessageDiscord: sendFns.discord }; return { sendMessageDiscord: sendFns.discord };
}); });
vi.mock("../slack/send.js", () => { vi.mock("../../extensions/slack/src/send.js", () => {
moduleLoads.slack(); moduleLoads.slack();
return { sendMessageSlack: sendFns.slack }; return { sendMessageSlack: sendFns.slack };
}); });
vi.mock("../signal/send.js", () => { vi.mock("../../extensions/signal/src/send.js", () => {
moduleLoads.signal(); moduleLoads.signal();
return { sendMessageSignal: sendFns.signal }; return { sendMessageSignal: sendFns.signal };
}); });
vi.mock("../imessage/send.js", () => { vi.mock("../../extensions/imessage/src/send.js", () => {
moduleLoads.imessage(); moduleLoads.imessage();
return { sendMessageIMessage: sendFns.imessage }; return { sendMessageIMessage: sendFns.imessage };
}); });

View File

@ -40,27 +40,27 @@ export function createDefaultDeps(): CliDeps {
), ),
telegram: createLazySender( telegram: createLazySender(
"telegram", "telegram",
() => import("../telegram/send.js") as Promise<Record<string, unknown>>, () => import("../../extensions/telegram/src/send.js") as Promise<Record<string, unknown>>,
"sendMessageTelegram", "sendMessageTelegram",
), ),
discord: createLazySender( discord: createLazySender(
"discord", "discord",
() => import("../discord/send.js") as Promise<Record<string, unknown>>, () => import("../../extensions/discord/src/send.js") as Promise<Record<string, unknown>>,
"sendMessageDiscord", "sendMessageDiscord",
), ),
slack: createLazySender( slack: createLazySender(
"slack", "slack",
() => import("../slack/send.js") as Promise<Record<string, unknown>>, () => import("../../extensions/slack/src/send.js") as Promise<Record<string, unknown>>,
"sendMessageSlack", "sendMessageSlack",
), ),
signal: createLazySender( signal: createLazySender(
"signal", "signal",
() => import("../signal/send.js") as Promise<Record<string, unknown>>, () => import("../../extensions/signal/src/send.js") as Promise<Record<string, unknown>>,
"sendMessageSignal", "sendMessageSignal",
), ),
imessage: createLazySender( imessage: createLazySender(
"imessage", "imessage",
() => import("../imessage/send.js") as Promise<Record<string, unknown>>, () => import("../../extensions/imessage/src/send.js") as Promise<Record<string, unknown>>,
"sendMessageIMessage", "sendMessageIMessage",
), ),
}; };
@ -70,4 +70,4 @@ export function createOutboundSendDeps(deps: CliDeps): OutboundSendDeps {
return createOutboundSendDepsFromCliSource(deps); return createOutboundSendDepsFromCliSource(deps);
} }
export { logWebSelfId } from "../web/auth-store.js"; export { logWebSelfId } from "../../extensions/whatsapp/src/auth-store.js";

View File

@ -24,8 +24,9 @@ vi.mock("../config/config.js", async (importOriginal) => {
}; };
}); });
vi.mock("../telegram/update-offset-store.js", async (importOriginal) => { vi.mock("../../extensions/telegram/src/update-offset-store.js", async (importOriginal) => {
const actual = await importOriginal<typeof import("../telegram/update-offset-store.js")>(); const actual =
await importOriginal<typeof import("../../extensions/telegram/src/update-offset-store.js")>();
return { return {
...actual, ...actual,
deleteTelegramUpdateOffset: offsetMocks.deleteTelegramUpdateOffset, deleteTelegramUpdateOffset: offsetMocks.deleteTelegramUpdateOffset,

View File

@ -1,3 +1,5 @@
import { resolveTelegramAccount } from "../../../extensions/telegram/src/accounts.js";
import { deleteTelegramUpdateOffset } from "../../../extensions/telegram/src/update-offset-store.js";
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../agents/agent-scope.js"; import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../agents/agent-scope.js";
import { listChannelPluginCatalogEntries } from "../../channels/plugins/catalog.js"; import { listChannelPluginCatalogEntries } from "../../channels/plugins/catalog.js";
import { parseOptionalDelimitedEntries } from "../../channels/plugins/helpers.js"; import { parseOptionalDelimitedEntries } from "../../channels/plugins/helpers.js";
@ -7,8 +9,6 @@ import type { ChannelId, ChannelSetupInput } from "../../channels/plugins/types.
import { writeConfigFile, type OpenClawConfig } from "../../config/config.js"; import { writeConfigFile, type OpenClawConfig } from "../../config/config.js";
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../routing/session-key.js"; import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../routing/session-key.js";
import { defaultRuntime, type RuntimeEnv } from "../../runtime.js"; import { defaultRuntime, type RuntimeEnv } from "../../runtime.js";
import { resolveTelegramAccount } from "../../telegram/accounts.js";
import { deleteTelegramUpdateOffset } from "../../telegram/update-offset-store.js";
import { createClackPrompter } from "../../wizard/clack-prompter.js"; import { createClackPrompter } from "../../wizard/clack-prompter.js";
import { applyAgentBindings, describeBinding } from "../agents.bindings.js"; import { applyAgentBindings, describeBinding } from "../agents.bindings.js";
import { buildAgentSummaries } from "../agents.config.js"; import { buildAgentSummaries } from "../agents.config.js";

View File

@ -1,9 +1,9 @@
process.env.NO_COLOR = "1"; process.env.NO_COLOR = "1";
import { beforeEach, describe, expect, it, vi } from "vitest"; import { beforeEach, describe, expect, it, vi } from "vitest";
import { fetchSlackScopes } from "../../../extensions/slack/src/scopes.js";
import { getChannelPlugin, listChannelPlugins } from "../../channels/plugins/index.js"; import { getChannelPlugin, listChannelPlugins } from "../../channels/plugins/index.js";
import type { ChannelPlugin } from "../../channels/plugins/types.js"; import type { ChannelPlugin } from "../../channels/plugins/types.js";
import { fetchSlackScopes } from "../../slack/scopes.js";
import { channelsCapabilitiesCommand } from "./capabilities.js"; import { channelsCapabilitiesCommand } from "./capabilities.js";
const logs: string[] = []; const logs: string[] = [];
@ -21,7 +21,7 @@ vi.mock("../../channels/plugins/index.js", () => ({
getChannelPlugin: vi.fn(), getChannelPlugin: vi.fn(),
})); }));
vi.mock("../../slack/scopes.js", () => ({ vi.mock("../../../extensions/slack/src/scopes.js", () => ({
fetchSlackScopes: vi.fn(), fetchSlackScopes: vi.fn(),
})); }));

View File

@ -1,12 +1,12 @@
import { fetchChannelPermissionsDiscord } from "../../../extensions/discord/src/send.js";
import { parseDiscordTarget } from "../../../extensions/discord/src/targets.js";
import { fetchSlackScopes, type SlackScopesResult } from "../../../extensions/slack/src/scopes.js";
import { resolveChannelDefaultAccountId } from "../../channels/plugins/helpers.js"; import { resolveChannelDefaultAccountId } from "../../channels/plugins/helpers.js";
import { getChannelPlugin, listChannelPlugins } from "../../channels/plugins/index.js"; import { getChannelPlugin, listChannelPlugins } from "../../channels/plugins/index.js";
import type { ChannelCapabilities, ChannelPlugin } from "../../channels/plugins/types.js"; import type { ChannelCapabilities, ChannelPlugin } from "../../channels/plugins/types.js";
import type { OpenClawConfig } from "../../config/config.js"; import type { OpenClawConfig } from "../../config/config.js";
import { fetchChannelPermissionsDiscord } from "../../discord/send.js";
import { parseDiscordTarget } from "../../discord/targets.js";
import { danger } from "../../globals.js"; import { danger } from "../../globals.js";
import { defaultRuntime, type RuntimeEnv } from "../../runtime.js"; import { defaultRuntime, type RuntimeEnv } from "../../runtime.js";
import { fetchSlackScopes, type SlackScopesResult } from "../../slack/scopes.js";
import { theme } from "../../terminal/theme.js"; import { theme } from "../../terminal/theme.js";
import { formatChannelAccountLabel, requireValidConfig } from "./shared.js"; import { formatChannelAccountLabel, requireValidConfig } from "./shared.js";

View File

@ -1,3 +1,4 @@
import { deleteTelegramUpdateOffset } from "../../../extensions/telegram/src/update-offset-store.js";
import { resolveChannelDefaultAccountId } from "../../channels/plugins/helpers.js"; import { resolveChannelDefaultAccountId } from "../../channels/plugins/helpers.js";
import { import {
getChannelPlugin, getChannelPlugin,
@ -7,7 +8,6 @@ import {
import { type OpenClawConfig, writeConfigFile } from "../../config/config.js"; import { type OpenClawConfig, writeConfigFile } from "../../config/config.js";
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../routing/session-key.js"; import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../routing/session-key.js";
import { defaultRuntime, type RuntimeEnv } from "../../runtime.js"; import { defaultRuntime, type RuntimeEnv } from "../../runtime.js";
import { deleteTelegramUpdateOffset } from "../../telegram/update-offset-store.js";
import { createClackPrompter } from "../../wizard/clack-prompter.js"; import { createClackPrompter } from "../../wizard/clack-prompter.js";
import { type ChatChannel, channelLabel, requireValidConfig, shouldUseWizard } from "./shared.js"; import { type ChatChannel, channelLabel, requireValidConfig, shouldUseWizard } from "./shared.js";

View File

@ -1,11 +1,16 @@
import fs from "node:fs/promises"; import fs from "node:fs/promises";
import path from "node:path"; import path from "node:path";
import { normalizeChatChannelId } from "../channels/registry.js"; import { inspectTelegramAccount } from "../../extensions/telegram/src/account-inspect.js";
import {
listTelegramAccountIds,
resolveTelegramAccount,
} from "../../extensions/telegram/src/accounts.js";
import { import {
isNumericTelegramUserId, isNumericTelegramUserId,
normalizeTelegramAllowFromEntry, normalizeTelegramAllowFromEntry,
} from "../channels/telegram/allow-from.js"; } from "../../extensions/telegram/src/allow-from.js";
import { fetchTelegramChatId } from "../channels/telegram/api.js"; import { fetchTelegramChatId } from "../../extensions/telegram/src/api-fetch.js";
import { normalizeChatChannelId } from "../channels/registry.js";
import { formatCliCommand } from "../cli/command-format.js"; import { formatCliCommand } from "../cli/command-format.js";
import { resolveCommandSecretRefsViaGateway } from "../cli/command-secret-gateway.js"; import { resolveCommandSecretRefsViaGateway } from "../cli/command-secret-gateway.js";
import { getChannelsCommandSecretTargetIds } from "../cli/command-secret-targets.js"; import { getChannelsCommandSecretTargetIds } from "../cli/command-secret-targets.js";
@ -46,8 +51,6 @@ import {
isSlackMutableAllowEntry, isSlackMutableAllowEntry,
isZalouserMutableGroupEntry, isZalouserMutableGroupEntry,
} from "../security/mutable-allowlist-detectors.js"; } from "../security/mutable-allowlist-detectors.js";
import { inspectTelegramAccount } from "../telegram/account-inspect.js";
import { listTelegramAccountIds, resolveTelegramAccount } from "../telegram/accounts.js";
import { note } from "../terminal/note.js"; import { note } from "../terminal/note.js";
import { resolveHomeDir } from "../utils.js"; import { resolveHomeDir } from "../utils.js";
import { import {

View File

@ -258,7 +258,7 @@ vi.mock("../pairing/pairing-store.js", () => ({
upsertChannelPairingRequest: vi.fn().mockResolvedValue({ code: "000000", created: false }), upsertChannelPairingRequest: vi.fn().mockResolvedValue({ code: "000000", created: false }),
})); }));
vi.mock("../telegram/token.js", () => ({ vi.mock("../../extensions/telegram/src/token.js", () => ({
resolveTelegramToken: vi.fn(() => ({ token: "", source: "none" })), resolveTelegramToken: vi.fn(() => ({ token: "", source: "none" })),
})); }));

View File

@ -1,3 +1,4 @@
import { hasAnyWhatsAppAuth } from "../../extensions/whatsapp/src/accounts.js";
import { normalizeProviderId } from "../agents/model-selection.js"; import { normalizeProviderId } from "../agents/model-selection.js";
import { import {
getChannelPluginCatalogEntry, getChannelPluginCatalogEntry,
@ -13,7 +14,6 @@ import {
type PluginManifestRegistry, type PluginManifestRegistry,
} from "../plugins/manifest-registry.js"; } from "../plugins/manifest-registry.js";
import { isRecord } from "../utils.js"; import { isRecord } from "../utils.js";
import { hasAnyWhatsAppAuth } from "../web/accounts.js";
import type { OpenClawConfig } from "./config.js"; import type { OpenClawConfig } from "./config.js";
import { ensurePluginAllowlisted } from "./plugins-allowlist.js"; import { ensurePluginAllowlisted } from "./plugins-allowlist.js";

View File

@ -1,7 +1,7 @@
import { import {
DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS, DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS,
DISCORD_DEFAULT_LISTENER_TIMEOUT_MS, DISCORD_DEFAULT_LISTENER_TIMEOUT_MS,
} from "../discord/monitor/timeouts.js"; } from "../../extensions/discord/src/monitor/timeouts.js";
import { MEDIA_AUDIO_FIELD_HELP } from "./media-audio-field-metadata.js"; import { MEDIA_AUDIO_FIELD_HELP } from "./media-audio-field-metadata.js";
import { IRC_FIELD_HELP } from "./schema.irc.js"; import { IRC_FIELD_HELP } from "./schema.irc.js";
import { describeTalkSilenceTimeoutDefaults } from "./talk-defaults.js"; import { describeTalkSilenceTimeoutDefaults } from "./talk-defaults.js";

View File

@ -1,5 +1,5 @@
import { normalizeExplicitDiscordSessionKey } from "../../../extensions/discord/src/session-key-normalization.js";
import type { MsgContext } from "../../auto-reply/templating.js"; import type { MsgContext } from "../../auto-reply/templating.js";
import { normalizeExplicitDiscordSessionKey } from "../../discord/session-key-normalization.js";
type ExplicitSessionKeyNormalizer = (sessionKey: string, ctx: MsgContext) => string; type ExplicitSessionKeyNormalizer = (sessionKey: string, ctx: MsgContext) => string;
type ExplicitSessionKeyNormalizerEntry = { type ExplicitSessionKeyNormalizerEntry = {

View File

@ -1,4 +1,4 @@
import type { DiscordPluralKitConfig } from "../discord/pluralkit.js"; import type { DiscordPluralKitConfig } from "../../extensions/discord/src/pluralkit.js";
import type { import type {
BlockStreamingChunkConfig, BlockStreamingChunkConfig,
BlockStreamingCoalesceConfig, BlockStreamingCoalesceConfig,

View File

@ -25,11 +25,11 @@ vi.mock("../../../extensions/whatsapp/src/accounts.js", () => ({
resolveWhatsAppAccount: vi.fn(() => ({ allowFrom: [] })), resolveWhatsAppAccount: vi.fn(() => ({ allowFrom: [] })),
})); }));
import { resolveWhatsAppAccount } from "../../../extensions/whatsapp/src/accounts.js";
import { loadSessionStore } from "../../config/sessions.js"; import { loadSessionStore } from "../../config/sessions.js";
import { resolveMessageChannelSelection } from "../../infra/outbound/channel-selection.js"; import { resolveMessageChannelSelection } from "../../infra/outbound/channel-selection.js";
import { maybeResolveIdLikeTarget } from "../../infra/outbound/target-resolver.js"; import { maybeResolveIdLikeTarget } from "../../infra/outbound/target-resolver.js";
import { readChannelAllowFromStoreSync } from "../../pairing/pairing-store.js"; import { readChannelAllowFromStoreSync } from "../../pairing/pairing-store.js";
import { resolveWhatsAppAccount } from "../../web/accounts.js";
import { resolveDeliveryTarget } from "./delivery-target.js"; import { resolveDeliveryTarget } from "./delivery-target.js";
function makeCfg(overrides?: Partial<OpenClawConfig>): OpenClawConfig { function makeCfg(overrides?: Partial<OpenClawConfig>): OpenClawConfig {

View File

@ -1,3 +1,4 @@
import { resolveWhatsAppAccount } from "../../../extensions/whatsapp/src/accounts.js";
import type { ChannelId } from "../../channels/plugins/types.js"; import type { ChannelId } from "../../channels/plugins/types.js";
import type { OpenClawConfig } from "../../config/config.js"; import type { OpenClawConfig } from "../../config/config.js";
import { import {
@ -15,7 +16,6 @@ import {
import { readChannelAllowFromStoreSync } from "../../pairing/pairing-store.js"; import { readChannelAllowFromStoreSync } from "../../pairing/pairing-store.js";
import { buildChannelAccountBindings } from "../../routing/bindings.js"; import { buildChannelAccountBindings } from "../../routing/bindings.js";
import { normalizeAccountId, normalizeAgentId } from "../../routing/session-key.js"; import { normalizeAccountId, normalizeAgentId } from "../../routing/session-key.js";
import { resolveWhatsAppAccount } from "../../web/accounts.js";
import { normalizeWhatsAppTarget } from "../../whatsapp/normalize.js"; import { normalizeWhatsAppTarget } from "../../whatsapp/normalize.js";
export type DeliveryTargetResolution = export type DeliveryTargetResolution =

View File

@ -1 +0,0 @@
export * from "../../extensions/discord/src/account-inspect.js";

View File

@ -1 +0,0 @@
export * from "../../extensions/discord/src/accounts.js";

Some files were not shown because too many files have changed in this diff Show More