@cored-im/openclaw-plugin 0.1.4 → 0.1.5

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.js CHANGED
@@ -1,3 +1,12 @@
1
+ // src/index.ts
2
+ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
3
+
4
+ // src/channel.ts
5
+ import {
6
+ createChatChannelPlugin,
7
+ createChannelPluginBase
8
+ } from "openclaw/plugin-sdk/core";
9
+
1
10
  // src/config.ts
2
11
  var DEFAULTS = {
3
12
  enableEncryption: true,
@@ -306,23 +315,79 @@ function parseTarget(to) {
306
315
  }
307
316
 
308
317
  // src/channel.ts
309
- var coredPlugin = {
310
- id: "cored",
318
+ function resolveAccount(cfg, accountId) {
319
+ const section = cfg.channels?.["cored"];
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
311
373
  meta: {
312
374
  id: "cored",
313
375
  label: "Cored",
314
376
  selectionLabel: "Cored",
315
377
  docsPath: "/channels/cored",
316
- blurb: "Cored enterprise IM channel",
378
+ blurb: "Connect OpenClaw to Cored",
317
379
  aliases: ["cored", "co"]
318
380
  },
381
+ // Capabilities
319
382
  capabilities: {
320
383
  chatTypes: ["direct", "group"]
321
384
  },
385
+ // Config
322
386
  config: {
323
387
  listAccountIds: (cfg) => listAccountIds(cfg),
324
388
  resolveAccount: (cfg, accountId) => resolveAccountConfig(cfg, accountId)
325
389
  },
390
+ // Outbound messaging
326
391
  outbound: {
327
392
  deliveryMode: "direct",
328
393
  resolveTarget: ({ to }) => {
@@ -351,8 +416,70 @@ var coredPlugin = {
351
416
  }
352
417
  return sendText(target.id, text, accountId);
353
418
  }
419
+ },
420
+ // Setup wizard for openclaw onboard
421
+ setupWizard: {
422
+ channel: "cored",
423
+ status: {
424
+ configuredLabel: "Connected",
425
+ unconfiguredLabel: "Not configured",
426
+ resolveConfigured: ({ cfg }) => {
427
+ const section = cfg.channels?.["cored"];
428
+ return Boolean(section?.appId && section?.appSecret && section?.backendUrl);
429
+ }
430
+ },
431
+ credentials: [
432
+ {
433
+ inputKey: "appId",
434
+ providerHint: "cored",
435
+ credentialLabel: "App ID",
436
+ preferredEnvVar: "CORED_APP_ID",
437
+ envPrompt: "Use CORED_APP_ID from environment?",
438
+ keepPrompt: "Keep current App ID?",
439
+ inputPrompt: "Enter your Cored App ID:",
440
+ inspect: ({ cfg }) => {
441
+ const section = cfg.channels?.["cored"];
442
+ return {
443
+ accountConfigured: Boolean(section?.appId),
444
+ hasConfiguredValue: Boolean(section?.appId)
445
+ };
446
+ }
447
+ },
448
+ {
449
+ inputKey: "appSecret",
450
+ providerHint: "cored",
451
+ credentialLabel: "App Secret",
452
+ preferredEnvVar: "CORED_APP_SECRET",
453
+ envPrompt: "Use CORED_APP_SECRET from environment?",
454
+ keepPrompt: "Keep current App Secret?",
455
+ inputPrompt: "Enter your Cored App Secret:",
456
+ inspect: ({ cfg }) => {
457
+ const section = cfg.channels?.["cored"];
458
+ return {
459
+ accountConfigured: Boolean(section?.appSecret),
460
+ hasConfiguredValue: Boolean(section?.appSecret)
461
+ };
462
+ }
463
+ },
464
+ {
465
+ inputKey: "backendUrl",
466
+ providerHint: "cored",
467
+ credentialLabel: "Backend URL",
468
+ preferredEnvVar: "CORED_BACKEND_URL",
469
+ envPrompt: "Use CORED_BACKEND_URL from environment?",
470
+ keepPrompt: "Keep current Backend URL?",
471
+ inputPrompt: "Enter your Cored backend server URL:",
472
+ inspect: ({ cfg }) => {
473
+ const section = cfg.channels?.["cored"];
474
+ return {
475
+ accountConfigured: Boolean(section?.backendUrl),
476
+ hasConfiguredValue: Boolean(section?.backendUrl)
477
+ };
478
+ }
479
+ }
480
+ ]
354
481
  }
355
- };
482
+ });
356
483
 
