@cored-im/openclaw-plugin 0.1.7 → 0.1.10
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/dist/index.cjs +120 -115
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -9
- package/dist/index.d.ts +11 -9
- package/dist/index.js +120 -115
- package/dist/index.js.map +1 -1
- package/dist/setup-entry.cjs +110 -104
- package/dist/setup-entry.cjs.map +1 -1
- package/dist/setup-entry.d.cts +4 -9
- package/dist/setup-entry.d.ts +4 -9
- package/dist/setup-entry.js +110 -104
- package/dist/setup-entry.js.map +1 -1
- package/dist/types-C6n4PnbR.d.cts +14 -0
- package/dist/types-C6n4PnbR.d.ts +14 -0
- package/openclaw.plugin.json +2 -51
- package/package.json +3 -2
- package/src/channel.ts +129 -134
- package/src/index.ts +15 -21
- package/src/messaging/inbound.test.ts +2 -2
- package/src/messaging/inbound.ts +11 -8
- package/src/types.ts +0 -4
- package/src/typings/openclaw-plugin-sdk.d.ts +0 -162
package/dist/index.js
CHANGED
|
@@ -315,171 +315,177 @@ function parseTarget(to) {
|
|
|
315
315
|
}
|
|
316
316
|
|
|
317
317
|
// src/channel.ts
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
const accounts = section?.accounts;
|
|
321
|
-
const defaultAccount = section?.defaultAccount;
|
|
322
|
-
if (accounts && Object.keys(accounts).length > 0) {
|
|
323
|
-
const targetId = accountId ?? defaultAccount ?? Object.keys(accounts)[0];
|
|
324
|
-
const account = accounts[targetId];
|
|
325
|
-
if (!account) {
|
|
326
|
-
throw new Error(`cored: account "${targetId}" not found`);
|
|
327
|
-
}
|
|
328
|
-
return {
|
|
329
|
-
accountId: targetId,
|
|
330
|
-
appId: account.appId,
|
|
331
|
-
appSecret: account.appSecret,
|
|
332
|
-
backendUrl: account.backendUrl,
|
|
333
|
-
enableEncryption: account.enableEncryption ?? section.enableEncryption ?? true,
|
|
334
|
-
requestTimeout: account.requestTimeout ?? section.requestTimeout ?? 3e4,
|
|
335
|
-
requireMention: account.requireMention ?? section.requireMention ?? true
|
|
336
|
-
};
|
|
337
|
-
}
|
|
338
|
-
const appId = section?.appId;
|
|
339
|
-
const appSecret = section?.appSecret;
|
|
340
|
-
const backendUrl = section?.backendUrl;
|
|
341
|
-
if (!appId || !appSecret || !backendUrl) {
|
|
342
|
-
throw new Error("cored: appId, appSecret, and backendUrl are required");
|
|
343
|
-
}
|
|
344
|
-
return {
|
|
345
|
-
accountId: null,
|
|
346
|
-
appId,
|
|
347
|
-
appSecret,
|
|
348
|
-
backendUrl,
|
|
349
|
-
enableEncryption: section?.enableEncryption ?? true,
|
|
350
|
-
requestTimeout: section?.requestTimeout ?? 3e4,
|
|
351
|
-
requireMention: section?.requireMention ?? true
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
|
-
var coredPlugin = createChatChannelPlugin({
|
|
355
|
-
base: createChannelPluginBase({
|
|
356
|
-
id: "cored",
|
|
357
|
-
setup: {
|
|
358
|
-
resolveAccount,
|
|
359
|
-
inspectAccount(cfg, accountId) {
|
|
360
|
-
const section = cfg.channels?.["cored"];
|
|
361
|
-
const hasConfig = Boolean(
|
|
362
|
-
section?.appId && section?.appSecret && section?.backendUrl
|
|
363
|
-
);
|
|
364
|
-
return {
|
|
365
|
-
enabled: Boolean(section?.enabled !== false),
|
|
366
|
-
configured: hasConfig,
|
|
367
|
-
tokenStatus: hasConfig ? "available" : "missing"
|
|
368
|
-
};
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
}),
|
|
372
|
-
// Plugin metadata
|
|
318
|
+
var base = createChannelPluginBase({
|
|
319
|
+
id: "cored",
|
|
373
320
|
meta: {
|
|
374
321
|
id: "cored",
|
|
375
322
|
label: "Cored",
|
|
376
323
|
selectionLabel: "Cored",
|
|
377
324
|
docsPath: "/channels/cored",
|
|
378
325
|
blurb: "Connect OpenClaw to Cored",
|
|
379
|
-
aliases: ["
|
|
326
|
+
aliases: ["co"]
|
|
380
327
|
},
|
|
381
|
-
// Capabilities
|
|
382
328
|
capabilities: {
|
|
383
329
|
chatTypes: ["direct", "group"]
|
|
384
330
|
},
|
|
385
|
-
// Config
|
|
386
331
|
config: {
|
|
387
332
|
listAccountIds: (cfg) => listAccountIds(cfg),
|
|
388
|
-
resolveAccount: (cfg, accountId) => resolveAccountConfig(cfg, accountId)
|
|
333
|
+
resolveAccount: (cfg, accountId) => resolveAccountConfig(cfg, accountId ?? void 0),
|
|
334
|
+
inspectAccount(cfg, accountId) {
|
|
335
|
+
const resolved = resolveAccountConfig(cfg, accountId ?? void 0);
|
|
336
|
+
const hasConfig = Boolean(
|
|
337
|
+
resolved.appId && resolved.appSecret && resolved.backendUrl
|
|
338
|
+
);
|
|
339
|
+
return {
|
|
340
|
+
enabled: resolved.enabled,
|
|
341
|
+
configured: hasConfig,
|
|
342
|
+
tokenStatus: hasConfig ? "available" : "missing"
|
|
343
|
+
};
|
|
344
|
+
}
|
|
389
345
|
},
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
const
|
|
395
|
-
if (!
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
};
|
|
346
|
+
setup: {
|
|
347
|
+
applyAccountConfig: ({ cfg, accountId, input }) => {
|
|
348
|
+
const updated = structuredClone(cfg);
|
|
349
|
+
if (!updated.channels) updated.channels = {};
|
|
350
|
+
const ch = updated.channels;
|
|
351
|
+
if (!ch["cored"]) ch["cored"] = {};
|
|
352
|
+
const section = ch["cored"];
|
|
353
|
+
const appId = input.appToken;
|
|
354
|
+
const appSecret = input.token;
|
|
355
|
+
const backendUrl = input.url;
|
|
356
|
+
if (accountId && accountId !== "default") {
|
|
357
|
+
if (!section.accounts) section.accounts = {};
|
|
358
|
+
const accounts = section.accounts;
|
|
359
|
+
if (!accounts[accountId]) accounts[accountId] = {};
|
|
360
|
+
const account = accounts[accountId];
|
|
361
|
+
if (appId) account.appId = appId;
|
|
362
|
+
if (appSecret) account.appSecret = appSecret;
|
|
363
|
+
if (backendUrl) account.backendUrl = backendUrl;
|
|
364
|
+
} else {
|
|
365
|
+
if (appId) section.appId = appId;
|
|
366
|
+
if (appSecret) section.appSecret = appSecret;
|
|
367
|
+
if (backendUrl) section.backendUrl = backendUrl;
|
|
402
368
|
}
|
|
403
|
-
return
|
|
404
|
-
},
|
|
405
|
-
sendText: async ({
|
|
406
|
-
to,
|
|
407
|
-
text,
|
|
408
|
-
accountId
|
|
409
|
-
}) => {
|
|
410
|
-
const target = parseTarget(to);
|
|
411
|
-
if (!target) {
|
|
412
|
-
return {
|
|
413
|
-
ok: false,
|
|
414
|
-
error: new Error(`[cored] invalid send target: ${to}`)
|
|
415
|
-
};
|
|
416
|
-
}
|
|
417
|
-
return sendText(target.id, text, accountId);
|
|
369
|
+
return updated;
|
|
418
370
|
}
|
|
419
371
|
},
|
|
420
|
-
// Setup wizard for openclaw onboard
|
|
421
372
|
setupWizard: {
|
|
422
373
|
channel: "cored",
|
|
423
374
|
status: {
|
|
424
375
|
configuredLabel: "Connected",
|
|
425
376
|
unconfiguredLabel: "Not configured",
|
|
426
377
|
resolveConfigured: ({ cfg }) => {
|
|
427
|
-
const
|
|
428
|
-
return
|
|
378
|
+
const ids = listAccountIds(cfg);
|
|
379
|
+
return ids.some((id) => {
|
|
380
|
+
const resolved = resolveAccountConfig(cfg, id);
|
|
381
|
+
return Boolean(resolved.appId && resolved.appSecret && resolved.backendUrl);
|
|
382
|
+
});
|
|
429
383
|
}
|
|
430
384
|
},
|
|
431
385
|
credentials: [
|
|
432
386
|
{
|
|
433
|
-
inputKey: "
|
|
387
|
+
inputKey: "appToken",
|
|
434
388
|
providerHint: "cored",
|
|
435
389
|
credentialLabel: "App ID",
|
|
436
390
|
preferredEnvVar: "CORED_APP_ID",
|
|
437
391
|
envPrompt: "Use CORED_APP_ID from environment?",
|
|
438
392
|
keepPrompt: "Keep current App ID?",
|
|
439
393
|
inputPrompt: "Enter your Cored App ID:",
|
|
440
|
-
inspect: ({ cfg }) => {
|
|
441
|
-
const
|
|
394
|
+
inspect: ({ cfg, accountId }) => {
|
|
395
|
+
const resolved = resolveAccountConfig(cfg, accountId ?? void 0);
|
|
442
396
|
return {
|
|
443
|
-
accountConfigured: Boolean(
|
|
444
|
-
hasConfiguredValue: Boolean(
|
|
397
|
+
accountConfigured: Boolean(resolved.appId),
|
|
398
|
+
hasConfiguredValue: Boolean(resolved.appId)
|
|
445
399
|
};
|
|
446
400
|
}
|
|
447
401
|
},
|
|
448
402
|
{
|
|
449
|
-
inputKey: "
|
|
403
|
+
inputKey: "token",
|
|
450
404
|
providerHint: "cored",
|
|
451
405
|
credentialLabel: "App Secret",
|
|
452
406
|
preferredEnvVar: "CORED_APP_SECRET",
|
|
453
407
|
envPrompt: "Use CORED_APP_SECRET from environment?",
|
|
454
408
|
keepPrompt: "Keep current App Secret?",
|
|
455
409
|
inputPrompt: "Enter your Cored App Secret:",
|
|
456
|
-
inspect: ({ cfg }) => {
|
|
457
|
-
const
|
|
410
|
+
inspect: ({ cfg, accountId }) => {
|
|
411
|
+
const resolved = resolveAccountConfig(cfg, accountId ?? void 0);
|
|
458
412
|
return {
|
|
459
|
-
accountConfigured: Boolean(
|
|
460
|
-
hasConfiguredValue: Boolean(
|
|
413
|
+
accountConfigured: Boolean(resolved.appSecret),
|
|
414
|
+
hasConfiguredValue: Boolean(resolved.appSecret)
|
|
461
415
|
};
|
|
462
416
|
}
|
|
463
417
|
},
|
|
464
418
|
{
|
|
465
|
-
inputKey: "
|
|
419
|
+
inputKey: "url",
|
|
466
420
|
providerHint: "cored",
|
|
467
421
|
credentialLabel: "Backend URL",
|
|
468
422
|
preferredEnvVar: "CORED_BACKEND_URL",
|
|
469
423
|
envPrompt: "Use CORED_BACKEND_URL from environment?",
|
|
470
424
|
keepPrompt: "Keep current Backend URL?",
|
|
471
425
|
inputPrompt: "Enter your Cored backend server URL:",
|
|
472
|
-
inspect: ({ cfg }) => {
|
|
473
|
-
const
|
|
426
|
+
inspect: ({ cfg, accountId }) => {
|
|
427
|
+
const resolved = resolveAccountConfig(cfg, accountId ?? void 0);
|
|
474
428
|
return {
|
|
475
|
-
accountConfigured: Boolean(
|
|
476
|
-
hasConfiguredValue: Boolean(
|
|
429
|
+
accountConfigured: Boolean(resolved.backendUrl),
|
|
430
|
+
hasConfiguredValue: Boolean(resolved.backendUrl)
|
|
477
431
|
};
|
|
478
432
|
}
|
|
479
433
|
}
|
|
480
434
|
]
|
|
481
435
|
}
|
|
482
436
|
});
|
|
437
|
+
var coredPlugin = createChatChannelPlugin({
|
|
438
|
+
base,
|
|
439
|
+
// DM security: who can message the bot
|
|
440
|
+
security: {
|
|
441
|
+
dm: {
|
|
442
|
+
channelKey: "cored",
|
|
443
|
+
resolvePolicy: () => void 0,
|
|
444
|
+
resolveAllowFrom: () => [],
|
|
445
|
+
defaultPolicy: "allowlist"
|
|
446
|
+
}
|
|
447
|
+
},
|
|
448
|
+
// Threading: how replies are delivered
|
|
449
|
+
threading: { topLevelReplyToMode: "reply" },
|
|
450
|
+
// Outbound: send messages to the platform
|
|
451
|
+
outbound: {
|
|
452
|
+
attachedResults: {
|
|
453
|
+
channel: "cored",
|
|
454
|
+
sendText: async (ctx) => {
|
|
455
|
+
const target = parseTarget(ctx.to);
|
|
456
|
+
if (!target) {
|
|
457
|
+
throw new Error(`[cored] invalid send target: ${ctx.to}`);
|
|
458
|
+
}
|
|
459
|
+
const result = await sendText(
|
|
460
|
+
target.id,
|
|
461
|
+
ctx.text,
|
|
462
|
+
ctx.accountId ?? void 0,
|
|
463
|
+
ctx.replyToId ?? void 0
|
|
464
|
+
);
|
|
465
|
+
if (!result.ok) {
|
|
466
|
+
throw result.error ?? new Error("[cored] send failed");
|
|
467
|
+
}
|
|
468
|
+
return { messageId: result.messageId ?? "" };
|
|
469
|
+
}
|
|
470
|
+
},
|
|
471
|
+
base: {
|
|
472
|
+
deliveryMode: "direct",
|
|
473
|
+
resolveTarget: ({ to }) => {
|
|
474
|
+
if (!to) return { ok: false, error: new Error("[cored] --to is required") };
|
|
475
|
+
const target = parseTarget(to);
|
|
476
|
+
if (!target) {
|
|
477
|
+
return {
|
|
478
|
+
ok: false,
|
|
479
|
+
error: new Error(
|
|
480
|
+
`Cored requires --to <user:ID|chat:ID>, got: ${JSON.stringify(to)}`
|
|
481
|
+
)
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
return { ok: true, to: `${target.kind}:${target.id}` };
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
});
|
|
483
489
|
|
|
484
490
|
// src/messaging/inbound.ts
|
|
485
491
|
function parseMessageEvent(event) {
|
|
@@ -695,43 +701,42 @@ var index_default = defineChannelPluginEntry({
|
|
|
695
701
|
description: "Connect OpenClaw with Cored",
|
|
696
702
|
plugin: coredPlugin,
|
|
697
703
|
registerFull(api) {
|
|
698
|
-
|
|
699
|
-
typedApi.registerService({
|
|
704
|
+
api.registerService({
|
|
700
705
|
id: "cored-sdk",
|
|
701
706
|
start: async () => {
|
|
702
707
|
if (clientCount() > 0) return;
|
|
703
|
-
const accounts = listEnabledAccountConfigs(
|
|
708
|
+
const accounts = listEnabledAccountConfigs(api.config);
|
|
704
709
|
if (accounts.length === 0) {
|
|
705
|
-
|
|
710
|
+
api.logger?.warn?.("[cored] no enabled account config found \u2014 service idle");
|
|
706
711
|
return;
|
|
707
712
|
}
|
|
708
713
|
for (const account of accounts) {
|
|
709
714
|
const errors = validateAccountConfig(account);
|
|
710
715
|
if (errors.length > 0) {
|
|
711
|
-
|
|
716
|
+
api.logger?.warn?.(
|
|
712
717
|
`[cored] skipping account=${account.accountId}: ${errors.map((e) => e.message).join("; ")}`
|
|
713
718
|
);
|
|
714
719
|
continue;
|
|
715
720
|
}
|
|
716
721
|
try {
|
|
717
|
-
await startAccount(
|
|
718
|
-
|
|
722
|
+
await startAccount(api, account);
|
|
723
|
+
api.logger?.info?.(
|
|
719
724
|
`[cored] account=${account.accountId} connected (appId=${account.appId})`
|
|
720
725
|
);
|
|
721
726
|
} catch (err) {
|
|
722
|
-
|
|
727
|
+
api.logger?.error?.(
|
|
723
728
|
`[cored] account=${account.accountId} failed to start: ${err instanceof Error ? err.message : String(err)}`
|
|
724
729
|
);
|
|
725
730
|
}
|
|
726
731
|
}
|
|
727
|
-
|
|
732
|
+
api.logger?.info?.(`[cored] service started with ${clientCount()} account(s)`);
|
|
728
733
|
},
|
|
729
734
|
stop: async () => {
|
|
730
735
|
await destroyAllClients();
|
|
731
|
-
|
|
736
|
+
api.logger?.info?.("[cored] service stopped \u2014 all clients disconnected");
|
|
732
737
|
}
|
|
733
738
|
});
|
|
734
|
-
|
|
739
|
+
api.logger?.info?.("[cored] plugin registered");
|
|
735
740
|
}
|
|
736
741
|
});
|
|
737
742
|
async function startAccount(api, account) {
|