@openclaw/line 2026.9.6 → 2026.9.7

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 (77) hide show
  1. package/assets/icon.png +0 -0
  2. package/dist/.setup/{accounts-BBEFMYbY.mjs → accounts-DOiM8-y3.mjs} +1 -4
  3. package/dist/.setup/api-4RgpQmHW.mjs +3 -0
  4. package/dist/.setup/{api-D_06cuHl.mjs → api-w4QdlCCB.mjs} +2 -2
  5. package/dist/.setup/{card-command-710u8FBH.mjs → card-command-DYf4gnmI.mjs} +25 -33
  6. package/dist/.setup/{channel-kc3VRglA.mjs → channel-DN6Za8Vm.mjs} +789 -26
  7. package/dist/.setup/channel.runtime-bd5vGeSo.mjs +4 -0
  8. package/dist/.setup/{monitor-morJPcPd.mjs → monitor-C01hAm3f.mjs} +262 -333
  9. package/dist/.setup/monitor.runtime-DwH2zK48.mjs +2 -0
  10. package/dist/.setup/outbound.runtime-D_Gs99Dm.mjs +3 -0
  11. package/dist/.setup/probe.runtime-Cj08-BZ1.mjs +2 -0
  12. package/dist/.setup/runtime-V7yh9OeC.mjs +8 -0
  13. package/dist/.setup/{send-BmsHY4WC.mjs → send-DOY1WTxv.mjs} +7 -26
  14. package/dist/.setup/{send-retry-DbfiHBPd.mjs → send-retry-DV6I0muq.mjs} +104 -208
  15. package/dist/.setup/{setup-surface-CcfKJKtr.mjs → setup-surface-CbfkmkIS.mjs} +15 -4
  16. package/dist/.setup/{markdown-to-line-CRfEHFs0.mjs → template-messages-CxCnYsWN.mjs} +168 -189
  17. package/dist/api.js +2 -2
  18. package/dist/channel-plugin-api.js +1 -1
  19. package/dist/contract-api.js +1 -1
  20. package/dist/index.js +1 -1
  21. package/dist/runtime-api.js +2 -260
  22. package/dist/setup-api.js +1 -1
  23. package/dist/setup-entry.js +1 -1
  24. package/node_modules/@line/bot-sdk/node_modules/@types/node/README.md +1 -1
  25. package/node_modules/@line/bot-sdk/node_modules/@types/node/child_process.d.ts +1 -1
  26. package/node_modules/@line/bot-sdk/node_modules/@types/node/package.json +2 -2
  27. package/node_modules/typebox/build/compile/code.mjs +1 -2
  28. package/node_modules/typebox/build/compile/validator.mjs +5 -1
  29. package/node_modules/typebox/build/format/iri.mjs +16 -9
  30. package/node_modules/typebox/build/guard/emit.mjs +2 -2
  31. package/node_modules/typebox/build/guard/guard.d.mts +7 -5
  32. package/node_modules/typebox/build/guard/guard.mjs +14 -9
  33. package/node_modules/typebox/build/guard/index.mjs +6 -0
  34. package/node_modules/typebox/build/guard/unicode/unicode.d.mts +6 -0
  35. package/node_modules/typebox/build/guard/unicode/unicode.mjs +35 -0
  36. package/node_modules/typebox/build/guard/{string.mjs → unicode/unicode_segment.mjs} +16 -19
  37. package/node_modules/typebox/build/schema/build.mjs +2 -3
  38. package/node_modules/typebox/build/schema/engine/_pathing.d.mts +1 -0
  39. package/node_modules/typebox/build/schema/engine/_pathing.mjs +11 -0
  40. package/node_modules/typebox/build/schema/engine/_refine.mjs +13 -5
  41. package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +2 -1
  42. package/node_modules/typebox/build/schema/engine/dependencies.mjs +2 -1
  43. package/node_modules/typebox/build/schema/engine/dependentSchemas.mjs +2 -1
  44. package/node_modules/typebox/build/schema/engine/dynamicRef.d.mts +1 -1
  45. package/node_modules/typebox/build/schema/engine/dynamicRef.mjs +2 -2
  46. package/node_modules/typebox/build/schema/engine/format.mjs +9 -2
  47. package/node_modules/typebox/build/schema/engine/patternProperties.mjs +3 -2
  48. package/node_modules/typebox/build/schema/engine/properties.mjs +3 -2
  49. package/node_modules/typebox/build/schema/engine/propertyNames.mjs +2 -1
  50. package/node_modules/typebox/build/schema/engine/recursiveRef.d.mts +1 -1
  51. package/node_modules/typebox/build/schema/engine/recursiveRef.mjs +2 -2
  52. package/node_modules/typebox/build/schema/engine/ref.d.mts +1 -1
  53. package/node_modules/typebox/build/schema/engine/ref.mjs +2 -2
  54. package/node_modules/typebox/build/schema/engine/schema.mjs +24 -24
  55. package/node_modules/typebox/build/schema/parse.mjs +3 -0
  56. package/node_modules/typebox/build/schema/pointer/pointer.d.mts +1 -6
  57. package/node_modules/typebox/build/schema/pointer/pointer.mjs +47 -64
  58. package/node_modules/typebox/build/system/settings/internal.d.mts +2 -0
  59. package/node_modules/typebox/build/system/settings/internal.mjs +20 -0
  60. package/node_modules/typebox/build/system/settings/settings.d.mts +11 -0
  61. package/node_modules/typebox/build/system/settings/settings.mjs +14 -0
  62. package/node_modules/typebox/build/type/extends/inference.d.mts +1 -1
  63. package/node_modules/typebox/build/type/extends/inference.mjs +15 -2
  64. package/node_modules/typebox/build/type/extends/tuple.d.mts +2 -1
  65. package/node_modules/typebox/build/type/extends/tuple.mjs +21 -1
  66. package/node_modules/typebox/build/value/parse/parse.mjs +10 -4
  67. package/node_modules/typebox/package.json +1 -1
  68. package/node_modules/typebox/readme.md +3 -1
  69. package/package.json +5 -5
  70. package/dist/.setup/account-helpers-BSUyZwLm.mjs +0 -12
  71. package/dist/.setup/api-RdEuQgW-.mjs +0 -3
  72. package/dist/.setup/channel.runtime-BtkeDELb.mjs +0 -4
  73. package/dist/.setup/monitor.runtime-BGhxYDKG.mjs +0 -2
  74. package/dist/.setup/outbound.runtime-QGvZy8Em.mjs +0 -3
  75. package/dist/.setup/probe.runtime-CMf8b-jB.mjs +0 -2
  76. package/dist/.setup/rich-messages-d8CmBVJj.mjs +0 -872
  77. /package/node_modules/typebox/build/guard/{string.d.mts → unicode/unicode_segment.d.mts} +0 -0
