@openclaw/line 2026.6.11-beta.2 → 2026.7.1-beta.1

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
@@ -4,7 +4,7 @@ let lineCardCommandPromise = null;
4
4
  async function loadLineCardCommand(api) {
5
5
  lineCardCommandPromise ??= (async () => {
6
6
  let registered = null;
7
- const { registerLineCardCommand } = await import("./card-command-ML0lh9al.js");
7
+ const { registerLineCardCommand } = await import("./card-command-BaaE1SfK.js");
8
8
  registerLineCardCommand({
9
9
  ...api,
10
10
  registerCommand(command) {
@@ -1,70 +1,11 @@
1
- import { i as resolveLineAccount } from "./accounts-B-K3yrdP.js";
2
- import { l as validateLineMediaUrl, o as createLineSendReceipt } from "./reply-payload-transform-DZ8-37Ot.js";
3
- import { r as createReceiptCard } from "./schedule-cards-Bq74H30B.js";
1
+ import { i as resolveLineAccount } from "./accounts-DJVOv1JI.js";
2
+ import { o as validateLineMediaUrl, r as createLineSendReceipt } from "./reply-payload-transform-BwF-zq0G.js";
3
+ import { c as uriAction, d as createReceiptCard, o as messageAction, s as postbackAction, t as toFlexMessage } from "./flex-templates-DPBtqQ8R.js";
4
4
  import { messagingApi } from "@line/bot-sdk";
5
5
  import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
6
6
  import { recordChannelActivity } from "openclaw/plugin-sdk/channel-activity-runtime";
7
7
  import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
8
8
  import { stripMarkdown, stripMarkdown as stripMarkdown$1 } from "openclaw/plugin-sdk/text-chunking";
9
- //#region extensions/line/src/flex-templates/message.ts
10
- /**
11
- * Wrap a FlexContainer in a FlexMessage
12
- */
13
- function toFlexMessage(altText, contents) {
14
- return {
15
- type: "flex",
16
- altText,
17
- contents
18
- };
19
- }
20
- //#endregion
21
- //#region extensions/line/src/actions.ts
22
- /**
23
- * Create a message action (sends text when tapped)
24
- */
25
- function messageAction(label, text) {
26
- return {
27
- type: "message",
28
- label: label.slice(0, 20),
29
- text: text ?? label
30
- };
31
- }
32
- /**
33
- * Create a URI action (opens a URL when tapped)
34
- */
35
- function uriAction(label, uri) {
36
- return {
37
- type: "uri",
38
- label: label.slice(0, 20),
39
- uri
40
- };
41
- }
42
- /**
43
- * Create a postback action (sends data to webhook when tapped)
44
- */
45
- function postbackAction(label, data, displayText) {
46
- return {
47
- type: "postback",
48
- label: label.slice(0, 20),
49
- data: data.slice(0, 300),
50
- displayText: displayText?.slice(0, 300)
51
- };
52
- }
53
- /**
54
- * Create a datetime picker action
55
- */
56
- function datetimePickerAction(label, data, mode, options) {
57
- return {
58
- type: "datetimepicker",
59
- label: label.slice(0, 20),
60
- data: data.slice(0, 300),
61
- mode,
62
- initial: options?.initial,
63
- max: options?.max,
64
- min: options?.min
65
- };
66
- }
67
- //#endregion
68
9
  //#region extensions/line/src/template-messages.ts
69
10
  const COMPACT_TEMPLATE_TEXT_LIMIT = 60;
70
11
  const graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
@@ -90,6 +31,9 @@ function truncateTemplateText(text, limit) {
90
31
  }
91
32
  return result;
92
33
  }
34
+ function truncateOptionalTemplateText(value, limit) {
35
+ return value === void 0 ? void 0 : truncateTemplateText(value, limit);
36
+ }
93
37
  function formatProductCarouselText(description, price) {
94
38
  if (!price) return description;
95
39
  const priceText = truncateTemplateText(price, COMPACT_TEMPLATE_TEXT_LIMIT);
@@ -102,12 +46,12 @@ function formatProductCarouselText(description, price) {
102
46
  function createConfirmTemplate(text, confirmAction, cancelAction, altText) {
103
47
  const template = {
104
48
  type: "confirm",
105
- text: text.slice(0, 240),
49
+ text: truncateTemplateText(text, 240),
106
50
  actions: [confirmAction, cancelAction]
107
51
  };
108
52
  return {
109
53
  type: "template",
110
- altText: altText?.slice(0, 400) ?? text.slice(0, 400),
54
+ altText: truncateOptionalTemplateText(altText, 400) ?? truncateTemplateText(text, 400),
111
55
  template
112
56
  };
113
57
  }
@@ -122,7 +66,7 @@ function createButtonTemplate(title, text, actions, options) {
122
66
  });
123
67
  const template = {
124
68
  type: "buttons",
125
- title: title.slice(0, 40),
69
+ title: truncateTemplateText(title, 40),
126
70
  text: truncateTemplateText(text, textLimit),
127
71
  actions: actions.slice(0, 4),
128
72
  thumbnailImageUrl: options?.thumbnailImageUrl,
@@ -133,7 +77,7 @@ function createButtonTemplate(title, text, actions, options) {
133
77
  };
134
78
  return {
135
79
  type: "template",
136
- altText: options?.altText?.slice(0, 400) ?? `${title}: ${text}`.slice(0, 400),
80
+ altText: truncateOptionalTemplateText(options?.altText, 400) ?? truncateTemplateText(`${title}: ${text}`, 400),
137
81
  template
138
82
  };
139
83
  }
@@ -149,7 +93,7 @@ function createTemplateCarousel(columns, options) {
149
93
  };
150
94
  return {
151
95
  type: "template",
152
- altText: options?.altText?.slice(0, 400) ?? "View carousel",
96
+ altText: truncateOptionalTemplateText(options?.altText, 400) ?? "View carousel",
153
97
  template
154
98
  };
155
99
  }
@@ -162,7 +106,7 @@ function createCarouselColumn(params) {
162
106
  textOnlyLimit: 120
163
107
  });
164
108
  return {
165
- title: params.title?.slice(0, 40),
109
+ title: truncateOptionalTemplateText(params.title, 40),
166
110
  text: truncateTemplateText(params.text, textLimit),
167
111
  actions: params.actions.slice(0, 3),
168
112
  thumbnailImageUrl: params.thumbnailImageUrl,
@@ -180,7 +124,7 @@ function createImageCarousel(columns, altText) {
180
124
  };
181
125
  return {
182
126
  type: "template",
183
- altText: altText?.slice(0, 400) ?? "View images",
127
+ altText: truncateOptionalTemplateText(altText, 400) ?? "View images",
184
128
  template
185
129
  };
186
130
  }
@@ -485,11 +429,7 @@ async function pushTextMessageWithQuickReplies(to, text, quickReplyLabels, opts)
485
429
  function createQuickReplyItems(labels) {
486
430
  return { items: labels.slice(0, 13).map((label) => ({
487
431
  type: "action",
488
- action: {
489
- type: "message",
490
- label: label.slice(0, 20),
491
- text: label
492
- }
432
+ action: messageAction(label, label)
493
433
  })) };
494
434
  }
495
435
  function createTextMessageWithQuickReplies(text, quickReplyLabels) {
@@ -783,11 +723,7 @@ function convertLinksToFlexBubble(links) {
783
723
  layout: "vertical",
784
724
  contents: links.slice(0, 4).map((link, index) => ({
785
725
  type: "button",
786
- action: {
787
- type: "uri",
788
- label: link.text.slice(0, 20),
789
- uri: link.url
790
- },
726
+ action: uriAction(link.text, link.url),
791
727
  style: index === 0 ? "primary" : "secondary",
792
728
  margin: index > 0 ? "sm" : void 0
793
729
  })),
@@ -840,4 +776,4 @@ function hasMarkdownToConvert(text) {
840
776
  return false;
841
777
  }
842
778
  //#endregion
843
- export { buildTemplateMessageFromPayload as A, createYesNoConfirm as B, pushMessagesLine as C, sendMessageLine as D, replyMessageLine as E, createImageCarousel as F, toFlexMessage as G, messageAction as H, createImageCarouselColumn as I, createLinkMenu as L, createButtonTemplate as M, createCarouselColumn as N, showLoadingAnimation as O, createConfirmTemplate as P, createProductCarousel as R, pushMessageLine as S, pushTextMessageWithQuickReplies as T, postbackAction as U, datetimePickerAction as V, uriAction as W, getUserDisplayName as _, extractLinks as a, pushImageMessage as b, processLineMessage as c, createFlexMessage as d, createImageMessage as f, createVideoMessage as g, createTextMessageWithQuickReplies as h, extractCodeBlocks as i, createButtonMenu as j, resolveLineChannelAccessToken as k, stripMarkdown$1 as l, createQuickReplyItems as m, convertLinksToFlexBubble as n, extractMarkdownTables as o, createLocationMessage as p, convertTableToFlexBubble as r, hasMarkdownToConvert as s, convertCodeBlockToFlexBubble as t, createAudioMessage as u, getUserProfile as v, pushTemplateMessage as w, pushLocationMessage as x, pushFlexMessage as y, createTemplateCarousel as z };
779
+ export { buildTemplateMessageFromPayload as A, createYesNoConfirm as B, pushMessagesLine as C, sendMessageLine as D, replyMessageLine as E, createImageCarousel as F, createImageCarouselColumn as I, createLinkMenu as L, createButtonTemplate as M, createCarouselColumn as N, showLoadingAnimation as O, createConfirmTemplate as P, createProductCarousel as R, pushMessageLine as S, pushTextMessageWithQuickReplies as T, getUserDisplayName as _, extractLinks as a, pushImageMessage as b, processLineMessage as c, createFlexMessage as d, createImageMessage as f, createVideoMessage as g, createTextMessageWithQuickReplies as h, extractCodeBlocks as i, createButtonMenu as j, resolveLineChannelAccessToken as k, stripMarkdown$1 as l, createQuickReplyItems as m, convertLinksToFlexBubble as n, extractMarkdownTables as o, createLocationMessage as p, convertTableToFlexBubble as r, hasMarkdownToConvert as s, convertCodeBlockToFlexBubble as t, createAudioMessage as u, getUserProfile as v, pushTemplateMessage as w, pushLocationMessage as x, pushFlexMessage as y, createTemplateCarousel as z };
@@ -1,6 +1,6 @@
1
- import { i as resolveLineAccount, r as resolveDefaultLineAccountId } from "./accounts-B-K3yrdP.js";
2
- import { h as resolveLineGroupConfigEntry, s as buildLineQuickReplyFallbackText, u as getLineRuntime } from "./reply-payload-transform-DZ8-37Ot.js";
3
- import { A as buildTemplateMessageFromPayload, C as pushMessagesLine, E as replyMessageLine, O as showLoadingAnimation, S as pushMessageLine, T as pushTextMessageWithQuickReplies, _ as getUserDisplayName, c as processLineMessage, d as createFlexMessage, f as createImageMessage, h as createTextMessageWithQuickReplies, m as createQuickReplyItems, p as createLocationMessage } from "./markdown-to-line-juqp-iiY.js";
1
+ import { i as resolveLineAccount, r as resolveDefaultLineAccountId } from "./accounts-DJVOv1JI.js";
2
+ import { f as resolveLineGroupConfigEntry, i as buildLineQuickReplyFallbackText, s as getLineRuntime } from "./reply-payload-transform-BwF-zq0G.js";
3
+ import { A as buildTemplateMessageFromPayload, C as pushMessagesLine, E as replyMessageLine, O as showLoadingAnimation, S as pushMessageLine, T as pushTextMessageWithQuickReplies, _ as getUserDisplayName, c as processLineMessage, d as createFlexMessage, f as createImageMessage, h as createTextMessageWithQuickReplies, m as createQuickReplyItems, p as createLocationMessage } from "./markdown-to-line-BBM3V8-S.js";
4
4
  import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
5
5
  import { normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
6
6
  import { createMessageReceiveContext } from "openclaw/plugin-sdk/channel-outbound";
@@ -41,8 +41,8 @@ const normalizeAllowFrom = (list) => {
41
41
  };
42
42
  //#endregion
43
43
  //#region extensions/line/src/download.ts
44
- async function downloadLineMedia(messageId, channelAccessToken, maxBytes = 10 * 1024 * 1024) {
45
- const saved = await saveMediaStream(await new messagingApi.MessagingApiBlobClient({ channelAccessToken }).getMessageContent(messageId), void 0, "inbound", maxBytes);
44
+ async function downloadLineMedia(messageId, channelAccessToken, maxBytes = 10 * 1024 * 1024, options) {
45
+ const saved = await saveMediaStream(await new messagingApi.MessagingApiBlobClient({ channelAccessToken }).getMessageContent(messageId), void 0, "inbound", maxBytes, options?.originalFilename);
46
46
  logVerbose(`line: persisted media ${messageId} to ${saved.path} (${saved.size} bytes)`);
47
47
  return {
48
48
  path: saved.path,
@@ -839,7 +839,8 @@ async function handleMessageEvent(event, context) {
839
839
  }
840
840
  const allMedia = [];
841
841
  if (isDownloadableLineMessageType(message.type)) try {
842
- const media = await downloadLineMedia(message.id, account.channelAccessToken, mediaMaxBytes);
842
+ const originalFilename = message.type === "file" ? normalizeOptionalString(message.fileName) : void 0;
843
+ const media = await downloadLineMedia(message.id, account.channelAccessToken, mediaMaxBytes, { originalFilename });
843
844
  allMedia.push({
844
845
  path: media.path,
845
846
  contentType: media.contentType
@@ -0,0 +1,2 @@
1
+ import { t as monitorLineProvider } from "./monitor-BEsUjORi.js";
2
+ export { monitorLineProvider };
@@ -1,2 +1,2 @@
1
- import { A as buildTemplateMessageFromPayload, C as pushMessagesLine, D as sendMessageLine, S as pushMessageLine, T as pushTextMessageWithQuickReplies, c as processLineMessage, m as createQuickReplyItems, w as pushTemplateMessage, x as pushLocationMessage, y as pushFlexMessage } from "./markdown-to-line-juqp-iiY.js";
1
+ import { A as buildTemplateMessageFromPayload, C as pushMessagesLine, D as sendMessageLine, S as pushMessageLine, T as pushTextMessageWithQuickReplies, c as processLineMessage, m as createQuickReplyItems, w as pushTemplateMessage, x as pushLocationMessage, y as pushFlexMessage } from "./markdown-to-line-BBM3V8-S.js";
2
2
  export { buildTemplateMessageFromPayload, createQuickReplyItems, processLineMessage, pushFlexMessage, pushLocationMessage, pushMessageLine, pushMessagesLine, pushTemplateMessage, pushTextMessageWithQuickReplies, sendMessageLine };
@@ -0,0 +1,2 @@
1
+ import { t as probeLineBot } from "./probe-BslD77tJ.js";
2
+ export { probeLineBot };
@@ -1,4 +1,4 @@
1
- import { n as createEventCard, t as createAgendaCard } from "./schedule-cards-Bq74H30B.js";
1
+ import { i as createMediaPlayerCard, l as createAgendaCard, n as createAppleTvRemoteCard, r as createDeviceControlCard, u as createEventCard } from "./flex-templates-DPBtqQ8R.js";
2
2
  import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
3
3
  import { resolveAccountEntry } from "openclaw/plugin-sdk/account-resolution";
4
4
  import { normalizeLowercaseStringOrEmpty, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -197,405 +197,6 @@ function createLineSendReceipt(params) {
197
197
  });
198
198
  }
199
199
  //#endregion
200
- //#region extensions/line/src/flex-templates/media-control-cards.ts
201
- /**
202
- * Create a media player card for Sonos, Spotify, Apple Music, etc.
203
- *
204
- * Editorial design: Album art hero with gradient overlay for text,
205
- * prominent now-playing indicator, refined playback controls.
206
- */
207
- function createMediaPlayerCard(params) {
208
- const { title, subtitle, source, imageUrl, isPlaying, progress, controls, extraActions } = params;
209
- const trackInfo = [{
210
- type: "text",
211
- text: title,
212
- weight: "bold",
213
- size: "xl",
214
- color: "#111111",
215
- wrap: true
216
- }];
217
- if (subtitle) trackInfo.push({
218
- type: "text",
219
- text: subtitle,
220
- size: "md",
221
- color: "#666666",
222
- wrap: true,
223
- margin: "sm"
224
- });
225
- const statusItems = [];
226
- if (isPlaying !== void 0) statusItems.push({
227
- type: "box",
228
- layout: "horizontal",
229
- contents: [{
230
- type: "box",
231
- layout: "vertical",
232
- contents: [],
233
- width: "8px",
234
- height: "8px",
235
- backgroundColor: isPlaying ? "#06C755" : "#CCCCCC",
236
- cornerRadius: "4px"
237
- }, {
238
- type: "text",
239
- text: isPlaying ? "Now Playing" : "Paused",
240
- size: "xs",
241
- color: isPlaying ? "#06C755" : "#888888",
242
- weight: "bold",
243
- margin: "sm"
244
- }],
245
- alignItems: "center"
246
- });
247
- if (source) statusItems.push({
248
- type: "text",
249
- text: source,
250
- size: "xs",
251
- color: "#AAAAAA",
252
- margin: statusItems.length > 0 ? "lg" : void 0
253
- });
254
- if (progress) statusItems.push({
255
- type: "text",
256
- text: progress,
257
- size: "xs",
258
- color: "#888888",
259
- align: "end",
260
- flex: 1
261
- });
262
- const bodyContents = [{
263
- type: "box",
264
- layout: "vertical",
265
- contents: trackInfo
266
- }];
267
- if (statusItems.length > 0) bodyContents.push({
268
- type: "box",
269
- layout: "horizontal",
270
- contents: statusItems,
271
- margin: "lg",
272
- alignItems: "center"
273
- });
274
- const bubble = {
275
- type: "bubble",
276
- size: "mega",
277
- body: {
278
- type: "box",
279
- layout: "vertical",
280
- contents: bodyContents,
281
- paddingAll: "xl",
282
- backgroundColor: "#FFFFFF"
283
- }
284
- };
285
- if (imageUrl) bubble.hero = {
286
- type: "image",
287
- url: imageUrl,
288
- size: "full",
289
- aspectRatio: "1:1",
290
- aspectMode: "cover"
291
- };
292
- if (controls || extraActions?.length) {
293
- const footerContents = [];
294
- if (controls) {
295
- const controlButtons = [];
296
- if (controls.previous) controlButtons.push({
297
- type: "button",
298
- action: {
299
- type: "postback",
300
- label: "⏮",
301
- data: controls.previous.data
302
- },
303
- style: "secondary",
304
- flex: 1,
305
- height: "sm"
306
- });
307
- if (controls.play) controlButtons.push({
308
- type: "button",
309
- action: {
310
- type: "postback",
311
- label: "▶",
312
- data: controls.play.data
313
- },
314
- style: isPlaying ? "secondary" : "primary",
315
- flex: 1,
316
- height: "sm",
317
- margin: controls.previous ? "md" : void 0
318
- });
319
- if (controls.pause) controlButtons.push({
320
- type: "button",
321
- action: {
322
- type: "postback",
323
- label: "⏸",
324
- data: controls.pause.data
325
- },
326
- style: isPlaying ? "primary" : "secondary",
327
- flex: 1,
328
- height: "sm",
329
- margin: controlButtons.length > 0 ? "md" : void 0
330
- });
331
- if (controls.next) controlButtons.push({
332
- type: "button",
333
- action: {
334
- type: "postback",
335
- label: "⏭",
336
- data: controls.next.data
337
- },
338
- style: "secondary",
339
- flex: 1,
340
- height: "sm",
341
- margin: controlButtons.length > 0 ? "md" : void 0
342
- });
343
- if (controlButtons.length > 0) footerContents.push({
344
- type: "box",
345
- layout: "horizontal",
346
- contents: controlButtons
347
- });
348
- }
349
- if (extraActions?.length) footerContents.push({
350
- type: "box",
351
- layout: "horizontal",
352
- contents: extraActions.slice(0, 2).map((action, index) => ({
353
- type: "button",
354
- action: {
355
- type: "postback",
356
- label: action.label.slice(0, 15),
357
- data: action.data
358
- },
359
- style: "secondary",
360
- flex: 1,
361
- height: "sm",
362
- margin: index > 0 ? "md" : void 0
363
- })),
364
- margin: "md"
365
- });
366
- if (footerContents.length > 0) bubble.footer = {
367
- type: "box",
368
- layout: "vertical",
369
- contents: footerContents,
370
- paddingAll: "lg",
371
- backgroundColor: "#FAFAFA"
372
- };
373
- }
374
- return bubble;
375
- }
376
- /**
377
- * Create an Apple TV remote card with a D-pad and control rows.
378
- */
379
- function createAppleTvRemoteCard(params) {
380
- const { deviceName, status, actionData } = params;
381
- const headerContents = [{
382
- type: "text",
383
- text: deviceName,
384
- weight: "bold",
385
- size: "xl",
386
- color: "#111111",
387
- wrap: true
388
- }];
389
- if (status) headerContents.push({
390
- type: "text",
391
- text: status,
392
- size: "sm",
393
- color: "#666666",
394
- wrap: true,
395
- margin: "sm"
396
- });
397
- const makeButton = (label, data, style = "secondary") => ({
398
- type: "button",
399
- action: {
400
- type: "postback",
401
- label,
402
- data
403
- },
404
- style,
405
- height: "sm",
406
- flex: 1
407
- });
408
- const dpadRows = [
409
- {
410
- type: "box",
411
- layout: "horizontal",
412
- contents: [
413
- { type: "filler" },
414
- makeButton("↑", actionData.up),
415
- { type: "filler" }
416
- ]
417
- },
418
- {
419
- type: "box",
420
- layout: "horizontal",
421
- contents: [
422
- makeButton("←", actionData.left),
423
- makeButton("OK", actionData.select, "primary"),
424
- makeButton("→", actionData.right)
425
- ],
426
- margin: "md"
427
- },
428
- {
429
- type: "box",
430
- layout: "horizontal",
431
- contents: [
432
- { type: "filler" },
433
- makeButton("↓", actionData.down),
434
- { type: "filler" }
435
- ],
436
- margin: "md"
437
- }
438
- ];
439
- const menuRow = {
440
- type: "box",
441
- layout: "horizontal",
442
- contents: [makeButton("Menu", actionData.menu), makeButton("Home", actionData.home)],
443
- margin: "lg"
444
- };
445
- const playbackRow = {
446
- type: "box",
447
- layout: "horizontal",
448
- contents: [makeButton("Play", actionData.play), makeButton("Pause", actionData.pause)],
449
- margin: "md"
450
- };
451
- const volumeRow = {
452
- type: "box",
453
- layout: "horizontal",
454
- contents: [
455
- makeButton("Vol +", actionData.volumeUp),
456
- makeButton("Mute", actionData.mute),
457
- makeButton("Vol -", actionData.volumeDown)
458
- ],
459
- margin: "md"
460
- };
461
- return {
462
- type: "bubble",
463
- size: "mega",
464
- body: {
465
- type: "box",
466
- layout: "vertical",
467
- contents: [
468
- {
469
- type: "box",
470
- layout: "vertical",
471
- contents: headerContents
472
- },
473
- {
474
- type: "separator",
475
- margin: "lg",
476
- color: "#EEEEEE"
477
- },
478
- ...dpadRows,
479
- menuRow,
480
- playbackRow,
481
- volumeRow
482
- ],
483
- paddingAll: "xl",
484
- backgroundColor: "#FFFFFF"
485
- }
486
- };
487
- }
488
- /**
489
- * Create a device control card for Apple TV, smart home devices, etc.
490
- *
491
- * Editorial design: Device-focused header with status indicator,
492
- * clean control grid with clear visual hierarchy.
493
- */
494
- function createDeviceControlCard(params) {
495
- const { deviceName, deviceType, status, isOnline, imageUrl, controls } = params;
496
- const headerContents = [{
497
- type: "box",
498
- layout: "horizontal",
499
- contents: [{
500
- type: "box",
501
- layout: "vertical",
502
- contents: [],
503
- width: "10px",
504
- height: "10px",
505
- backgroundColor: isOnline !== false ? "#06C755" : "#FF5555",
506
- cornerRadius: "5px"
507
- }, {
508
- type: "text",
509
- text: deviceName,
510
- weight: "bold",
511
- size: "xl",
512
- color: "#111111",
513
- wrap: true,
514
- flex: 1,
515
- margin: "md"
516
- }],
517
- alignItems: "center"
518
- }];
519
- if (deviceType) headerContents.push({
520
- type: "text",
521
- text: deviceType,
522
- size: "sm",
523
- color: "#888888",
524
- margin: "sm"
525
- });
526
- if (status) headerContents.push({
527
- type: "box",
528
- layout: "vertical",
529
- contents: [{
530
- type: "text",
531
- text: status,
532
- size: "sm",
533
- color: "#444444",
534
- wrap: true
535
- }],
536
- margin: "lg",
537
- paddingAll: "md",
538
- backgroundColor: "#F8F9FA",
539
- cornerRadius: "md"
540
- });
541
- const bubble = {
542
- type: "bubble",
543
- size: "mega",
544
- body: {
545
- type: "box",
546
- layout: "vertical",
547
- contents: headerContents,
548
- paddingAll: "xl",
549
- backgroundColor: "#FFFFFF"
550
- }
551
- };
552
- if (imageUrl) bubble.hero = {
553
- type: "image",
554
- url: imageUrl,
555
- size: "full",
556
- aspectRatio: "16:9",
557
- aspectMode: "cover"
558
- };
559
- if (controls.length > 0) {
560
- const rows = [];
561
- const limitedControls = controls.slice(0, 6);
562
- for (let i = 0; i < limitedControls.length; i += 2) {
563
- const rowButtons = [];
564
- for (let j = i; j < Math.min(i + 2, limitedControls.length); j++) {
565
- const ctrl = limitedControls[j];
566
- const buttonLabel = ctrl.icon ? `${ctrl.icon} ${ctrl.label}` : ctrl.label;
567
- rowButtons.push({
568
- type: "button",
569
- action: {
570
- type: "postback",
571
- label: buttonLabel.slice(0, 18),
572
- data: ctrl.data
573
- },
574
- style: ctrl.style ?? "secondary",
575
- flex: 1,
576
- height: "sm",
577
- margin: j > i ? "md" : void 0
578
- });
579
- }
580
- if (rowButtons.length === 1) rowButtons.push({ type: "filler" });
581
- rows.push({
582
- type: "box",
583
- layout: "horizontal",
584
- contents: rowButtons,
585
- margin: i > 0 ? "md" : void 0
586
- });
587
- }
588
- bubble.footer = {
589
- type: "box",
590
- layout: "vertical",
591
- contents: rows,
592
- paddingAll: "lg",
593
- backgroundColor: "#FAFAFA"
594
- };
595
- }
596
- return bubble;
597
- }
598
- //#endregion
599
200
  //#region extensions/line/src/reply-payload-transform.ts
600
201
  /**
601
202
  * Parse LINE-specific directives from text and extract them into ReplyPayload fields.
@@ -853,4 +454,4 @@ function hasLineDirectives(text) {
853
454
  return /\[\[(quick_replies|location|confirm|buttons|media_player|event|agenda|device|appletv_remote):/i.test(text);
854
455
  }
855
456
  //#endregion
856
- export { resolveLineGroupsConfig as _, createMediaPlayerCard as a, resolveLineOutboundMedia as c, setLineRuntime as d, LineChannelConfigSchema as f, resolveLineGroupLookupIds as g, resolveLineGroupConfigEntry as h, createDeviceControlCard as i, validateLineMediaUrl as l, resolveExactLineGroupConfigKey as m, parseLineDirectives as n, createLineSendReceipt as o, LineConfigSchema as p, createAppleTvRemoteCard as r, buildLineQuickReplyFallbackText as s, hasLineDirectives as t, getLineRuntime as u };
457
+ export { resolveLineOutboundMedia as a, setLineRuntime as c, resolveExactLineGroupConfigKey as d, resolveLineGroupConfigEntry as f, buildLineQuickReplyFallbackText as i, LineChannelConfigSchema as l, resolveLineGroupsConfig as m, parseLineDirectives as n, validateLineMediaUrl as o, resolveLineGroupLookupIds as p, createLineSendReceipt as r, getLineRuntime as s, hasLineDirectives as t, LineConfigSchema as u };
@@ -1,10 +1,9 @@
1
- import { i as resolveLineAccount, n as normalizeAccountId, r as resolveDefaultLineAccountId, t as listLineAccountIds } from "./accounts-B-K3yrdP.js";
2
- import { _ as resolveLineGroupsConfig, a as createMediaPlayerCard, d as setLineRuntime, f as LineChannelConfigSchema, g as resolveLineGroupLookupIds, h as resolveLineGroupConfigEntry, i as createDeviceControlCard, m as resolveExactLineGroupConfigKey, n as parseLineDirectives, p as LineConfigSchema, r as createAppleTvRemoteCard, t as hasLineDirectives } from "./reply-payload-transform-DZ8-37Ot.js";
3
- import { n as createEventCard, r as createReceiptCard, t as createAgendaCard } from "./schedule-cards-Bq74H30B.js";
4
- import { a as createListCard, i as createInfoCard, n as createCarousel, o as createNotificationBubble, r as createImageCard, t as createActionCard } from "./basic-cards-B1eTkw-f.js";
5
- import { A as buildTemplateMessageFromPayload, B as createYesNoConfirm, C as pushMessagesLine, D as sendMessageLine, E as replyMessageLine, F as createImageCarousel, G as toFlexMessage, H as messageAction, I as createImageCarouselColumn, L as createLinkMenu, M as createButtonTemplate, N as createCarouselColumn, O as showLoadingAnimation, P as createConfirmTemplate, R as createProductCarousel, S as pushMessageLine, T as pushTextMessageWithQuickReplies, U as postbackAction, V as datetimePickerAction, W as uriAction, _ as getUserDisplayName, a as extractLinks, b as pushImageMessage, c as processLineMessage, d as createFlexMessage, f as createImageMessage, g as createVideoMessage, h as createTextMessageWithQuickReplies, i as extractCodeBlocks, j as createButtonMenu, k as resolveLineChannelAccessToken, l as stripMarkdown, m as createQuickReplyItems, n as convertLinksToFlexBubble, o as extractMarkdownTables, p as createLocationMessage, r as convertTableToFlexBubble, s as hasMarkdownToConvert, t as convertCodeBlockToFlexBubble, u as createAudioMessage, v as getUserProfile, w as pushTemplateMessage, x as pushLocationMessage, y as pushFlexMessage, z as createTemplateCarousel } from "./markdown-to-line-juqp-iiY.js";
6
- import { a as validateLineSignature, c as normalizeAllowFrom, i as parseLineWebhookBody, n as createLineNodeWebhookHandler, o as downloadLineMedia, r as readLineWebhookRequestBody, s as firstDefined, t as monitorLineProvider } from "./monitor-CULIHcvR.js";
7
- import { t as probeLineBot } from "./probe-CqTNoMdZ.js";
1
+ import { i as resolveLineAccount, n as normalizeAccountId, r as resolveDefaultLineAccountId, t as listLineAccountIds } from "./accounts-DJVOv1JI.js";
2
+ import { c as setLineRuntime, d as resolveExactLineGroupConfigKey, f as resolveLineGroupConfigEntry, l as LineChannelConfigSchema, m as resolveLineGroupsConfig, n as parseLineDirectives, p as resolveLineGroupLookupIds, t as hasLineDirectives, u as LineConfigSchema } from "./reply-payload-transform-BwF-zq0G.js";
3
+ import { _ as createNotificationBubble, a as datetimePickerAction, c as uriAction, d as createReceiptCard, f as createActionCard, g as createListCard, h as createInfoCard, i as createMediaPlayerCard, l as createAgendaCard, m as createImageCard, n as createAppleTvRemoteCard, o as messageAction, p as createCarousel, r as createDeviceControlCard, s as postbackAction, t as toFlexMessage, u as createEventCard } from "./flex-templates-DPBtqQ8R.js";
4
+ import { a as validateLineSignature, c as normalizeAllowFrom, i as parseLineWebhookBody, n as createLineNodeWebhookHandler, o as downloadLineMedia, r as readLineWebhookRequestBody, s as firstDefined, t as monitorLineProvider } from "./monitor-BEsUjORi.js";
5
+ import { t as probeLineBot } from "./probe-BslD77tJ.js";
6
+ import { A as buildTemplateMessageFromPayload, B as createYesNoConfirm, C as pushMessagesLine, D as sendMessageLine, E as replyMessageLine, F as createImageCarousel, I as createImageCarouselColumn, L as createLinkMenu, M as createButtonTemplate, N as createCarouselColumn, O as showLoadingAnimation, P as createConfirmTemplate, R as createProductCarousel, S as pushMessageLine, T as pushTextMessageWithQuickReplies, _ as getUserDisplayName, a as extractLinks, b as pushImageMessage, c as processLineMessage, d as createFlexMessage, f as createImageMessage, g as createVideoMessage, h as createTextMessageWithQuickReplies, i as extractCodeBlocks, j as createButtonMenu, k as resolveLineChannelAccessToken, l as stripMarkdown, m as createQuickReplyItems, n as convertLinksToFlexBubble, o as extractMarkdownTables, p as createLocationMessage, r as convertTableToFlexBubble, s as hasMarkdownToConvert, t as convertCodeBlockToFlexBubble, u as createAudioMessage, v as getUserProfile, w as pushTemplateMessage, x as pushLocationMessage, y as pushFlexMessage, z as createTemplateCarousel } from "./markdown-to-line-BBM3V8-S.js";
8
7
  import { clearAccountEntryFields } from "openclaw/plugin-sdk/core";
9
8
  import { buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";
10
9
  import { createMessageReceiveContext } from "openclaw/plugin-sdk/channel-outbound";
package/dist/setup-api.js CHANGED
@@ -1,2 +1,2 @@
1
- import { n as lineSetupAdapter, t as lineSetupWizard } from "./setup-surface-CvTRDCEq.js";
1
+ import { n as lineSetupAdapter, t as lineSetupWizard } from "./setup-surface-Bc36YSS3.js";
2
2
  export { lineSetupAdapter, lineSetupWizard };
@@ -1,4 +1,4 @@
1
- import { i as resolveLineAccount, n as normalizeAccountId, r as resolveDefaultLineAccountId, t as listLineAccountIds } from "./accounts-B-K3yrdP.js";
1
+ import { i as resolveLineAccount, n as normalizeAccountId, r as resolveDefaultLineAccountId, t as listLineAccountIds } from "./accounts-DJVOv1JI.js";
2
2
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  import { DEFAULT_ACCOUNT_ID, createAllowFromSection, createSetupInputPresenceValidator, createSetupTranslator, createStandardChannelSetupStatus, formatDocsLink, mergeAllowFromEntries, setSetupChannelEnabled, splitSetupEntries } from "openclaw/plugin-sdk/setup";
4
4
  //#region extensions/line/src/account-helpers.ts