@wooters/crabcallr 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Chuck Wooters
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,136 @@
1
+ # CrabCallr Plugin for OpenClaw
2
+
3
+ Talk to your OpenClaw assistant via phone or browser with CrabCallr.
4
+
5
+ ## Overview
6
+
7
+ CrabCallr is a voice interface that lets you have natural conversations with your OpenClaw assistant. This plugin connects your OpenClaw instance to the CrabCallr hosted service, enabling:
8
+
9
+ - **Browser calling** - Talk to OpenClaw from any web browser via WebRTC
10
+ - **Phone calling** - Call a phone number to reach your assistant (Basic tier)
11
+ - **Streaming speech recognition** - Real-time transcription with Deepgram
12
+ - **Natural voice responses** - High-quality text-to-speech with ElevenLabs
13
+ - **Barge-in support** - Interrupt the assistant mid-response
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ openclaw plugins install @wooters/crabcallr
19
+ ```
20
+
21
+ ## Setup
22
+
23
+ 1. **Get an API key** - Sign up at [app.crabcallr.com](https://app.crabcallr.com) and generate an API key
24
+
25
+ 2. **Configure the plugin** - Add to your `~/.openclaw/openclaw.json`:
26
+
27
+ ```json
28
+ {
29
+ "channels": {
30
+ "crabcallr": {
31
+ "accounts": {
32
+ "default": {
33
+ "apiKey": "cc_your_api_key_here"
34
+ }
35
+ }
36
+ }
37
+ }
38
+ }
39
+ ```
40
+
41
+ 3. **Restart OpenClaw Gateway** - The plugin will automatically connect to the CrabCallr service
42
+
43
+ 4. **Start calling** - Visit [app.crabcallr.com](https://app.crabcallr.com) and click "Call" to talk to your assistant
44
+
45
+ ## Configuration Options
46
+
47
+ | Option | Type | Default | Description |
48
+ | ---------------------- | ------- | ------------------------------- | -------------------------------------- |
49
+ | `apiKey` | string | (required) | Your CrabCallr API key |
50
+ | `serviceUrl` | string | `wss://ws.crabcallr.com/plugin` | WebSocket URL for the service |
51
+ | `autoConnect` | boolean | `true` | Connect automatically on startup |
52
+ | `reconnectInterval` | number | `5000` | Reconnection interval in ms |
53
+ | `maxReconnectAttempts` | number | `10` | Max reconnect attempts (0 = unlimited) |
54
+
55
+ ## CLI Commands
56
+
57
+ Check connection status:
58
+
59
+ ```bash
60
+ openclaw channels status --probe
61
+ ```
62
+
63
+ ## How It Works
64
+
65
+ ```plaintext
66
+ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
67
+ │ Your Phone │────▶│ CrabCallr │────▶│ Your │
68
+ │ or Browser │◀────│ Service │◀────│ OpenClaw │
69
+ └─────────────────┘ └─────────────────┘ └─────────────────┘
70
+ │ │ │
71
+ │ Audio/WebRTC │ WebSocket │ Messages
72
+ │ │ │
73
+ You speak Transcribed text OpenClaw responds
74
+ You hear Response audio via this plugin
75
+ ```
76
+
77
+ 1. You speak into your phone or browser
78
+ 2. CrabCallr transcribes your speech in real-time (Deepgram)
79
+ 3. The transcript is sent to your OpenClaw via this plugin
80
+ 4. OpenClaw processes your request and generates a response
81
+ 5. The response is sent back to CrabCallr
82
+ 6. CrabCallr converts the response to speech (ElevenLabs)
83
+ 7. You hear the response
84
+
85
+ ## Voice Skill
86
+
87
+ This plugin includes a voice skill that automatically adapts OpenClaw's responses for spoken conversation:
88
+
89
+ - Concise, conversational responses (1-3 sentences)
90
+ - No bullet points, markdown, or code blocks
91
+ - Natural speech patterns with contractions
92
+ - Graceful handling of interruptions
93
+
94
+ The skill is automatically loaded when the plugin is enabled.
95
+
96
+ ## Pricing
97
+
98
+ - **Free tier** - 30 min/month browser calling via WebRTC
99
+ - **Basic tier** ($5/month) - 120 min browser + 30 min phone calling, $0.15/minute overage
100
+
101
+ See [crabcallr.com](https://crabcallr.com) for current pricing.
102
+
103
+ ## Troubleshooting
104
+
105
+ ### Plugin won't connect
106
+
107
+ - Verify your API key is correct (should start with `cc_`)
108
+ - Check that your OpenClaw Gateway can reach `ws.crabcallr.com`
109
+ - Run `openclaw channels status --probe` to see connection details
110
+
111
+ ### No response from assistant
112
+
113
+ - Ensure your OpenClaw agent is configured and working
114
+ - Check OpenClaw logs for errors processing messages
115
+
116
+ ### Poor audio quality
117
+
118
+ - Use a quiet environment or headphones
119
+ - Browser calling typically has better quality than phone
120
+
121
+ ## Development
122
+
123
+ ```bash
124
+ # Install dependencies
125
+ npm install
126
+
127
+ # Build
128
+ npm run build
129
+
130
+ # Watch mode
131
+ npm run dev
132
+ ```
133
+
134
+ ## License
135
+
136
+ MIT
@@ -0,0 +1,28 @@
1
+ import type { ChannelPlugin } from "openclaw/plugin-sdk";
2
+ import type { CrabCallrAccountConfig, ConnectionStatus } from "./types.js";
3
+ type ResolvedCrabCallrAccount = {
4
+ accountId: string;
5
+ name?: string;
6
+ enabled: boolean;
7
+ configured: boolean;
8
+ config: CrabCallrAccountConfig;
9
+ };
10
+ export declare function getCrabCallrStatus(accountId?: string): {
11
+ accountId: string;
12
+ connected: boolean;
13
+ status: ConnectionStatus;
14
+ userId: string | null;
15
+ running: boolean;
16
+ reconnectAttempts: number;
17
+ };
18
+ export declare function sendCrabCallrResponse(params: {
19
+ accountId?: string;
20
+ requestId: string;
21
+ text: string;
22
+ }): {
23
+ ok: boolean;
24
+ error?: string;
25
+ };
26
+ export declare const crabcallrPlugin: ChannelPlugin<ResolvedCrabCallrAccount>;
27
+ export {};
28
+ //# sourceMappingURL=channel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,aAAa,EAGd,MAAM,qBAAqB,CAAC;AAQ7B,OAAO,KAAK,EACV,sBAAsB,EAEtB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAKpB,KAAK,wBAAwB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,sBAAsB,CAAC;CAChC,CAAC;AA4RF,wBAAgB,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAqBA;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAYlC;AAED,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,wBAAwB,CAgNnE,CAAC"}
@@ -0,0 +1,448 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ import { createReplyPrefixOptions, DEFAULT_ACCOUNT_ID, normalizeAccountId, } from "openclaw/plugin-sdk";
3
+ import { validateConfig } from "./config.js";
4
+ import { getCrabCallrRuntime } from "./runtime.js";
5
+ import { CrabCallrWebSocket } from "./websocket.js";
6
+ const CHANNEL_ID = "crabcallr";
7
+ const connections = new Map();
8
+ const CrabCallrAccountSchema = Type.Object({
9
+ name: Type.Optional(Type.String()),
10
+ enabled: Type.Optional(Type.Boolean()),
11
+ apiKey: Type.Optional(Type.String({
12
+ description: "Your CrabCallr API key from app.crabcallr.com",
13
+ })),
14
+ serviceUrl: Type.Optional(Type.String({
15
+ description: "CrabCallr service WebSocket URL",
16
+ default: "wss://ws.crabcallr.com/plugin",
17
+ })),
18
+ autoConnect: Type.Optional(Type.Boolean({
19
+ description: "Automatically connect to CrabCallr service on startup",
20
+ default: true,
21
+ })),
22
+ reconnectInterval: Type.Optional(Type.Number({
23
+ description: "Reconnection interval in milliseconds",
24
+ default: 5000,
25
+ })),
26
+ maxReconnectAttempts: Type.Optional(Type.Number({
27
+ description: "Maximum number of reconnection attempts (0 for unlimited)",
28
+ default: 10,
29
+ })),
30
+ }, { additionalProperties: false });
31
+ const CrabCallrChannelSchema = Type.Object({
32
+ ...CrabCallrAccountSchema.properties,
33
+ accounts: Type.Optional(Type.Record(Type.String(), CrabCallrAccountSchema)),
34
+ }, { additionalProperties: false });
35
+ const crabcallrConfigSchema = {
36
+ schema: CrabCallrChannelSchema,
37
+ uiHints: {
38
+ apiKey: {
39
+ label: "CrabCallr API Key",
40
+ sensitive: true,
41
+ placeholder: "cc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
42
+ },
43
+ serviceUrl: {
44
+ label: "Service URL",
45
+ advanced: true,
46
+ },
47
+ autoConnect: {
48
+ label: "Auto-connect on startup",
49
+ },
50
+ reconnectInterval: {
51
+ label: "Reconnect interval (ms)",
52
+ advanced: true,
53
+ },
54
+ maxReconnectAttempts: {
55
+ label: "Max reconnect attempts",
56
+ advanced: true,
57
+ },
58
+ },
59
+ };
60
+ function resolveChannelConfig(cfg) {
61
+ const channel = cfg.channels?.crabcallr;
62
+ if (!channel || typeof channel !== "object") {
63
+ return {};
64
+ }
65
+ return channel;
66
+ }
67
+ function hasBaseConfig(cfg) {
68
+ return Boolean(cfg.apiKey ||
69
+ cfg.serviceUrl ||
70
+ typeof cfg.autoConnect === "boolean" ||
71
+ typeof cfg.reconnectInterval === "number" ||
72
+ typeof cfg.maxReconnectAttempts === "number" ||
73
+ typeof cfg.enabled === "boolean" ||
74
+ cfg.name);
75
+ }
76
+ function listCrabCallrAccountIds(cfg) {
77
+ const channel = resolveChannelConfig(cfg);
78
+ const ids = new Set();
79
+ if (hasBaseConfig(channel)) {
80
+ ids.add(DEFAULT_ACCOUNT_ID);
81
+ }
82
+ const accounts = channel.accounts;
83
+ if (accounts && typeof accounts === "object") {
84
+ for (const key of Object.keys(accounts)) {
85
+ if (!key) {
86
+ continue;
87
+ }
88
+ ids.add(normalizeAccountId(key));
89
+ }
90
+ }
91
+ if (ids.size === 0) {
92
+ ids.add(DEFAULT_ACCOUNT_ID);
93
+ }
94
+ return [...ids].sort((a, b) => a.localeCompare(b));
95
+ }
96
+ function resolveAccountConfig(cfg, accountId) {
97
+ const channel = resolveChannelConfig(cfg);
98
+ const { accounts: _ignored, ...base } = channel;
99
+ const accounts = channel.accounts ?? {};
100
+ const direct = accounts[accountId];
101
+ if (direct) {
102
+ return { ...base, ...direct };
103
+ }
104
+ const normalized = normalizeAccountId(accountId);
105
+ const matchKey = Object.keys(accounts).find((key) => normalizeAccountId(key) === normalized);
106
+ const resolved = matchKey ? accounts[matchKey] : undefined;
107
+ return { ...base, ...(resolved ?? {}) };
108
+ }
109
+ function resolveDefaultCrabCallrAccountId(cfg) {
110
+ const ids = listCrabCallrAccountIds(cfg);
111
+ if (ids.includes(DEFAULT_ACCOUNT_ID)) {
112
+ return DEFAULT_ACCOUNT_ID;
113
+ }
114
+ return ids[0] ?? DEFAULT_ACCOUNT_ID;
115
+ }
116
+ function resolveCrabCallrAccount(params) {
117
+ const id = normalizeAccountId(params.accountId ?? DEFAULT_ACCOUNT_ID);
118
+ const merged = resolveAccountConfig(params.cfg, id);
119
+ const channel = resolveChannelConfig(params.cfg);
120
+ const enabled = (channel.enabled ?? true) && merged.enabled !== false;
121
+ const configured = Boolean(merged.apiKey?.trim());
122
+ return {
123
+ accountId: id,
124
+ name: merged.name?.trim() || undefined,
125
+ enabled,
126
+ configured,
127
+ config: merged,
128
+ };
129
+ }
130
+ function createStatusSink(ctx) {
131
+ return (patch) => {
132
+ const base = ctx.getStatus?.() ?? { accountId: ctx.accountId };
133
+ ctx.setStatus?.({ ...base, ...patch, accountId: ctx.accountId });
134
+ };
135
+ }
136
+ async function handleRequest(params) {
137
+ const { cfg, accountId, requestId, text, callId, ws, statusSink, logError } = params;
138
+ const core = getCrabCallrRuntime();
139
+ const route = core.channel.routing.resolveAgentRoute({
140
+ cfg,
141
+ channel: CHANNEL_ID,
142
+ accountId,
143
+ peer: {
144
+ kind: "dm",
145
+ id: callId,
146
+ },
147
+ });
148
+ const storePath = core.channel.session.resolveStorePath(cfg.session?.store, {
149
+ agentId: route.agentId,
150
+ });
151
+ const envelopeOptions = core.channel.reply.resolveEnvelopeFormatOptions(cfg);
152
+ const previousTimestamp = core.channel.session.readSessionUpdatedAt({
153
+ storePath,
154
+ sessionKey: route.sessionKey,
155
+ });
156
+ const body = core.channel.reply.formatAgentEnvelope({
157
+ channel: "CrabCallr",
158
+ from: "Voice Caller",
159
+ timestamp: Date.now(),
160
+ previousTimestamp,
161
+ envelope: envelopeOptions,
162
+ body: text,
163
+ });
164
+ const ctxPayload = core.channel.reply.finalizeInboundContext({
165
+ Body: body,
166
+ RawBody: text,
167
+ CommandBody: text,
168
+ From: `crabcallr:call:${callId}`,
169
+ To: `crabcallr:call:${callId}`,
170
+ SessionKey: route.sessionKey,
171
+ AccountId: route.accountId,
172
+ ChatType: "direct",
173
+ ConversationLabel: `call:${callId}`,
174
+ SenderName: "Voice Caller",
175
+ SenderId: callId,
176
+ Provider: CHANNEL_ID,
177
+ Surface: CHANNEL_ID,
178
+ MessageSid: requestId,
179
+ Timestamp: Date.now(),
180
+ OriginatingChannel: CHANNEL_ID,
181
+ OriginatingTo: `crabcallr:call:${callId}`,
182
+ });
183
+ await core.channel.session.recordInboundSession({
184
+ storePath,
185
+ sessionKey: ctxPayload.SessionKey ?? route.sessionKey,
186
+ ctx: ctxPayload,
187
+ onRecordError: (err) => {
188
+ logError(`[CrabCallr] Failed updating session meta: ${String(err)}`);
189
+ },
190
+ });
191
+ const { onModelSelected, ...prefixOptions } = createReplyPrefixOptions({
192
+ cfg,
193
+ agentId: route.agentId,
194
+ channel: CHANNEL_ID,
195
+ accountId: route.accountId,
196
+ });
197
+ await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
198
+ ctx: ctxPayload,
199
+ cfg,
200
+ dispatcherOptions: {
201
+ ...prefixOptions,
202
+ deliver: async (payload, info) => {
203
+ if (info.kind !== "final") {
204
+ return;
205
+ }
206
+ const replyText = payload.text?.trim();
207
+ if (!replyText) {
208
+ return;
209
+ }
210
+ ws.sendResponse(requestId, replyText);
211
+ statusSink?.({ lastOutboundAt: Date.now() });
212
+ },
213
+ onError: (err, info) => {
214
+ logError(`[CrabCallr] ${info.kind} reply failed: ${String(err)}`);
215
+ },
216
+ },
217
+ replyOptions: {
218
+ onModelSelected,
219
+ disableBlockStreaming: true,
220
+ },
221
+ });
222
+ }
223
+ function getConnection(accountId) {
224
+ return connections.get(normalizeAccountId(accountId));
225
+ }
226
+ export function getCrabCallrStatus(accountId) {
227
+ const resolvedId = normalizeAccountId(accountId ?? DEFAULT_ACCOUNT_ID);
228
+ const record = connections.get(resolvedId);
229
+ if (!record) {
230
+ return {
231
+ accountId: resolvedId,
232
+ connected: false,
233
+ status: "disconnected",
234
+ userId: null,
235
+ running: false,
236
+ reconnectAttempts: 0,
237
+ };
238
+ }
239
+ return {
240
+ accountId: resolvedId,
241
+ connected: record.ws.isConnected(),
242
+ status: record.ws.getStatus(),
243
+ userId: record.ws.getUserId(),
244
+ running: true,
245
+ reconnectAttempts: record.ws.getReconnectAttempts(),
246
+ };
247
+ }
248
+ export function sendCrabCallrResponse(params) {
249
+ const resolvedId = normalizeAccountId(params.accountId ?? DEFAULT_ACCOUNT_ID);
250
+ const record = connections.get(resolvedId);
251
+ if (!record) {
252
+ return { ok: false, error: "CrabCallr connection not running" };
253
+ }
254
+ if (!record.ws.isConnected()) {
255
+ return { ok: false, error: "CrabCallr is not connected" };
256
+ }
257
+ record.ws.sendResponse(params.requestId, params.text);
258
+ record.statusSink?.({ lastOutboundAt: Date.now() });
259
+ return { ok: true };
260
+ }
261
+ export const crabcallrPlugin = {
262
+ id: CHANNEL_ID,
263
+ meta: {
264
+ id: CHANNEL_ID,
265
+ label: "CrabCallr Voice",
266
+ selectionLabel: "CrabCallr (Voice)",
267
+ docsPath: "/channels/crabcallr",
268
+ blurb: "Voice calling via phone or browser",
269
+ aliases: ["voice", "phone"],
270
+ order: 100,
271
+ },
272
+ capabilities: {
273
+ chatTypes: ["direct"],
274
+ blockStreaming: true,
275
+ },
276
+ reload: { configPrefixes: ["channels.crabcallr"] },
277
+ configSchema: crabcallrConfigSchema,
278
+ config: {
279
+ listAccountIds: (cfg) => listCrabCallrAccountIds(cfg),
280
+ resolveAccount: (cfg, accountId) => resolveCrabCallrAccount({ cfg, accountId }),
281
+ defaultAccountId: (cfg) => resolveDefaultCrabCallrAccountId(cfg),
282
+ isConfigured: (account) => account.configured,
283
+ isEnabled: (account) => account.enabled,
284
+ describeAccount: (account) => ({
285
+ accountId: account.accountId,
286
+ name: account.name,
287
+ enabled: account.enabled,
288
+ configured: account.configured,
289
+ }),
290
+ },
291
+ gateway: {
292
+ startAccount: async (ctx) => {
293
+ const account = ctx.account;
294
+ if (!account.enabled) {
295
+ ctx.log?.info(`[${account.accountId}] CrabCallr disabled`);
296
+ ctx.setStatus?.({
297
+ accountId: account.accountId,
298
+ running: false,
299
+ connected: false,
300
+ lastStopAt: Date.now(),
301
+ });
302
+ return;
303
+ }
304
+ let config;
305
+ try {
306
+ config = validateConfig({
307
+ apiKey: account.config.apiKey,
308
+ serviceUrl: account.config.serviceUrl,
309
+ autoConnect: account.config.autoConnect,
310
+ reconnectInterval: account.config.reconnectInterval,
311
+ maxReconnectAttempts: account.config.maxReconnectAttempts,
312
+ });
313
+ }
314
+ catch (err) {
315
+ const message = err instanceof Error ? err.message : String(err);
316
+ ctx.setStatus?.({
317
+ accountId: account.accountId,
318
+ running: false,
319
+ connected: false,
320
+ lastError: message,
321
+ lastStopAt: Date.now(),
322
+ });
323
+ throw err;
324
+ }
325
+ const logger = ctx.log ??
326
+ {
327
+ info: console.log,
328
+ warn: console.warn,
329
+ error: console.error,
330
+ debug: console.debug,
331
+ };
332
+ const statusSink = createStatusSink({
333
+ accountId: account.accountId,
334
+ getStatus: ctx.getStatus,
335
+ setStatus: ctx.setStatus,
336
+ });
337
+ const ws = new CrabCallrWebSocket(config, logger);
338
+ connections.set(account.accountId, { accountId: account.accountId, ws, statusSink });
339
+ statusSink({
340
+ running: true,
341
+ connected: ws.isConnected(),
342
+ lastStartAt: Date.now(),
343
+ lastError: null,
344
+ reconnectAttempts: ws.getReconnectAttempts(),
345
+ });
346
+ ws.on("connected", () => {
347
+ statusSink({
348
+ connected: true,
349
+ lastConnectedAt: Date.now(),
350
+ lastDisconnect: null,
351
+ reconnectAttempts: ws.getReconnectAttempts(),
352
+ lastError: null,
353
+ });
354
+ });
355
+ ws.on("disconnected", (reason) => {
356
+ statusSink({
357
+ connected: false,
358
+ lastDisconnect: {
359
+ at: Date.now(),
360
+ error: reason,
361
+ },
362
+ reconnectAttempts: ws.getReconnectAttempts(),
363
+ });
364
+ });
365
+ ws.on("error", (error) => {
366
+ statusSink({
367
+ lastError: error.message,
368
+ reconnectAttempts: ws.getReconnectAttempts(),
369
+ });
370
+ });
371
+ ws.on("request", (requestId, text, callId) => {
372
+ statusSink({ lastInboundAt: Date.now() });
373
+ handleRequest({
374
+ cfg: ctx.cfg,
375
+ accountId: account.accountId,
376
+ requestId,
377
+ text,
378
+ callId,
379
+ ws,
380
+ statusSink,
381
+ logError: (message) => logger.error(message),
382
+ }).catch((err) => {
383
+ logger.error(`[CrabCallr] Failed to handle request: ${String(err)}`);
384
+ });
385
+ });
386
+ ws.on("callStart", (callId, source) => {
387
+ logger.info(`[CrabCallr] Call started from ${source}: ${callId}`);
388
+ });
389
+ ws.on("callEnd", (callId, durationSeconds, source) => {
390
+ logger.info(`[CrabCallr] Call ended: ${callId} (${durationSeconds}s from ${source})`);
391
+ });
392
+ const stop = () => {
393
+ ws.disconnect();
394
+ connections.delete(account.accountId);
395
+ statusSink({
396
+ running: false,
397
+ connected: false,
398
+ lastStopAt: Date.now(),
399
+ });
400
+ };
401
+ ctx.abortSignal.addEventListener("abort", stop, { once: true });
402
+ if (config.autoConnect) {
403
+ logger.info("[CrabCallr] Auto-connecting to CrabCallr service");
404
+ ws.connect();
405
+ }
406
+ },
407
+ stopAccount: async (ctx) => {
408
+ const record = getConnection(ctx.accountId);
409
+ if (record) {
410
+ record.ws.disconnect();
411
+ connections.delete(record.accountId);
412
+ }
413
+ ctx.setStatus?.({
414
+ accountId: ctx.accountId,
415
+ running: false,
416
+ connected: false,
417
+ lastStopAt: Date.now(),
418
+ });
419
+ },
420
+ },
421
+ status: {
422
+ defaultRuntime: {
423
+ accountId: DEFAULT_ACCOUNT_ID,
424
+ running: false,
425
+ connected: false,
426
+ lastStartAt: null,
427
+ lastStopAt: null,
428
+ lastError: null,
429
+ },
430
+ buildAccountSnapshot: ({ account, runtime, }) => ({
431
+ accountId: account.accountId,
432
+ name: account.name,
433
+ enabled: account.enabled,
434
+ configured: account.configured,
435
+ running: runtime?.running ?? false,
436
+ connected: runtime?.connected ?? false,
437
+ reconnectAttempts: runtime?.reconnectAttempts ?? 0,
438
+ lastConnectedAt: runtime?.lastConnectedAt ?? null,
439
+ lastDisconnect: runtime?.lastDisconnect ?? null,
440
+ lastError: runtime?.lastError ?? null,
441
+ lastStartAt: runtime?.lastStartAt ?? null,
442
+ lastStopAt: runtime?.lastStopAt ?? null,
443
+ lastInboundAt: runtime?.lastInboundAt ?? null,
444
+ lastOutboundAt: runtime?.lastOutboundAt ?? null,
445
+ }),
446
+ },
447
+ };
448
+ //# sourceMappingURL=channel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel.js","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAQzC,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAMnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEpD,MAAM,UAAU,GAAG,WAAW,CAAC;AAgB/B,MAAM,WAAW,GAAG,IAAI,GAAG,EAA+B,CAAC;AAE3D,MAAM,sBAAsB,GAAG,IAAI,CAAC,MAAM,CACxC;IACE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;IAClC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IACtC,MAAM,EAAE,IAAI,CAAC,QAAQ,CACnB,IAAI,CAAC,MAAM,CAAC;QACV,WAAW,EAAE,+CAA+C;KAC7D,CAAC,CACH;IACD,UAAU,EAAE,IAAI,CAAC,QAAQ,CACvB,IAAI,CAAC,MAAM,CAAC;QACV,WAAW,EAAE,iCAAiC;QAC9C,OAAO,EAAE,+BAA+B;KACzC,CAAC,CACH;IACD,WAAW,EAAE,IAAI,CAAC,QAAQ,CACxB,IAAI,CAAC,OAAO,CAAC;QACX,WAAW,EAAE,uDAAuD;QACpE,OAAO,EAAE,IAAI;KACd,CAAC,CACH;IACD,iBAAiB,EAAE,IAAI,CAAC,QAAQ,CAC9B,IAAI,CAAC,MAAM,CAAC;QACV,WAAW,EAAE,uCAAuC;QACpD,OAAO,EAAE,IAAI;KACd,CAAC,CACH;IACD,oBAAoB,EAAE,IAAI,CAAC,QAAQ,CACjC,IAAI,CAAC,MAAM,CAAC;QACV,WAAW,EAAE,2DAA2D;QACxE,OAAO,EAAE,EAAE;KACZ,CAAC,CACH;CACF,EACD,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAChC,CAAC;AAEF,MAAM,sBAAsB,GAAG,IAAI,CAAC,MAAM,CACxC;IACE,GAAG,sBAAsB,CAAC,UAAU;IACpC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,sBAAsB,CAAC,CAAC;CAC5E,EACD,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAChC,CAAC;AAEF,MAAM,qBAAqB,GAAG;IAC5B,MAAM,EAAE,sBAAsB;IAC9B,OAAO,EAAE;QACP,MAAM,EAAE;YACN,KAAK,EAAE,mBAAmB;YAC1B,SAAS,EAAE,IAAI;YACf,WAAW,EAAE,qCAAqC;SACnD;QACD,UAAU,EAAE;YACV,KAAK,EAAE,aAAa;YACpB,QAAQ,EAAE,IAAI;SACf;QACD,WAAW,EAAE;YACX,KAAK,EAAE,yBAAyB;SACjC;QACD,iBAAiB,EAAE;YACjB,KAAK,EAAE,yBAAyB;YAChC,QAAQ,EAAE,IAAI;SACf;QACD,oBAAoB,EAAE;YACpB,KAAK,EAAE,wBAAwB;YAC/B,QAAQ,EAAE,IAAI;SACf;KACF;CACF,CAAC;AAEF,SAAS,oBAAoB,CAAC,GAAmB;IAC/C,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC;IACxC,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,OAAiC,CAAC;AAC3C,CAAC;AAED,SAAS,aAAa,CAAC,GAA2B;IAChD,OAAO,OAAO,CACZ,GAAG,CAAC,MAAM;QACR,GAAG,CAAC,UAAU;QACd,OAAO,GAAG,CAAC,WAAW,KAAK,SAAS;QACpC,OAAO,GAAG,CAAC,iBAAiB,KAAK,QAAQ;QACzC,OAAO,GAAG,CAAC,oBAAoB,KAAK,QAAQ;QAC5C,OAAO,GAAG,CAAC,OAAO,KAAK,SAAS;QAChC,GAAG,CAAC,IAAI,CACX,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAAC,GAAmB;IAClD,MAAM,OAAO,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,GAAG,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAC9B,CAAC;IACD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC7C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,SAAS;YACX,CAAC;YACD,GAAG,CAAC,GAAG,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACnB,GAAG,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAmB,EAAE,SAAiB;IAClE,MAAM,OAAO,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAC1C,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IAChD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;IACxC,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;IACnC,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC;IAChC,CAAC;IACD,MAAM,UAAU,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACjD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CACzC,CAAC,GAAG,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,UAAU,CAChD,CAAC;IACF,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3D,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,CAAC;AAC1C,CAAC;AAED,SAAS,gCAAgC,CAAC,GAAmB;IAC3D,MAAM,GAAG,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,GAAG,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACrC,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IACD,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,kBAAkB,CAAC;AACtC,CAAC;AAED,SAAS,uBAAuB,CAAC,MAGhC;IACC,MAAM,EAAE,GAAG,kBAAkB,CAAC,MAAM,CAAC,SAAS,IAAI,kBAAkB,CAAC,CAAC;IACtE,MAAM,MAAM,GAAG,oBAAoB,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,oBAAoB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,KAAK,KAAK,CAAC;IACtE,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,OAAO;QACL,SAAS,EAAE,EAAE;QACb,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,SAAS;QACtC,OAAO;QACP,UAAU;QACV,MAAM,EAAE,MAAM;KACf,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,GAIzB;IACC,OAAO,CAAC,KAAsC,EAAE,EAAE;QAChD,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC;QAC/D,GAAG,CAAC,SAAS,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;IACnE,CAAC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,MAS5B;IACC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;IACrF,MAAM,IAAI,GAAG,mBAAmB,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC;QACnD,GAAG;QACH,OAAO,EAAE,UAAU;QACnB,SAAS;QACT,IAAI,EAAE;YACJ,IAAI,EAAE,IAAI;YACV,EAAE,EAAE,MAAM;SACX;KACF,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE;QAC1E,OAAO,EAAE,KAAK,CAAC,OAAO;KACvB,CAAC,CAAC;IACH,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,GAAG,CAAC,CAAC;IAC7E,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC;QAClE,SAAS;QACT,UAAU,EAAE,KAAK,CAAC,UAAU;KAC7B,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC;QAClD,OAAO,EAAE,WAAW;QACpB,IAAI,EAAE,cAAc;QACpB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,iBAAiB;QACjB,QAAQ,EAAE,eAAe;QACzB,IAAI,EAAE,IAAI;KACX,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC;QAC3D,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,IAAI;QACb,WAAW,EAAE,IAAI;QACjB,IAAI,EAAE,kBAAkB,MAAM,EAAE;QAChC,EAAE,EAAE,kBAAkB,MAAM,EAAE;QAC9B,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,QAAQ,EAAE,QAAQ;QAClB,iBAAiB,EAAE,QAAQ,MAAM,EAAE;QACnC,UAAU,EAAE,cAAc;QAC1B,QAAQ,EAAE,MAAM;QAChB,QAAQ,EAAE,UAAU;QACpB,OAAO,EAAE,UAAU;QACnB,UAAU,EAAE,SAAS;QACrB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,kBAAkB,EAAE,UAAU;QAC9B,aAAa,EAAE,kBAAkB,MAAM,EAAE;KAC1C,CAAC,CAAC;IAEH,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC;QAC9C,SAAS;QACT,UAAU,EAAE,UAAU,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU;QACrD,GAAG,EAAE,UAAU;QACf,aAAa,EAAE,CAAC,GAAY,EAAE,EAAE;YAC9B,QAAQ,CAAC,6CAA6C,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvE,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,EAAE,eAAe,EAAE,GAAG,aAAa,EAAE,GAAG,wBAAwB,CAAC;QACrE,GAAG;QACH,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,OAAO,EAAE,UAAU;QACnB,SAAS,EAAE,KAAK,CAAC,SAAS;KAC3B,CAAC,CAAC;IAEH,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC;QAChE,GAAG,EAAE,UAAU;QACf,GAAG;QACH,iBAAiB,EAAE;YACjB,GAAG,aAAa;YAChB,OAAO,EAAE,KAAK,EACZ,OAAqB,EACrB,IAA0C,EAC1C,EAAE;gBACF,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBAC1B,OAAO;gBACT,CAAC;gBACD,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;gBACvC,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,OAAO;gBACT,CAAC;gBACD,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;gBACtC,UAAU,EAAE,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAC/C,CAAC;YACD,OAAO,EAAE,CAAC,GAAY,EAAE,IAA0C,EAAE,EAAE;gBACpE,QAAQ,CAAC,eAAe,IAAI,CAAC,IAAI,kBAAkB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACpE,CAAC;SACF;QACD,YAAY,EAAE;YACZ,eAAe;YACf,qBAAqB,EAAE,IAAI;SAC5B;KACF,CAAC,CAAC;AACL,CAAC;AAED,SAAS,aAAa,CAAC,SAAiB;IACtC,OAAO,WAAW,CAAC,GAAG,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,SAAkB;IAQnD,MAAM,UAAU,GAAG,kBAAkB,CAAC,SAAS,IAAI,kBAAkB,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO;YACL,SAAS,EAAE,UAAU;YACrB,SAAS,EAAE,KAAK;YAChB,MAAM,EAAE,cAAc;YACtB,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,KAAK;YACd,iBAAiB,EAAE,CAAC;SACrB,CAAC;IACJ,CAAC;IACD,OAAO;QACL,SAAS,EAAE,UAAU;QACrB,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE;QAClC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE;QAC7B,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE;QAC7B,OAAO,EAAE,IAAI;QACb,iBAAiB,EAAE,MAAM,CAAC,EAAE,CAAC,oBAAoB,EAAE;KACpD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAIrC;IACC,MAAM,UAAU,GAAG,kBAAkB,CAAC,MAAM,CAAC,SAAS,IAAI,kBAAkB,CAAC,CAAC;IAC9E,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC;IAClE,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;QAC7B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC;IAC5D,CAAC;IACD,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IACtD,MAAM,CAAC,UAAU,EAAE,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACpD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAA4C;IACtE,EAAE,EAAE,UAAU;IACd,IAAI,EAAE;QACJ,EAAE,EAAE,UAAU;QACd,KAAK,EAAE,iBAAiB;QACxB,cAAc,EAAE,mBAAmB;QACnC,QAAQ,EAAE,qBAAqB;QAC/B,KAAK,EAAE,oCAAoC;QAC3C,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;QAC3B,KAAK,EAAE,GAAG;KACX;IACD,YAAY,EAAE;QACZ,SAAS,EAAE,CAAC,QAAQ,CAAC;QACrB,cAAc,EAAE,IAAI;KACrB;IACD,MAAM,EAAE,EAAE,cAAc,EAAE,CAAC,oBAAoB,CAAC,EAAE;IAClD,YAAY,EAAE,qBAAqB;IACnC,MAAM,EAAE;QACN,cAAc,EAAE,CAAC,GAAmB,EAAE,EAAE,CAAC,uBAAuB,CAAC,GAAG,CAAC;QACrE,cAAc,EAAE,CAAC,GAAmB,EAAE,SAAyB,EAAE,EAAE,CACjE,uBAAuB,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;QAC7C,gBAAgB,EAAE,CAAC,GAAmB,EAAE,EAAE,CAAC,gCAAgC,CAAC,GAAG,CAAC;QAChF,YAAY,EAAE,CAAC,OAAiC,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU;QACvE,SAAS,EAAE,CAAC,OAAiC,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO;QACjE,eAAe,EAAE,CAAC,OAAiC,EAAE,EAAE,CAAC,CAAC;YACvD,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,UAAU,EAAE,OAAO,CAAC,UAAU;SAC/B,CAAC;KACH;IACD,OAAO,EAAE;QACP,YAAY,EAAE,KAAK,EAAE,GAAoD,EAAE,EAAE;YAC3E,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;YAC5B,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBACrB,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,OAAO,CAAC,SAAS,sBAAsB,CAAC,CAAC;gBAC3D,GAAG,CAAC,SAAS,EAAE,CAAC;oBACd,SAAS,EAAE,OAAO,CAAC,SAAS;oBAC5B,OAAO,EAAE,KAAK;oBACd,SAAS,EAAE,KAAK;oBAChB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;iBACvB,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,IAAI,MAAyC,CAAC;YAC9C,IAAI,CAAC;gBACH,MAAM,GAAG,cAAc,CAAC;oBACtB,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM;oBAC7B,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU;oBACrC,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW;oBACvC,iBAAiB,EAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB;oBACnD,oBAAoB,EAAE,OAAO,CAAC,MAAM,CAAC,oBAAoB;iBAC1D,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACjE,GAAG,CAAC,SAAS,EAAE,CAAC;oBACd,SAAS,EAAE,OAAO,CAAC,SAAS;oBAC5B,OAAO,EAAE,KAAK;oBACd,SAAS,EAAE,KAAK;oBAChB,SAAS,EAAE,OAAO;oBAClB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;iBACvB,CAAC,CAAC;gBACH,MAAM,GAAG,CAAC;YACZ,CAAC;YAED,MAAM,MAAM,GACV,GAAG,CAAC,GAAG;gBACN;oBACC,IAAI,EAAE,OAAO,CAAC,GAAG;oBACjB,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,KAAK,EAAE,OAAO,CAAC,KAAK;iBACX,CAAC;YACd,MAAM,UAAU,GAAG,gBAAgB,CAAC;gBAClC,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,SAAS,EAAE,GAAG,CAAC,SAAS;gBACxB,SAAS,EAAE,GAAG,CAAC,SAAS;aACzB,CAAC,CAAC;YAEH,MAAM,EAAE,GAAG,IAAI,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAClD,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;YAErF,UAAU,CAAC;gBACT,OAAO,EAAE,IAAI;gBACb,SAAS,EAAE,EAAE,CAAC,WAAW,EAAE;gBAC3B,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;gBACvB,SAAS,EAAE,IAAI;gBACf,iBAAiB,EAAE,EAAE,CAAC,oBAAoB,EAAE;aAC7C,CAAC,CAAC;YAEH,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;gBACtB,UAAU,CAAC;oBACT,SAAS,EAAE,IAAI;oBACf,eAAe,EAAE,IAAI,CAAC,GAAG,EAAE;oBAC3B,cAAc,EAAE,IAAI;oBACpB,iBAAiB,EAAE,EAAE,CAAC,oBAAoB,EAAE;oBAC5C,SAAS,EAAE,IAAI;iBAChB,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,MAAM,EAAE,EAAE;gBAC/B,UAAU,CAAC;oBACT,SAAS,EAAE,KAAK;oBAChB,cAAc,EAAE;wBACd,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;wBACd,KAAK,EAAE,MAAM;qBACd;oBACD,iBAAiB,EAAE,EAAE,CAAC,oBAAoB,EAAE;iBAC7C,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBACvB,UAAU,CAAC;oBACT,SAAS,EAAE,KAAK,CAAC,OAAO;oBACxB,iBAAiB,EAAE,EAAE,CAAC,oBAAoB,EAAE;iBAC7C,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;gBAC3C,UAAU,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBAC1C,aAAa,CAAC;oBACZ,GAAG,EAAE,GAAG,CAAC,GAAG;oBACZ,SAAS,EAAE,OAAO,CAAC,SAAS;oBAC5B,SAAS;oBACT,IAAI;oBACJ,MAAM;oBACN,EAAE;oBACF,UAAU;oBACV,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;iBAC7C,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;oBACf,MAAM,CAAC,KAAK,CAAC,yCAAyC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACvE,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;gBACpC,MAAM,CAAC,IAAI,CAAC,iCAAiC,MAAM,KAAK,MAAM,EAAE,CAAC,CAAC;YACpE,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,EAAE;gBACnD,MAAM,CAAC,IAAI,CACT,2BAA2B,MAAM,KAAK,eAAe,UAAU,MAAM,GAAG,CACzE,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,MAAM,IAAI,GAAG,GAAG,EAAE;gBAChB,EAAE,CAAC,UAAU,EAAE,CAAC;gBAChB,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;gBACtC,UAAU,CAAC;oBACT,OAAO,EAAE,KAAK;oBACd,SAAS,EAAE,KAAK;oBAChB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;iBACvB,CAAC,CAAC;YACL,CAAC,CAAC;YAEF,GAAG,CAAC,WAAW,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAEhE,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;gBACvB,MAAM,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;gBAChE,EAAE,CAAC,OAAO,EAAE,CAAC;YACf,CAAC;QACH,CAAC;QACD,WAAW,EAAE,KAAK,EAAE,GAAoD,EAAE,EAAE;YAC1E,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAC5C,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC;gBACvB,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACvC,CAAC;YACD,GAAG,CAAC,SAAS,EAAE,CAAC;gBACd,SAAS,EAAE,GAAG,CAAC,SAAS;gBACxB,OAAO,EAAE,KAAK;gBACd,SAAS,EAAE,KAAK;gBAChB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;aACvB,CAAC,CAAC;QACL,CAAC;KACF;IACD,MAAM,EAAE;QACN,cAAc,EAAE;YACd,SAAS,EAAE,kBAAkB;YAC7B,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,KAAK;YAChB,WAAW,EAAE,IAAI;YACjB,UAAU,EAAE,IAAI;YAChB,SAAS,EAAE,IAAI;SAChB;QACD,oBAAoB,EAAE,CAAC,EACrB,OAAO,EACP,OAAO,GAIR,EAAE,EAAE,CAAC,CAAC;YACL,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,KAAK;YAClC,SAAS,EAAE,OAAO,EAAE,SAAS,IAAI,KAAK;YACtC,iBAAiB,EAAE,OAAO,EAAE,iBAAiB,IAAI,CAAC;YAClD,eAAe,EAAE,OAAO,EAAE,eAAe,IAAI,IAAI;YACjD,cAAc,EAAE,OAAO,EAAE,cAAc,IAAI,IAAI;YAC/C,SAAS,EAAE,OAAO,EAAE,SAAS,IAAI,IAAI;YACrC,WAAW,EAAE,OAAO,EAAE,WAAW,IAAI,IAAI;YACzC,UAAU,EAAE,OAAO,EAAE,UAAU,IAAI,IAAI;YACvC,aAAa,EAAE,OAAO,EAAE,aAAa,IAAI,IAAI;YAC7C,cAAc,EAAE,OAAO,EAAE,cAAc,IAAI,IAAI;SAChD,CAAC;KACH;CACF,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Configuration handling for CrabCallr plugin
3
+ */
4
+ import type { CrabCallrConfig } from './types.js';
5
+ /**
6
+ * Default configuration values
7
+ */
8
+ export declare const DEFAULT_CONFIG: Omit<CrabCallrConfig, 'apiKey'>;
9
+ /**
10
+ * Validates and normalizes plugin configuration
11
+ */
12
+ export declare function validateConfig(config: Partial<CrabCallrConfig>): CrabCallrConfig;
13
+ /**
14
+ * Masks an API key for logging (shows first 3 and last 4 chars)
15
+ */
16
+ export declare function maskApiKey(apiKey: string): string;
17
+ //# sourceMappingURL=config.d.ts.map