@@ -0,0 +1,2 @@
1
+ import { t as monitorLineProvider } from "./monitor-C01hAm3f.mjs";
2
+ export { monitorLineProvider };
@@ -0,0 +1,3 @@
1
+ import { c as pushLocationMessage, d as pushTemplateMessage, f as pushTextMessageWithQuickReplies, l as pushMessageLine, m as sendMessageLine, n as createLocationMessage, r as createQuickReplyItems, s as pushFlexMessage, t as createFlexMessage, u as pushMessagesLine } from "./send-DOY1WTxv.mjs";
2
+ import { n as processLineMessage, t as buildTemplateMessageFromPayload } from "./template-messages-CxCnYsWN.mjs";
3
+ export { buildTemplateMessageFromPayload, createFlexMessage, createLocationMessage, createQuickReplyItems, processLineMessage, pushFlexMessage, pushLocationMessage, pushMessageLine, pushMessagesLine, pushTemplateMessage, pushTextMessageWithQuickReplies, sendMessageLine };
@@ -0,0 +1,2 @@
1
+ import { a as probeLineBot } from "./send-retry-DV6I0muq.mjs";
2
+ export { probeLineBot };
@@ -0,0 +1,8 @@
1
+ import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
2
+ //#region extensions/line/src/runtime.ts
3
+ const { setRuntime: setLineRuntime, getRuntime: getLineRuntime } = createPluginRuntimeStore({
4
+ pluginId: "line",
5
+ errorMessage: "LINE runtime not initialized - plugin not registered"
6
+ });
7
+ //#endregion
8
+ export { setLineRuntime as n, getLineRuntime as t };
@@ -1,5 +1,5 @@
1
- import { i as resolveLineAccount } from "./accounts-BBEFMYbY.mjs";
2
- import { A as withoutLineQuoteTokens, g as messageAction, i as runLinePushWithRetries, j as buildLineMediaMessage, n as findLineHttpError, o as resolveLineChannelAccessToken, s as createLineSendReceipt, v as normalizeLineMessage, w as applyLineQuoteToken } from "./send-retry-DbfiHBPd.mjs";
1
+ import { r as resolveLineAccount } from "./accounts-DOiM8-y3.mjs";
2
+ import { A as withoutLineQuoteTokens, g as messageAction, i as runLinePushWithRetries, j as buildLineMediaMessage, n as findLineHttpError, o as resolveLineChannelAccessToken, s as createLineSendReceipt, v as normalizeLineMessage, w as applyLineQuoteToken } from "./send-retry-DV6I0muq.mjs";
3
3
  import { createChannelPartialDeliveryError } from "openclaw/plugin-sdk/channel-inbound";
