@openclaw/crabline 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +226 -0
  3. package/dist/src/bin/crabline.d.ts +2 -0
  4. package/dist/src/bin/crabline.js +7 -0
  5. package/dist/src/bin/crabline.js.map +1 -0
  6. package/dist/src/cli/program.d.ts +5 -0
  7. package/dist/src/cli/program.js +295 -0
  8. package/dist/src/cli/program.js.map +1 -0
  9. package/dist/src/config/load.d.ts +6 -0
  10. package/dist/src/config/load.js +41 -0
  11. package/dist/src/config/load.js.map +1 -0
  12. package/dist/src/config/schema.d.ts +1571 -0
  13. package/dist/src/config/schema.js +528 -0
  14. package/dist/src/config/schema.js.map +1 -0
  15. package/dist/src/core/errors.d.ts +12 -0
  16. package/dist/src/core/errors.js +28 -0
  17. package/dist/src/core/errors.js.map +1 -0
  18. package/dist/src/core/exit-codes.d.ts +13 -0
  19. package/dist/src/core/exit-codes.js +13 -0
  20. package/dist/src/core/exit-codes.js.map +1 -0
  21. package/dist/src/core/matcher.d.ts +2 -0
  22. package/dist/src/core/matcher.js +30 -0
  23. package/dist/src/core/matcher.js.map +1 -0
  24. package/dist/src/core/message-template.d.ts +2 -0
  25. package/dist/src/core/message-template.js +20 -0
  26. package/dist/src/core/message-template.js.map +1 -0
  27. package/dist/src/core/nonces.d.ts +2 -0
  28. package/dist/src/core/nonces.js +11 -0
  29. package/dist/src/core/nonces.js.map +1 -0
  30. package/dist/src/core/reporters.d.ts +3 -0
  31. package/dist/src/core/reporters.js +23 -0
  32. package/dist/src/core/reporters.js.map +1 -0
  33. package/dist/src/core/run.d.ts +30 -0
  34. package/dist/src/core/run.js +240 -0
  35. package/dist/src/core/run.js.map +1 -0
  36. package/dist/src/fake-servers/index.d.ts +10 -0
  37. package/dist/src/fake-servers/index.js +12 -0
  38. package/dist/src/fake-servers/index.js.map +1 -0
  39. package/dist/src/fake-servers/telegram.d.ts +29 -0
  40. package/dist/src/fake-servers/telegram.js +346 -0
  41. package/dist/src/fake-servers/telegram.js.map +1 -0
  42. package/dist/src/index.d.ts +15 -0
  43. package/dist/src/index.js +9 -0
  44. package/dist/src/index.js.map +1 -0
  45. package/dist/src/openclaw.d.ts +102 -0
  46. package/dist/src/openclaw.js +289 -0
  47. package/dist/src/openclaw.js.map +1 -0
  48. package/dist/src/providers/builtin/discord.d.ts +15 -0
  49. package/dist/src/providers/builtin/discord.js +92 -0
  50. package/dist/src/providers/builtin/discord.js.map +1 -0
  51. package/dist/src/providers/builtin/feishu.d.ts +10 -0
  52. package/dist/src/providers/builtin/feishu.js +95 -0
  53. package/dist/src/providers/builtin/feishu.js.map +1 -0
  54. package/dist/src/providers/builtin/googlechat.d.ts +11 -0
  55. package/dist/src/providers/builtin/googlechat.js +83 -0
  56. package/dist/src/providers/builtin/googlechat.js.map +1 -0
  57. package/dist/src/providers/builtin/imessage.d.ts +11 -0
  58. package/dist/src/providers/builtin/imessage.js +67 -0
  59. package/dist/src/providers/builtin/imessage.js.map +1 -0
  60. package/dist/src/providers/builtin/loopback.d.ts +63 -0
  61. package/dist/src/providers/builtin/loopback.js +174 -0
  62. package/dist/src/providers/builtin/loopback.js.map +1 -0
  63. package/dist/src/providers/builtin/matrix.d.ts +21 -0
  64. package/dist/src/providers/builtin/matrix.js +84 -0
  65. package/dist/src/providers/builtin/matrix.js.map +1 -0
  66. package/dist/src/providers/builtin/mattermost.d.ts +11 -0
  67. package/dist/src/providers/builtin/mattermost.js +67 -0
  68. package/dist/src/providers/builtin/mattermost.js.map +1 -0
  69. package/dist/src/providers/builtin/msteams.d.ts +13 -0
  70. package/dist/src/providers/builtin/msteams.js +72 -0
  71. package/dist/src/providers/builtin/msteams.js.map +1 -0
  72. package/dist/src/providers/builtin/native-local-mock.d.ts +48 -0
  73. package/dist/src/providers/builtin/native-local-mock.js +119 -0
  74. package/dist/src/providers/builtin/native-local-mock.js.map +1 -0
  75. package/dist/src/providers/builtin/script.d.ts +39 -0
  76. package/dist/src/providers/builtin/script.js +206 -0
  77. package/dist/src/providers/builtin/script.js.map +1 -0
  78. package/dist/src/providers/builtin/slack.d.ts +6 -0
  79. package/dist/src/providers/builtin/slack.js +106 -0
  80. package/dist/src/providers/builtin/slack.js.map +1 -0
  81. package/dist/src/providers/builtin/telegram.d.ts +21 -0
  82. package/dist/src/providers/builtin/telegram.js +123 -0
  83. package/dist/src/providers/builtin/telegram.js.map +1 -0
  84. package/dist/src/providers/builtin/whatsapp.d.ts +19 -0
  85. package/dist/src/providers/builtin/whatsapp.js +90 -0
  86. package/dist/src/providers/builtin/whatsapp.js.map +1 -0
  87. package/dist/src/providers/builtin/zalo.d.ts +17 -0
  88. package/dist/src/providers/builtin/zalo.js +70 -0
  89. package/dist/src/providers/builtin/zalo.js.map +1 -0
  90. package/dist/src/providers/catalog.d.ts +69 -0
  91. package/dist/src/providers/catalog.js +95 -0
  92. package/dist/src/providers/catalog.js.map +1 -0
  93. package/dist/src/providers/local-mock.d.ts +41 -0
  94. package/dist/src/providers/local-mock.js +243 -0
  95. package/dist/src/providers/local-mock.js.map +1 -0
  96. package/dist/src/providers/recorder.d.ts +19 -0
  97. package/dist/src/providers/recorder.js +160 -0
  98. package/dist/src/providers/recorder.js.map +1 -0
  99. package/dist/src/providers/registry.d.ts +8 -0
  100. package/dist/src/providers/registry.js +171 -0
  101. package/dist/src/providers/registry.js.map +1 -0
  102. package/dist/src/providers/types.d.ts +94 -0
  103. package/dist/src/providers/types.js +2 -0
  104. package/dist/src/providers/types.js.map +1 -0
  105. package/dist/src/providers/webhook-server.d.ts +12 -0
  106. package/dist/src/providers/webhook-server.js +118 -0
  107. package/dist/src/providers/webhook-server.js.map +1 -0
  108. package/docs/channel-setup.md +181 -0
  109. package/fixtures/examples/crabline.example.yaml +195 -0
  110. package/fixtures/examples/openclaw-bridge.yaml +125 -0
  111. package/package.json +64 -0