357
484
  // src/messaging/inbound.ts
358
485
  function parseMessageEvent(event) {
@@ -471,33 +598,47 @@ function buildContext(msg, account) {
471
598
  }
472
599
  async function processInboundMessage(api, account, event, opts) {
473
600
  const logger = api.logger;
601
+ const log = {
602
+ debug: (msg) => {
603
+ logger?.debug?.(msg);
604
+ },
605
+ info: (msg) => {
606
+ logger?.info?.(msg);
607
+ },
608
+ warn: (msg) => {
609
+ logger?.warn?.(msg);
610
+ },
611
+ error: (msg) => {
612
+ logger?.error?.(msg);
613
+ }
614
+ };
474
615
  const parsed = parseMessageEvent(event);
475
616
  if (!parsed) {
476
- logger?.debug(
617
+ log.debug(
477
618
  `[cored] ignoring unparseable event (messageId=${event?.message?.messageId ?? "unknown"} messageType=${event?.message?.messageType ?? "undefined"})`
478
619
  );
479
620
  return false;
480
621
  }
481
622
  const gate = checkMessageGate(parsed, account);
482
623
  if (!gate.pass) {
483
- logger?.debug(
624
+ log.debug(
484
625
  `[cored] gated message=${parsed.messageId} reason=${gate.reason} chat=${parsed.chatId}`
485
626
  );
486
627
  return false;
487
628
  }
488
629
  if (isDuplicate(parsed.messageId)) {
489
- logger?.debug(
630
+ log.debug(
490
631
  `[cored] duplicate message=${parsed.messageId} chat=${parsed.chatId}`
491
632
  );
492
633
  return false;
493
634
  }
494
635
  const ctx = buildContext(parsed, account);
495
- logger?.info(
636
+ log.info(
496
637
  `[cored] dispatching message=${parsed.messageId} chat=${parsed.chatId} sender=${parsed.senderId} type=${parsed.chatType}`
497
638
  );
498
639
  const runtime = api.runtime;
499
640
  if (!runtime?.channel?.reply?.dispatchReplyWithBufferedBlockDispatcher) {
500
- logger?.warn("[cored] runtime.channel.reply not available \u2014 cannot dispatch");
641
+ log.warn("[cored] runtime.channel.reply not available \u2014 cannot dispatch");
501
642
  return false;
502
643
  }
503
644
  const cfgSession = api.config?.session;
@@ -516,7 +657,7 @@ async function processInboundMessage(api, account, event, opts) {
516
657
  accountId: account.accountId
517
658
  } : void 0
518
659
  });
519
- logger?.debug(
660
+ log.debug(
520
661
  `[cored] dispatch starting for message=${parsed.messageId} session=${ctx.SessionKey}`
521
662
  );
522
663
  await runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
@@ -524,77 +665,83 @@ async function processInboundMessage(api, account, event, opts) {
524
665
  cfg: api.config,
525
666
  dispatcherOptions: {
526
667
  deliver: async (payload) => {
527
- logger?.info(
668
+ log.info(
528
669
  `[cored] deliver callback called for message=${parsed.messageId} hasText=${!!payload.text} textLen=${payload.text?.length ?? 0}`
529
670
  );
530
671
  if (payload.text) {
531
672
  await opts.deliver(parsed.chatId, payload.text);
532
- logger?.info(
673
+ log.info(
533
674
  `[cored] deliver completed for message=${parsed.messageId} chat=${parsed.chatId}`
534
675
  );
535
676
  }
536
677
  },
537
678
  onError: (err, info) => {
538
- logger?.error(
679
+ log.error(
539
680
  `[cored] ${info?.kind ?? "reply"} error for message=${parsed.messageId}: ${err}`
540
681
  );
541
682
  }
542
683
  }
543
684
  });
544
- logger?.info(
685
+ log.info(
545
686
  `[cored] dispatch finished for message=${parsed.messageId}`
546
687
  );
547
688
  return true;
548
689
  }
549
690
 
550
691
  // src/index.ts
551
- function register(api) {
552
- api.registerChannel({ plugin: coredPlugin });
553
- api.registerService({
554
- id: "cored-sdk",
555
- start: async () => {
556
- if (clientCount() > 0) return;
557
- const accounts = listEnabledAccountConfigs(api.config);
558
- if (accounts.length === 0) {
559
- api.logger?.warn("[cored] no enabled account config found \u2014 service idle");
560
- return;
561
- }
562
- for (const account of accounts) {
563
- const errors = validateAccountConfig(account);
564
- if (errors.length > 0) {
565
- api.logger?.warn(
566
- `[cored] skipping account=${account.accountId}: ${errors.map((e) => e.message).join("; ")}`
567
- );
568
- continue;
692
+ var index_default = defineChannelPluginEntry({
693
+ id: "cored",
694
+ name: "Cored",
695
+ description: "Connect OpenClaw with Cored",
696
+ plugin: coredPlugin,
697
+ registerFull(api) {
698
+ const typedApi = api;
699
+ typedApi.registerService({
700
+ id: "cored-sdk",
701
+ start: async () => {
702
+ if (clientCount() > 0) return;
703
+ const accounts = listEnabledAccountConfigs(typedApi.config);
704
+ if (accounts.length === 0) {
705
+ typedApi.logger?.warn?.("[cored] no enabled account config found \u2014 service idle");
706
+ return;
569
707
  }
570
- try {
571
- await startAccount(api, account);
572
- api.logger?.info(
573
- `[cored] account=${account.accountId} connected (appId=${account.appId})`
574
- );
575
- } catch (err) {
576
- api.logger?.error(
577
- `[cored] account=${account.accountId} failed to start: ${err instanceof Error ? err.message : String(err)}`
578
- );
708
+ for (const account of accounts) {
709
+ const errors = validateAccountConfig(account);
710
+ if (errors.length > 0) {
711
+ typedApi.logger?.warn?.(
712
+ `[cored] skipping account=${account.accountId}: ${errors.map((e) => e.message).join("; ")}`
713
+ );
714
+ continue;
715
+ }
716
+ try {
717
+ await startAccount(typedApi, account);
718
+ typedApi.logger?.info?.(
719
+ `[cored] account=${account.accountId} connected (appId=${account.appId})`
720
+ );
721
+ } catch (err) {
722
+ typedApi.logger?.error?.(
723
+ `[cored] account=${account.accountId} failed to start: ${err instanceof Error ? err.message : String(err)}`
724
+ );
725
+ }
579
726
  }
727
+ typedApi.logger?.info?.(`[cored] service started with ${clientCount()} account(s)`);
728
+ },
729
+ stop: async () => {
730
+ await destroyAllClients();
731
+ typedApi.logger?.info?.("[cored] service stopped \u2014 all clients disconnected");
580
732
  }
581
- api.logger?.info(`[cored] service started with ${clientCount()} account(s)`);
582
- },
583
- stop: async () => {
584
- await destroyAllClients();
585
- api.logger?.info("[cored] service stopped \u2014 all clients disconnected");
586
- }
587
- });
588
- api.logger?.info("[cored] plugin registered");
589
- }
733
+ });
734
+ typedApi.logger?.info?.("[cored] plugin registered");
735
+ }
736
+ });
590
737
  async function startAccount(api, account) {
591
- const deliver = makeDeliver(account.accountId, (msg) => api.logger?.warn(msg));
738
+ const deliver = makeDeliver(account.accountId, (msg) => api.logger?.warn?.(msg));
592
739
  await createClient({
593
740
  config: account,
594
- log: (msg) => api.logger?.debug(msg),
741
+ log: (msg) => api.logger?.debug?.(msg),
595
742
  onMessage: (event, accountConfig) => {
596
743
  handleInbound(api, accountConfig, event, deliver).catch((err) => {
597
- api.logger?.error(
744
+ api.logger?.error?.(
598
745
  `[cored] unhandled inbound error for account=${accountConfig.accountId}: ${err}`
599
746
  );
600
747
  });
@@ -622,6 +769,6 @@ async function handleInbound(api, account, event, deliver) {
622
769
  }
623
770
  }
624
771
  export {
625
- register as default
772
+ index_default as default
626
773
  };
627
774
  //# sourceMappingURL=index.js.map