4
4
  import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
5
5
  import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
@@ -112,21 +112,6 @@ function resolveLineMessagingAccount(opts) {
112
112
  token: resolveLineChannelAccessToken(opts.channelAccessToken, account)
113
113
  };
114
114
  }
115
- function createLineMessagingClient(opts) {
116
- const { account, token } = resolveLineMessagingAccount(opts);
117
- return {
118
- account,
119
- client: new messagingApi.MessagingApiClient({ channelAccessToken: token })
120
- };
121
- }
122
- function createLinePushContext(to, opts) {
123
- const { account, token } = resolveLineMessagingAccount(opts);
124
- return {
125
- account,
126
- token,
127
- chatId: normalizeTarget(to)
128
- };
129
- }
130
115
  async function sendLineProviderMessages(operation, token, request, retryKey, authorize) {
131
116
  try {
132
117
  return await postLineProviderMessages(operation, token, request, retryKey, authorize);
@@ -233,7 +218,8 @@ function resolveLineReceiptKind(messages) {
233
218
  }
234
219
  async function pushLineMessages(to, messages, opts, behavior = {}) {
235
220
  if (messages.length === 0) throw new Error("Message must be non-empty for LINE sends");
236
- const { account, token, chatId } = createLinePushContext(to, opts);
221
+ const { account, token } = resolveLineMessagingAccount(opts);
222
+ const chatId = normalizeTarget(to);
237
223
  const normalizedMessages = applyLineQuoteToken(messages, opts.quoteToken).map(normalizeLineMessage);
238
224
  const retryKey = randomUUID();
239
225
  const { messageId, messageIds } = resolveLineProviderMessageIds(await runLinePushWithRetries(async () => {
@@ -333,12 +319,6 @@ function createFlexMessage(altText, contents) {
333
319
  contents
334
320
  };
335
321
  }
336
- async function pushImageMessage(to, originalContentUrl, previewImageUrl, opts) {
337
- return pushLineMessages(to, [await buildLineMediaMessage(originalContentUrl, {
338
- mediaKind: "image",
339
- previewImageUrl
340
- }, to)], opts, { verboseMessage: (chatId) => `line: pushed image to ${chatId}` });
341
- }
342
322
  async function pushLocationMessage(to, location, opts) {
343
323
  return pushLineMessages(to, [createLocationMessage(location)], opts, { verboseMessage: (chatId) => `line: pushed location to ${chatId}` });
344
324
  }
@@ -368,7 +348,8 @@ function createTextMessageWithQuickReplies(text, quickReplyLabels) {
368
348
  };
369
349
  }
370
350
  async function showLoadingAnimation(chatId, opts) {
371
- const { client } = createLineMessagingClient(opts);
351
+ const { token } = resolveLineMessagingAccount(opts);
352
+ const client = new messagingApi.MessagingApiClient({ channelAccessToken: token });
372
353
  try {
373
354
  await client.showLoadingAnimation({
374
355
  chatId: normalizeTarget(chatId),
@@ -446,4 +427,4 @@ async function getLineGroupName(groupId, opts) {
446
427
  }
447
428
  }
448
429
  //#endregion
449
- export { showLoadingAnimation as _, getLineGroupName as a, pushFlexMessage as c, pushMessageLine as d, pushMessagesLine as f, sendMessageLine as g, replyMessageLine as h, createTextMessageWithQuickReplies as i, pushImageMessage as l, pushTextMessageWithQuickReplies as m, createLocationMessage as n, getUserDisplayName as o, pushTemplateMessage as p, createQuickReplyItems as r, getUserProfile as s, createFlexMessage as t, pushLocationMessage as u, quotesLineBotMessage as v };
430
+ export { getUserDisplayName as a, pushLocationMessage as c, pushTemplateMessage as d, pushTextMessageWithQuickReplies as f, quotesLineBotMessage as g, showLoadingAnimation as h, getLineGroupName as i, pushMessageLine as l, sendMessageLine as m, createLocationMessage as n, getUserProfile as o, replyMessageLine as p, createQuickReplyItems as r, pushFlexMessage as s, createFlexMessage as t, pushMessagesLine as u };
@@ -1,4 +1,5 @@
1
- import { i as resolveLineAccount, n as normalizeAccountId, r as resolveDefaultLineAccountId } from "./accounts-BBEFMYbY.mjs";
1
+ import { n as resolveDefaultLineAccountId, r as resolveLineAccount } from "./accounts-DOiM8-y3.mjs";
2
+ import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
2
3
  import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
3
4
  import { createMessageReceiptFromOutboundResults } from "openclaw/plugin-sdk/channel-outbound";
4
5
  import { collectErrorGraphCandidates, extractErrorCode, formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
@@ -560,24 +561,21 @@ function postbackAction(label, data, displayText) {
560
561
  displayText
561
562
  });
562
563
  }
563
- /**
564
- * Create a datetime picker action
565
- */
566
- function datetimePickerAction(label, data, mode, options) {
567
- return normalizeLineAction({
568
- type: "datetimepicker",
569
- label,
570
- data,
571
- mode,
572
- initial: options?.initial,
573
- max: options?.max,
574
- min: options?.min
575
- });
576
- }
577
564
  //#endregion
578
565
  //#region extensions/line/src/flex-templates/common.ts
579
- function attachFooterText(bubble, footer) {
580
- bubble.footer = {
566
+ function createCardBubble(bodyContents, footer) {
567
+ const bubble = {
568
+ type: "bubble",
569
+ size: "mega",
570
+ body: {
571
+ type: "box",
572
+ layout: "vertical",
573
+ contents: bodyContents,
574
+ paddingAll: "xl",
575
+ backgroundColor: "#FFFFFF"
576
+ }
577
+ };
578
+ if (footer) bubble.footer = {
581
579
  type: "box",
582
580
  layout: "vertical",
583
581
  contents: [{
@@ -591,71 +589,48 @@ function attachFooterText(bubble, footer) {
591
589
  paddingAll: "lg",
592
590
  backgroundColor: "#FAFAFA"
593
591
  };
592
+ return bubble;
594
593
  }
595
594
  //#endregion
596
595
  //#region extensions/line/src/flex-templates/basic-cards.ts
597
- /**
598
- * Create an info card with title, body, and optional footer
599
- *
600
- * Editorial design: Clean hierarchy with accent bar, generous spacing,
601
- * and subtle background zones for visual separation.
602
- */
603
596
  function createInfoCard(title, body, footer) {
604
- const bubble = {
605
- type: "bubble",
606
- size: "mega",
607
- body: {
597
+ return createCardBubble([{
598
+ type: "box",
599
+ layout: "horizontal",
600
+ contents: [{
608
601
  type: "box",
609
602
  layout: "vertical",
610
- contents: [{
611
- type: "box",
612
- layout: "horizontal",
613
- contents: [{
614
- type: "box",
615
- layout: "vertical",
616
- contents: [],
617
- width: "4px",
618
- backgroundColor: "#06C755",
619
- cornerRadius: "2px"
620
- }, {
621
- type: "text",
622
- text: title,
623
- weight: "bold",
624
- size: "xl",
625
- color: "#111111",
626
- wrap: true,
627
- flex: 1,
628
- margin: "lg"
629
- }]
630
- }, ...body ? [{
631
- type: "box",
632
- layout: "vertical",
633
- contents: [{
634
- type: "text",
635
- text: body,
636
- size: "md",
637
- color: "#444444",
638
- wrap: true,
639
- lineSpacing: "6px"
640
- }],
641
- margin: "xl",
642
- paddingAll: "lg",
643
- backgroundColor: "#F8F9FA",
644
- cornerRadius: "lg"
645
- }] : []],
646
- paddingAll: "xl",
647
- backgroundColor: "#FFFFFF"
648
- }
649
- };
650
- if (footer) attachFooterText(bubble, footer);
651
- return bubble;
603
+ contents: [],
604
+ width: "4px",
605
+ backgroundColor: "#06C755",
606
+ cornerRadius: "2px"
607
+ }, {
608
+ type: "text",
609
+ text: title,
610
+ weight: "bold",
611
+ size: "xl",
612
+ color: "#111111",
613
+ wrap: true,
614
+ flex: 1,
615
+ margin: "lg"
616
+ }]
617
+ }, ...body ? [{
618
+ type: "box",
619
+ layout: "vertical",
620
+ contents: [{
621
+ type: "text",
622
+ text: body,
623
+ size: "md",
624
+ color: "#444444",
625
+ wrap: true,
626
+ lineSpacing: "6px"
627
+ }],
628
+ margin: "xl",
629
+ paddingAll: "lg",
630
+ backgroundColor: "#F8F9FA",
631
+ cornerRadius: "lg"
632
+ }] : []], footer);
652
633
  }
653
- /**
654
- * Create a list card with title and multiple items
655
- *
656
- * Editorial design: Numbered/bulleted list with clear visual hierarchy,
657
- * accent dots for each item, and generous spacing.
658
- */
659
634
  function createListCard(title, items) {
660
635
  const itemContents = items.slice(0, 8).map((item, index) => {
661
636
  const itemContentsLocal = [{
@@ -703,43 +678,53 @@ function createListCard(title, items) {
703
678
  if (item.action) itemBox.action = normalizeLineAction(item.action, 40);
704
679
  return itemBox;
705
680
  });
706
- return {
707
- type: "bubble",
708
- size: "mega",
709
- body: {
681
+ return createCardBubble([
682
+ {
683
+ type: "text",
684
+ text: title,
685
+ weight: "bold",
686
+ size: "xl",
687
+ color: "#111111",
688
+ wrap: true
689
+ },
690
+ {
691
+ type: "separator",
692
+ margin: "lg",
693
+ color: "#EEEEEE"
694
+ },
695
+ {
710
696
  type: "box",
711
697
  layout: "vertical",
712
- contents: [
713
- {
714
- type: "text",
715
- text: title,
716
- weight: "bold",
717
- size: "xl",
718
- color: "#111111",
719
- wrap: true
720
- },
721
- {
722
- type: "separator",
723
- margin: "lg",
724
- color: "#EEEEEE"
725
- },
726
- {
727
- type: "box",
728
- layout: "vertical",
729
- contents: itemContents,
730
- margin: "lg"
731
- }
732
- ],
733
- paddingAll: "xl",
734
- backgroundColor: "#FFFFFF"
698
+ contents: itemContents,
699
+ margin: "lg"
735
700
  }
701
+ ]);
702
+ }
703
+ function createTitleBody(title, body) {
704
+ const box = {
705
+ type: "box",
706
+ layout: "vertical",
707
+ contents: [{
708
+ type: "text",
709
+ text: title,
710
+ weight: "bold",
711
+ size: "xl",
712
+ wrap: true
713
+ }],
714
+ paddingAll: "lg"
736
715
  };
716
+ if (body) box.contents.push({
717
+ type: "text",
718
+ text: body,
719
+ size: "md",
720
+ wrap: true,
721
+ margin: "md",
722
+ color: "#666666"
723
+ });
724
+ return box;
737
725
  }
738
- /**
739
- * Create an image card with image, title, and optional body text
740
- */
741
726
  function createImageCard(imageUrl, title, body, options) {
742
- const bubble = {
727
+ return {
743
728
  type: "bubble",
744
729
  hero: {
745
730
  type: "image",
@@ -749,54 +734,13 @@ function createImageCard(imageUrl, title, body, options) {
749
734
  aspectMode: options?.aspectMode ?? "cover",
750
735
  action: options?.action === void 0 ? void 0 : normalizeLineAction(options.action, 40)
751
736
  },
752
- body: {
753
- type: "box",
754
- layout: "vertical",
755
- contents: [{
756
- type: "text",
757
- text: title,
758
- weight: "bold",
759
- size: "xl",
760
- wrap: true
761
- }],
762
- paddingAll: "lg"
763
- }
737
+ body: createTitleBody(title, body)
764
738
  };
765
- if (body && bubble.body) bubble.body.contents.push({
766
- type: "text",
767
- text: body,
768
- size: "md",
769
- wrap: true,
770
- margin: "md",
771
- color: "#666666"
772
- });
773
- return bubble;
774
739
  }
775
- /**
776
- * Create an action card with title, body, and action buttons
777
- */
778
740
  function createActionCard(title, body, actions, options) {
779
741
  const bubble = {
780
742
  type: "bubble",
781
- body: {
782
- type: "box",
783
- layout: "vertical",
784
- contents: [{
785
- type: "text",
786
- text: title,
787
- weight: "bold",
788
- size: "xl",
789
- wrap: true
790
- }, ...body ? [{
791
- type: "text",
792
- text: body,
793
- size: "md",
794
- wrap: true,
795
- margin: "md",
796
- color: "#666666"
797
- }] : []],
798
- paddingAll: "lg"
799
- },
743
+ body: createTitleBody(title, body),
800
744
  footer: {
801
745
  type: "box",
802
746
  layout: "vertical",
@@ -851,27 +795,6 @@ function buildCardHeaderSections(headerContents) {
851
795
  color: "#EEEEEE"
852
796
  }];
853
797
  }
854
- function createMegaBubbleWithFooter(params) {
855
- const bubble = {
856
- type: "bubble",
857
- size: "mega",
858
- body: {
859
- type: "box",
860
- layout: "vertical",
861
- contents: params.bodyContents,
862
- paddingAll: "xl",
863
- backgroundColor: "#FFFFFF"
864
- }
865
- };
866
- if (params.footer) attachFooterText(bubble, params.footer);
867
- return bubble;
868
- }
869
- /**
870
- * Create a receipt/summary card (for orders, transactions, data tables)
871
- *
872
- * Editorial design: Clean table layout with alternating row backgrounds,
873
- * prominent total section, and clear visual hierarchy.
874
- */
875
798
  function createReceiptCard(params) {
876
799
  const { title, subtitle, items, total, footer } = params;
877
800
  const itemRows = items.slice(0, 12).map((item, index) => ({
@@ -934,17 +857,8 @@ function createReceiptCard(params) {
934
857
  backgroundColor: "#F0FDF4",
935
858
  cornerRadius: "lg"
936
859
  });
937
- return createMegaBubbleWithFooter({
938
- bodyContents,
939
- footer
940
- });
860
+ return createCardBubble(bodyContents, footer);
941
861
  }
942
- /**
943
- * Create a calendar event card (for meetings, appointments, reminders)
944
- *
945
- * Editorial design: Date as hero, strong typographic hierarchy,
946
- * color-blocked zones, full text wrapping for readability.
947
- */
948
862
  function createEventCard(params) {
949
863
  const { title, date, time, location, description, calendar, isAllDay, action } = params;
950
864
  const dateBlock = {
@@ -1052,25 +966,10 @@ function createEventCard(params) {
1052
966
  cornerRadius: "lg"
1053
967
  });
1054
968
  }
1055
- return {
1056
- type: "bubble",
1057
- size: "mega",
1058
- body: {
1059
- type: "box",
1060
- layout: "vertical",
1061
- contents: bodyContents,
1062
- paddingAll: "xl",
1063
- backgroundColor: "#FFFFFF",
1064
- action: action === void 0 ? void 0 : normalizeLineAction(action, 40)
1065
- }
1066
- };
969
+ const bubble = createCardBubble(bodyContents);
970
+ bubble.body.action = action === void 0 ? void 0 : normalizeLineAction(action, 40);
971
+ return bubble;
1067
972
  }
1068
- /**
1069
- * Create a calendar agenda card showing multiple events
1070
- *
1071
- * Editorial timeline design: Time-focused left column with event details
1072
- * on the right. Visual accent bars indicate event priority/recency.
1073
- */
1074
973
  function createAgendaCard(params) {
1075
974
  const { title, subtitle, events, footer } = params;
1076
975
  const headerContents = buildTitleSubtitleHeader({
@@ -1148,15 +1047,12 @@ function createAgendaCard(params) {
1148
1047
  alignItems: "flex-start"
1149
1048
  };
1150
1049
  });
1151
- return createMegaBubbleWithFooter({
1152
- bodyContents: [...buildCardHeaderSections(headerContents), {
1153
- type: "box",
1154
- layout: "vertical",
1155
- contents: eventItems,
1156
- paddingTop: "xl"
1157
- }],
1158
- footer
1159
- });
1050
+ return createCardBubble([...buildCardHeaderSections(headerContents), {
1051
+ type: "box",
1052
+ layout: "vertical",
1053
+ contents: eventItems,
1054
+ paddingTop: "xl"
1055
+ }], footer);
1160
1056
  }
1161
1057
  //#endregion
1162
1058
  //#region extensions/line/src/send-receipt.ts
@@ -1334,4 +1230,4 @@ async function explainLineRefusal(params) {
1334
1230
  };
1335
1231
  }
1336
1232
  //#endregion
1337
- export { withoutLineQuoteTokens as A, toFlexMessage as C, recordLineQuoteToken as D, readLineQuoteToken as E, inferLineTargetChatType as F, normalizeLineMessagingTarget as I, createAudioMessage as M, createImageMessage as N, reportLineQuoteCarrierMissing as O, createVideoMessage as P, fitsLineFlexBubble as S, canCarryLineQuoteToken as T, normalizeLineAction as _, probeLineBot as a, truncateLineActionLabel as b, createAgendaCard as c, createActionCard as d, createImageCard as f, messageAction as g, datetimePickerAction as h, runLinePushWithRetries as i, buildLineMediaMessage as j, resolveLineQuoteToken as k, createEventCard as l, createListCard as m, findLineHttpError as n, resolveLineChannelAccessToken as o, createInfoCard as p, resolveLineNonDispatchRetryable as r, createLineSendReceipt as s, explainLineRefusal as t, createReceiptCard as u, normalizeLineMessage as v, applyLineQuoteToken as w, uriAction as x, postbackAction as y };
1233
+ export { withoutLineQuoteTokens as A, toFlexMessage as C, recordLineQuoteToken as D, readLineQuoteToken as E, inferLineTargetChatType as M, normalizeLineMessagingTarget as N, reportLineQuoteCarrierMissing as O, fitsLineFlexBubble as S, canCarryLineQuoteToken as T, normalizeLineAction as _, probeLineBot as a, truncateLineActionLabel as b, createAgendaCard as c, createActionCard as d, createImageCard as f, messageAction as g, createCardBubble as h, runLinePushWithRetries as i, buildLineMediaMessage as j, resolveLineQuoteToken as k, createEventCard as l, createListCard as m, findLineHttpError as n, resolveLineChannelAccessToken as o, createInfoCard as p, resolveLineNonDispatchRetryable as r, createLineSendReceipt as s, explainLineRefusal as t, createReceiptCard as u, normalizeLineMessage as v, applyLineQuoteToken as w, uriAction as x, postbackAction as y };
@@ -1,9 +1,20 @@
1
- import { i as resolveLineAccount, n as normalizeAccountId, r as resolveDefaultLineAccountId, t as listLineAccountIds } from "./accounts-BBEFMYbY.mjs";
2
- import { n as parseLineAllowFromId, t as hasLineCredentials } from "./account-helpers-BSUyZwLm.mjs";
1
+ import { n as resolveDefaultLineAccountId, r as resolveLineAccount, t as listLineAccountIds } from "./accounts-DOiM8-y3.mjs";
2
+ import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
3
3
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  import { defineChannelSetupContract } from "openclaw/plugin-sdk/channel-setup";
5
- import { DEFAULT_ACCOUNT_ID, createAllowFromSection, createPromptParsedAllowFromForAccount, createSetupInputPresenceValidator, createSetupTranslator, createStandardChannelSetupStatus, defineTokenCredential, formatDocsLink, parseSetupEntriesWithParser, patchScopedAccountConfig, setSetupChannelEnabled, splitSetupEntries } from "openclaw/plugin-sdk/setup";
5
+ import { createAllowFromSection, createPromptParsedAllowFromForAccount, createSetupInputPresenceValidator, createSetupTranslator, createStandardChannelSetupStatus, defineTokenCredential, formatDocsLink, parseSetupEntriesWithParser, patchScopedAccountConfig, setSetupChannelEnabled, splitSetupEntries } from "openclaw/plugin-sdk/setup";
6
6
  import { createChannelDmPolicy } from "openclaw/plugin-sdk/channel-dm-policy";
7
+ //#region extensions/line/src/account-helpers.ts
8
+ function hasLineCredentials(account) {
9
+ if (account.tokenStatus && account.signingSecretStatus) return account.tokenStatus !== "missing" && account.signingSecretStatus !== "missing";
10
+ return Boolean(account.channelAccessToken?.trim() && account.channelSecret?.trim());
11
+ }
12
+ function parseLineAllowFromId(raw) {
13
+ const trimmed = raw.trim().replace(/^line:(?:user:)?/i, "");
14
+ if (!/^U[a-f0-9]{32}$/i.test(trimmed)) return null;
15
+ return trimmed;
16
+ }
17
+ //#endregion
7
18
  //#region extensions/line/src/setup-core.ts
8
19
  function patchLineAccountConfig(params) {
9
20
  return patchScopedAccountConfig({
@@ -311,4 +322,4 @@ const lineSetupWizard = {
311
322
  disable: (cfg) => setSetupChannelEnabled(cfg, channel, false)
312
323
  };
313
324
  //#endregion
314
- export { lineSetupAdapter as n, lineSetupContract as r, lineSetupWizard as t };
325
+ export { hasLineCredentials as i, lineSetupAdapter as n, lineSetupContract as r, lineSetupWizard as t };