@@ -0,0 +1,48 @@
1
+ import type { LocalMockTargetCodec } from "../local-mock.js";
2
+ import type { InboundEnvelope } from "../types.js";
3
+ export type NativeIdRule = {
4
+ example: string;
5
+ name: string;
6
+ pattern: RegExp;
7
+ };
8
+ export declare function isRecord(value: unknown): value is Record<string, unknown>;
9
+ export declare function optionalRecord(value: Record<string, unknown>, key: string): Record<string, unknown> | undefined;
10
+ export declare function optionalString(value: Record<string, unknown>, key: string): string | undefined;
11
+ export declare function optionalNumberString(value: Record<string, unknown>, key: string): string | undefined;
12
+ export declare function optionalStringish(value: Record<string, unknown>, key: string): string | undefined;
13
+ export declare function normalizeAuthor(value: unknown): "assistant" | "system" | "user" | undefined;
14
+ export declare function requireNativeId(value: string, rule: NativeIdRule, label: string): string;
15
+ export declare function requireNativeInboundId(value: string, rule: NativeIdRule, label: string): string;
16
+ export declare function createNativeTargetCodec(options: {
17
+ channel: NativeIdRule;
18
+ channelLabel?: string | undefined;
19
+ thread?: NativeIdRule | undefined;
20
+ threadLabel?: string | undefined;
21
+ }): LocalMockTargetCodec;
22
+ export declare function genericMockPayloadWithNativeThread(params: {
23
+ channelRule?: NativeIdRule | undefined;
24
+ payload: Record<string, unknown>;
25
+ threadRule: NativeIdRule;
26
+ }): {
27
+ author?: "assistant" | "system" | "user" | undefined;
28
+ authorIsBot?: boolean;
29
+ id?: string | undefined;
30
+ raw: {};
31
+ text?: string | undefined;
32
+ } | {
33
+ author?: "assistant" | "system" | "user" | undefined;
34
+ authorIsBot?: boolean;
35
+ id?: string | undefined;
36
+ message?: {
37
+ author?: "assistant" | "system" | "user" | undefined;
38
+ authorIsBot?: boolean;
39
+ id?: string | undefined;
40
+ raw?: {} | null;
41
+ text?: string | undefined;
42
+ threadId: string;
43
+ };
44
+ raw: {};
45
+ text?: string | undefined;
46
+ threadId: string;
47
+ };
48
+ export declare function authorFromBotFlag(isBot: boolean | undefined): InboundEnvelope["author"];
@@ -0,0 +1,119 @@
1
+ import { CrablineError } from "../../core/errors.js";
2
+ export function isRecord(value) {
3
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
4
+ }
5
+ export function optionalRecord(value, key) {
6
+ const child = value[key];
7
+ return isRecord(child) ? child : undefined;
8
+ }
9
+ export function optionalString(value, key) {
10
+ const child = value[key];
11
+ return typeof child === "string" && child.length > 0 ? child : undefined;
12
+ }
13
+ export function optionalNumberString(value, key) {
14
+ const child = value[key];
15
+ return typeof child === "number" || typeof child === "bigint" ? child.toString() : undefined;
16
+ }
17
+ export function optionalStringish(value, key) {
18
+ return optionalString(value, key) ?? optionalNumberString(value, key);
19
+ }
20
+ export function normalizeAuthor(value) {
21
+ return value === "assistant" || value === "system" || value === "user" ? value : undefined;
22
+ }
23
+ export function requireNativeId(value, rule, label) {
24
+ if (!rule.pattern.test(value)) {
25
+ throw new CrablineError(`${label} must be a native ${rule.name} such as ${rule.example}.`, {
26
+ kind: "config",
27
+ });
28
+ }
29
+ return value;
30
+ }
31
+ export function requireNativeInboundId(value, rule, label) {
32
+ if (!rule.pattern.test(value)) {
33
+ throw new CrablineError(`${label} must be a native ${rule.name} such as ${rule.example}.`, {
34
+ kind: "inbound",
35
+ });
36
+ }
37
+ return value;
38
+ }
39
+ export function createNativeTargetCodec(options) {
40
+ const channelLabel = options.channelLabel ?? "channelId";
41
+ const threadLabel = options.threadLabel ?? "threadId";
42
+ const threadRule = options.thread ?? options.channel;
43
+ return {
44
+ normalize(target) {
45
+ const channelId = requireNativeId(target.channelId ?? target.id, options.channel, channelLabel);
46
+ const normalized = {
47
+ channelId,
48
+ id: target.id,
49
+ metadata: target.metadata,
50
+ };
51
+ if (target.threadId) {
52
+ normalized.threadId = requireNativeId(target.threadId, threadRule, threadLabel);
53
+ }
54
+ return normalized;
55
+ },
56
+ resolveThreadId(target) {
57
+ const normalized = this.normalize(target);
58
+ return normalized.threadId ?? normalized.channelId ?? normalized.id;
59
+ },
60
+ };
61
+ }
62
+ export function genericMockPayloadWithNativeThread(params) {
63
+ const message = optionalRecord(params.payload, "message");
64
+ const threadId = message
65
+ ? optionalString(message, "threadId")
66
+ : optionalString(params.payload, "threadId");
67
+ if (!threadId) {
68
+ return {
69
+ ...(normalizeAuthor(params.payload.author)
70
+ ? { author: normalizeAuthor(params.payload.author) }
71
+ : {}),
72
+ ...(typeof params.payload.authorIsBot === "boolean"
73
+ ? { authorIsBot: params.payload.authorIsBot }
74
+ : {}),
75
+ ...(optionalString(params.payload, "id") ? { id: optionalString(params.payload, "id") } : {}),
76
+ raw: params.payload.raw ?? params.payload,
77
+ ...(optionalString(params.payload, "text")
78
+ ? { text: optionalString(params.payload, "text") }
79
+ : {}),
80
+ };
81
+ }
82
+ const isValidThread = params.threadRule.pattern.test(threadId);
83
+ const isValidChannel = params.channelRule?.pattern.test(threadId) ?? false;
84
+ if (!isValidThread && !isValidChannel) {
85
+ throw new CrablineError(`mock webhook threadId must be a native ${params.threadRule.name}${params.channelRule ? ` or ${params.channelRule.name}` : ""}.`, { kind: "inbound" });
86
+ }
87
+ return {
88
+ ...(normalizeAuthor(params.payload.author)
89
+ ? { author: normalizeAuthor(params.payload.author) }
90
+ : {}),
91
+ ...(typeof params.payload.authorIsBot === "boolean"
92
+ ? { authorIsBot: params.payload.authorIsBot }
93
+ : {}),
94
+ ...(optionalString(params.payload, "id") ? { id: optionalString(params.payload, "id") } : {}),
95
+ ...(message
96
+ ? {
97
+ message: {
98
+ ...(normalizeAuthor(message.author) ? { author: normalizeAuthor(message.author) } : {}),
99
+ ...(typeof message.authorIsBot === "boolean"
100
+ ? { authorIsBot: message.authorIsBot }
101
+ : {}),
102
+ ...(optionalString(message, "id") ? { id: optionalString(message, "id") } : {}),
103
+ ...(message.raw !== undefined ? { raw: message.raw } : {}),
104
+ ...(optionalString(message, "text") ? { text: optionalString(message, "text") } : {}),
105
+ threadId,
106
+ },
107
+ }
108
+ : {}),
109
+ raw: params.payload.raw ?? params.payload,
110
+ ...(optionalString(params.payload, "text")
111
+ ? { text: optionalString(params.payload, "text") }
112
+ : {}),
113
+ threadId,
114
+ };
115
+ }
116
+ export function authorFromBotFlag(isBot) {
117
+ return isBot ? "assistant" : "user";
118
+ }
119
+ //# sourceMappingURL=native-local-mock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-local-mock.js","sourceRoot":"","sources":["../../../../src/providers/builtin/native-local-mock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { ProviderAdapter, ProviderContext, SendContext, WaitContext, WatchContext } from "../types.js";
2
+ type ScriptSendResult = {
3
+ accepted: boolean;
4
+ messageId: string;
5
+ threadId: string;
6
+ };
7
+ export declare class ScriptProviderAdapter implements ProviderAdapter {
8
+ #private;
9
+ readonly id: string;
10
+ readonly platform: "bluebubbles" | "discord" | "feishu" | "googlechat" | "imessage" | "irc" | "line" | "loopback" | "matrix" | "mattermost" | "msteams" | "nextcloudtalk" | "nostr" | "signal" | "slack" | "synologychat" | "telegram" | "tlon" | "twitch" | "webchat" | "whatsapp" | "zalo" | "zalouser";
11
+ readonly status: "bridge";
12
+ readonly supports: ("agent" | "probe" | "roundtrip" | "send")[];
13
+ constructor(context: ProviderContext);
14
+ normalizeTarget(target: ProviderContext["fixture"]["target"]): import("../types.js").NormalizedTarget;
15
+ probe(context: ProviderContext): Promise<{
16
+ details: string[];
17
+ healthy: boolean;
18
+ }>;
19
+ send(context: SendContext): Promise<ScriptSendResult>;
20
+ waitForInbound(context: WaitContext): Promise<{
21
+ author: "assistant" | "system" | "user";
22
+ id: string;
23
+ raw?: unknown;
24
+ sentAt: string;
25
+ text: string;
26
+ threadId: string;
27
+ provider: string;
28
+ } | null>;
29
+ watch(context: WatchContext): AsyncGenerator<{
30
+ author: "assistant" | "system" | "user";
31
+ id: string;
32
+ raw?: unknown;
33
+ sentAt: string;
34
+ text: string;
35
+ threadId: string;
36
+ provider: string;
37
+ }, void, unknown>;
38
+ }
39
+ export {};
@@ -0,0 +1,206 @@
1
+ import { spawn } from "node:child_process";
2
+ import path from "node:path";
3
+ import { CrablineError, ensureErrorMessage } from "../../core/errors.js";
4
+ function runScript(command, payload, cwd, shell) {
5
+ return new Promise((resolve, reject) => {
6
+ const child = spawn(command, {
7
+ cwd: cwd ? path.resolve(cwd) : process.cwd(),
8
+ env: process.env,
9
+ shell: shell ?? true,
10
+ stdio: ["pipe", "pipe", "pipe"],
11
+ });
12
+ let stdout = "";
13
+ let stderr = "";
14
+ child.stdout.on("data", (chunk) => {
15
+ stdout += String(chunk);
16
+ });
17
+ child.stderr.on("data", (chunk) => {
18
+ stderr += String(chunk);
19
+ });
20
+ child.on("error", reject);
21
+ child.on("close", (code) => {
22
+ if (code !== 0) {
23
+ reject(new CrablineError(`Script command failed: ${command}\n${stderr.trim() || stdout.trim()}`, {
24
+ kind: "connectivity",
25
+ }));
26
+ return;
27
+ }
28
+ try {
29
+ resolve(JSON.parse(stdout));
30
+ }
31
+ catch (error) {
32
+ reject(new CrablineError(`Script command did not return valid JSON: ${command}\n${ensureErrorMessage(error)}`, { kind: "config" }));
33
+ }
34
+ });
35
+ child.stdin.end(JSON.stringify(payload));
36
+ });
37
+ }
38
+ export class ScriptProviderAdapter {
39
+ id;
40
+ platform;
41
+ status = "bridge";
42
+ supports;
43
+ #config;
44
+ constructor(context) {
45
+ if (!context.config.script) {
46
+ throw new CrablineError(`Provider "${context.providerId}" is missing script configuration.`, {
47
+ kind: "config",
48
+ });
49
+ }
50
+ this.id = context.providerId;
51
+ this.platform = context.config.platform;
52
+ this.supports = [...context.config.capabilities];
53
+ this.#config = context.config.script;
54
+ }
55
+ normalizeTarget(target) {
56
+ const normalized = {
57
+ id: target.id,
58
+ metadata: target.metadata,
59
+ };
60
+ if (target.channelId) {
61
+ normalized.channelId = target.channelId;
62
+ }
63
+ if (target.threadId) {
64
+ normalized.threadId = target.threadId;
65
+ }
66
+ return normalized;
67
+ }
68
+ async probe(context) {
69
+ const command = this.#config.commands.probe;
70
+ if (!command) {
71
+ return {
72
+ details: ["probe command not configured"],
73
+ healthy: false,
74
+ };
75
+ }
76
+ const result = await runScript(command, createPayload(context), this.#config.cwd, this.#config.shell);
77
+ return {
78
+ details: result.details ?? [],
79
+ healthy: result.healthy,
80
+ };
81
+ }
82
+ async send(context) {
83
+ const command = this.#config.commands.send;
84
+ if (!command) {
85
+ throw new CrablineError(`Provider "${this.id}" is missing send command.`, {
86
+ kind: "config",
87
+ });
88
+ }
89
+ return runScript(command, {
90
+ ...createPayload(context),
91
+ outbound: {
92
+ mode: context.mode,
93
+ nonce: context.nonce,
94
+ target: this.normalizeTarget(context.fixture.target),
95
+ text: context.text,
96
+ },
97
+ }, this.#config.cwd, this.#config.shell);
98
+ }
99
+ async waitForInbound(context) {
100
+ const command = this.#config.commands.waitForInbound;
101
+ if (!command) {
102
+ return null;
103
+ }
104
+ const result = await runScript(command, {
105
+ ...createPayload(context),
106
+ wait: {
107
+ nonce: context.nonce,
108
+ since: context.since,
109
+ target: this.normalizeTarget(context.fixture.target),
110
+ timeoutMs: context.timeoutMs,
111
+ },
112
+ }, this.#config.cwd, this.#config.shell);
113
+ if (result.timeout || !result.message) {
114
+ return null;
115
+ }
116
+ return {
117
+ ...result.message,
118
+ provider: this.id,
119
+ };
120
+ }
121
+ async *watch(context) {
122
+ const command = this.#config.commands.watch;
123
+ if (!command) {
124
+ throw new CrablineError(`Provider "${this.id}" is missing watch command.`, {
125
+ kind: "config",
126
+ });
127
+ }
128
+ const child = spawn(command, {
129
+ cwd: this.#config.cwd ? path.resolve(this.#config.cwd) : process.cwd(),
130
+ env: process.env,
131
+ shell: this.#config.shell ?? true,
132
+ detached: process.platform !== "win32",
133
+ stdio: ["pipe", "pipe", "inherit"],
134
+ });
135
+ child.stdin.end(JSON.stringify({
136
+ ...createPayload(context),
137
+ watch: {
138
+ since: context.since,
139
+ target: this.normalizeTarget(context.fixture.target),
140
+ },
141
+ }));
142
+ let buffer = "";
143
+ const childClosed = new Promise((resolve) => {
144
+ if (child.exitCode !== null || child.signalCode !== null) {
145
+ resolve();
146
+ return;
147
+ }
148
+ child.once("close", () => resolve());
149
+ });
150
+ try {
151
+ for await (const chunk of child.stdout) {
152
+ buffer += String(chunk);
153
+ const lines = buffer.split("\n");
154
+ buffer = lines.pop() ?? "";
155
+ for (const line of lines) {
156
+ if (!line.trim()) {
157
+ continue;
158
+ }
159
+ const parsed = JSON.parse(line);
160
+ if (!parsed) {
161
+ continue;
162
+ }
163
+ yield {
164
+ ...parsed,
165
+ provider: this.id,
166
+ };
167
+ }
168
+ }
169
+ if (buffer.trim()) {
170
+ const parsed = JSON.parse(buffer);
171
+ if (parsed) {
172
+ yield {
173
+ ...parsed,
174
+ provider: this.id,
175
+ };
176
+ }
177
+ }
178
+ }
179
+ finally {
180
+ child.stdin.destroy();
181
+ if (child.exitCode === null && child.signalCode === null) {
182
+ child.kill();
183
+ if (process.platform !== "win32" && child.pid) {
184
+ try {
185
+ process.kill(-child.pid, "SIGKILL");
186
+ }
187
+ catch {
188
+ // The process group may have already exited with the shell.
189
+ }
190
+ }
191
+ }
192
+ await childClosed;
193
+ }
194
+ }
195
+ }
196
+ function createPayload(context) {
197
+ return {
198
+ fixture: context.fixture,
199
+ provider: {
200
+ config: context.config,
201
+ id: context.providerId,
202
+ manifestPath: context.manifestPath,
203
+ },
204
+ };
205
+ }
206
+ //# sourceMappingURL=script.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"script.js","sourceRoot":"","sources":["../../../../src/providers/builtin/script.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { ProviderConfig } from "../../config/schema.js";
2
+ import { LocalMockProviderAdapter } from "../local-mock.js";
3
+ import type { ProviderAdapter } from "../types.js";
4
+ export declare class SlackProviderAdapter extends LocalMockProviderAdapter implements ProviderAdapter {
5
+ constructor(id: string, config: ProviderConfig, _userName: string, _runtime?: unknown);
6
+ }
@@ -0,0 +1,106 @@
1
+ import path from "node:path";
2
+ import { CrablineError } from "../../core/errors.js";
3
+ import { LocalMockProviderAdapter } from "../local-mock.js";
4
+ import { genericMockPayloadWithNativeThread, isRecord, requireNativeInboundId, } from "./native-local-mock.js";
5
+ const SLACK_CHANNEL_ID_RULE = {
6
+ example: "C1234567890",
7
+ name: "Slack conversation id",
8
+ pattern: /^[CDG][A-Z0-9]{2,}$/u,
9
+ };
10
+ const SLACK_TS_RULE = {
11
+ example: "1700000000.000100",
12
+ name: "Slack timestamp",
13
+ pattern: /^\d{10}\.\d{6}$/u,
14
+ };
15
+ function requireSlackChannelId(value, label) {
16
+ if (!SLACK_CHANNEL_ID_RULE.pattern.test(value)) {
17
+ throw new CrablineError(`Slack ${label} must be a native Slack conversation id such as C1234567890, G1234567890, or D1234567890.`, { kind: "config" });
18
+ }
19
+ return value;
20
+ }
21
+ function requireSlackThreadTs(value, label) {
22
+ if (!SLACK_TS_RULE.pattern.test(value)) {
23
+ throw new CrablineError(`Slack ${label} must be a Slack timestamp such as 1700000000.000100.`, {
24
+ kind: "config",
25
+ });
26
+ }
27
+ return value;
28
+ }
29
+ function slackAuthorFromEvent(event) {
30
+ if (typeof event.bot_id === "string" || event.subtype === "bot_message") {
31
+ return "assistant";
32
+ }
33
+ return "user";
34
+ }
35
+ function normalizeSlackEventsPayload(payload) {
36
+ if (!isRecord(payload)) {
37
+ throw new CrablineError("Slack webhook payload must be an object", { kind: "inbound" });
38
+ }
39
+ if (isRecord(payload.event)) {
40
+ const event = payload.event;
41
+ const channel = event.channel;
42
+ const text = event.text;
43
+ if (typeof channel !== "string" || typeof text !== "string") {
44
+ throw new CrablineError("Slack event payload requires event.channel and event.text", {
45
+ kind: "inbound",
46
+ });
47
+ }
48
+ const threadTs = event.thread_ts;
49
+ const ts = event.ts;
50
+ return {
51
+ author: slackAuthorFromEvent(event),
52
+ ...(typeof ts === "string"
53
+ ? { id: requireNativeInboundId(ts, SLACK_TS_RULE, "Slack event.ts") }
54
+ : {}),
55
+ raw: payload,
56
+ text,
57
+ threadId: typeof threadTs === "string"
58
+ ? requireNativeInboundId(threadTs, SLACK_TS_RULE, "Slack event.thread_ts")
59
+ : requireNativeInboundId(channel, SLACK_CHANNEL_ID_RULE, "Slack event.channel"),
60
+ };
61
+ }
62
+ return genericMockPayloadWithNativeThread({
63
+ channelRule: SLACK_CHANNEL_ID_RULE,
64
+ payload,
65
+ threadRule: SLACK_TS_RULE,
66
+ });
67
+ }
68
+ const SLACK_CODEC = {
69
+ normalize(target) {
70
+ const channelId = requireSlackChannelId(target.channelId ?? target.id, "channelId");
71
+ const normalized = {
72
+ channelId,
73
+ id: target.id,
74
+ metadata: target.metadata,
75
+ };
76
+ if (target.threadId) {
77
+ normalized.threadId = requireSlackThreadTs(target.threadId, "threadId");
78
+ }
79
+ return normalized;
80
+ },
81
+ resolveThreadId(target) {
82
+ const normalized = this.normalize(target);
83
+ return normalized.threadId ?? normalized.channelId ?? normalized.id;
84
+ },
85
+ };
86
+ export class SlackProviderAdapter extends LocalMockProviderAdapter {
87
+ constructor(id, config, _userName, _runtime) {
88
+ super({
89
+ codec: SLACK_CODEC,
90
+ config,
91
+ id,
92
+ options: {
93
+ defaultWebhook: { host: "127.0.0.1", path: "/slack/events", port: 8787 },
94
+ endpointLabel: "events endpoint",
95
+ normalizeWebhookPayload: normalizeSlackEventsPayload,
96
+ platform: "slack",
97
+ publicUrl: config.slack?.webhook.publicUrl,
98
+ recorderPath: config.slack?.recorder.path
99
+ ? path.resolve(config.slack.recorder.path)
100
+ : undefined,
101
+ webhook: config.slack?.webhook,
102
+ },
103
+ });
104
+ }
105
+ }
106
+ //# sourceMappingURL=slack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.js","sourceRoot":"","sources":["../../../../src/providers/builtin/slack.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { ProviderConfig } from "../../config/schema.js";
2
+ import { LocalMockProviderAdapter } from "../local-mock.js";
3
+ import type { ProviderAdapter } from "../types.js";
4
+ type TelegramEnvironment = Partial<Pick<NodeJS.ProcessEnv, "TELEGRAM_API_BASE_URL" | "TELEGRAM_BOT_USERNAME" | "TELEGRAM_WEBHOOK_SECRET_TOKEN">>;
5
+ export declare function resolveTelegramAdapterConfig(config: ProviderConfig, env?: TelegramEnvironment): {
6
+ mode: "auto" | "polling" | "webhook";
7
+ apiUrl?: string;
8
+ secretToken?: string;
9
+ userName?: string;
10
+ };
11
+ export declare function normalizeTelegramWebhookPayload(payload: unknown): {
12
+ author?: "assistant" | "system" | "user" | undefined;
13
+ authorIsBot?: boolean;
14
+ id?: string | undefined;
15
+ raw: {};
16
+ text?: string | undefined;
17
+ };
18
+ export declare class TelegramProviderAdapter extends LocalMockProviderAdapter implements ProviderAdapter {
19
+ constructor(id: string, config: ProviderConfig, _userName: string);
20
+ }
21
+ export {};