@openclaw/line 2026.8.1-beta.3 → 2026.8.2

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 (156) hide show
  1. package/dist/account-helpers-BSUyZwLm.js +12 -0
  2. package/dist/{accounts-BqEVsDoB.js → accounts-BBEFMYbY.js} +2 -1
  3. package/dist/api.js +2 -2
  4. package/dist/card-command-DS6A5V6o.js +252 -0
  5. package/dist/{channel-DmoKZXmG.js → channel-CLCy4jAa.js} +97 -357
  6. package/dist/channel-plugin-api.js +1 -1
  7. package/dist/channel.runtime-Ih7sq1GN.js +4 -0
  8. package/dist/contract-api.js +1 -1
  9. package/dist/doctor-contract-api.js +141 -0
  10. package/dist/index.js +5 -17
  11. package/dist/{markdown-to-line-rEaras_0.js → markdown-to-line--jytmFan.js} +36 -29
  12. package/dist/{monitor-BYXS_B6r.js → monitor-CSpwQCBI.js} +292 -194
  13. package/dist/monitor.runtime-CV8EjkIT.js +2 -0
  14. package/dist/outbound.runtime-DLqcz_BQ.js +3 -0
  15. package/dist/probe.runtime-DTxBWvKz.js +2 -0
  16. package/dist/rich-messages-CIP7xn5E.js +761 -0
  17. package/dist/runtime-api.js +12 -13
  18. package/dist/{send-receipt-DKZzgHMO.js → send-retry-CUvrarfE.js} +137 -413
  19. package/dist/{send-BJCeiiOB.js → send-wVUV00WS.js} +150 -109
  20. package/dist/setup-api.js +1 -1
  21. package/dist/{setup-surface-W0Dbgu58.js → setup-surface-CDlgkTKi.js} +47 -39
  22. package/dist/webhook-spool-contract-1rY8OJw8.js +59 -0
  23. package/node_modules/typebox/build/format/date.d.mts +1 -1
  24. package/node_modules/typebox/build/format/date.mjs +1 -1
  25. package/node_modules/typebox/build/format/date_time.d.mts +2 -2
  26. package/node_modules/typebox/build/format/date_time.mjs +3 -3
  27. package/node_modules/typebox/build/format/email.d.mts +1 -1
  28. package/node_modules/typebox/build/format/email.mjs +2 -2
  29. package/node_modules/typebox/build/format/hostname.mjs +2 -10
  30. package/node_modules/typebox/build/format/idn_email.d.mts +1 -1
  31. package/node_modules/typebox/build/format/idn_email.mjs +3 -3
  32. package/node_modules/typebox/build/format/idn_hostname.d.mts +1 -0
  33. package/node_modules/typebox/build/format/idn_hostname.mjs +3 -11
  34. package/node_modules/typebox/build/format/idna/format/bidi.d.mts +3 -0
  35. package/node_modules/typebox/build/format/idna/format/bidi.mjs +98 -0
  36. package/node_modules/typebox/build/format/idna/format/puny.d.mts +3 -0
  37. package/node_modules/typebox/build/format/idna/format/puny.mjs +144 -0
  38. package/node_modules/typebox/build/format/idna/hostname.d.mts +1 -0
  39. package/node_modules/typebox/build/format/idna/hostname.mjs +16 -0
  40. package/node_modules/typebox/build/format/idna/idn-hostname.d.mts +1 -0
  41. package/node_modules/typebox/build/format/idna/idn-hostname.mjs +41 -0
  42. package/node_modules/typebox/build/format/idna/index.d.mts +2 -0
  43. package/node_modules/typebox/build/format/idna/index.mjs +2 -0
  44. package/node_modules/typebox/build/format/idna/label/ascii.d.mts +1 -0
  45. package/node_modules/typebox/build/format/idna/label/ascii.mjs +9 -0
  46. package/node_modules/typebox/build/format/idna/label/puny.d.mts +1 -0
  47. package/node_modules/typebox/build/format/idna/label/puny.mjs +28 -0
  48. package/node_modules/typebox/build/format/idna/label/unicode.d.mts +1 -0
  49. package/node_modules/typebox/build/format/idna/label/unicode.mjs +106 -0
  50. package/node_modules/typebox/build/format/idna/pattern/pattern.d.mts +30 -0
  51. package/node_modules/typebox/build/format/idna/pattern/pattern.mjs +70 -0
  52. package/node_modules/typebox/build/format/ipv4.d.mts +0 -1
  53. package/node_modules/typebox/build/format/ipv4.mjs +2 -32
  54. package/node_modules/typebox/build/format/ipv6.mjs +2 -61
  55. package/node_modules/typebox/build/format/iri.d.mts +2 -2
  56. package/node_modules/typebox/build/format/iri.mjs +26 -8
  57. package/node_modules/typebox/build/format/iri_reference.d.mts +2 -2
  58. package/node_modules/typebox/build/format/iri_reference.mjs +9 -55
  59. package/node_modules/typebox/build/format/regex.d.mts +1 -2
  60. package/node_modules/typebox/build/format/regex.mjs +2 -6
  61. package/node_modules/typebox/build/format/time.d.mts +2 -2
  62. package/node_modules/typebox/build/format/time.mjs +19 -14
  63. package/node_modules/typebox/build/format/uri.d.mts +1 -1
  64. package/node_modules/typebox/build/format/uri.mjs +3 -130
  65. package/node_modules/typebox/build/format/uri_reference.d.mts +1 -1
  66. package/node_modules/typebox/build/format/uri_reference.mjs +2 -3
  67. package/node_modules/typebox/build/format/uri_template.d.mts +2 -3
  68. package/node_modules/typebox/build/format/uri_template.mjs +4 -5
  69. package/node_modules/typebox/build/format/url.d.mts +3 -3
  70. package/node_modules/typebox/build/format/url.mjs +4 -5
  71. package/node_modules/typebox/build/guard/emit.d.mts +3 -1
  72. package/node_modules/typebox/build/guard/emit.mjs +12 -5
  73. package/node_modules/typebox/build/guard/guard.d.mts +8 -2
  74. package/node_modules/typebox/build/guard/guard.mjs +25 -4
  75. package/node_modules/typebox/build/guard/string.d.mts +2 -2
  76. package/node_modules/typebox/build/guard/string.mjs +7 -7
  77. package/node_modules/typebox/build/schema/engine/_context.mjs +3 -3
  78. package/node_modules/typebox/build/schema/engine/_functions.mjs +1 -2
  79. package/node_modules/typebox/build/schema/engine/_regexp.d.mts +2 -0
  80. package/node_modules/typebox/build/schema/engine/_regexp.mjs +4 -0
  81. package/node_modules/typebox/build/schema/engine/_stack.mjs +12 -13
  82. package/node_modules/typebox/build/schema/engine/additionalItems.mjs +17 -7
  83. package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +4 -3
  84. package/node_modules/typebox/build/schema/engine/contains.mjs +18 -6
  85. package/node_modules/typebox/build/schema/engine/enum.mjs +1 -1
  86. package/node_modules/typebox/build/schema/engine/items.mjs +26 -6
  87. package/node_modules/typebox/build/schema/engine/maxContains.mjs +3 -3
  88. package/node_modules/typebox/build/schema/engine/minContains.mjs +14 -4
  89. package/node_modules/typebox/build/schema/engine/not.mjs +4 -2
  90. package/node_modules/typebox/build/schema/engine/oneOf.mjs +7 -6
  91. package/node_modules/typebox/build/schema/engine/pattern.mjs +3 -2
  92. package/node_modules/typebox/build/schema/engine/patternProperties.mjs +4 -3
  93. package/node_modules/typebox/build/schema/engine/ref.mjs +1 -7
  94. package/node_modules/typebox/build/schema/engine/schema.mjs +13 -4
  95. package/node_modules/typebox/build/schema/engine/type.mjs +1 -1
  96. package/node_modules/typebox/build/schema/resolve/resolve.d.mts +4 -1
  97. package/node_modules/typebox/build/schema/resolve/resolve.mjs +202 -1
  98. package/node_modules/typebox/build/schema/static/propertyNames.d.mts +5 -0
  99. package/node_modules/typebox/build/schema/static/propertyNames.mjs +3 -0
  100. package/node_modules/typebox/build/schema/static/schema.d.mts +3 -0
  101. package/node_modules/typebox/build/schema/types/index.d.mts +0 -2
  102. package/node_modules/typebox/build/schema/types/index.mjs +0 -2
  103. package/node_modules/typebox/build/system/memory/clone.mjs +14 -11
  104. package/node_modules/typebox/build/system/memory/discard.mjs +6 -5
  105. package/node_modules/typebox/build/system/settings/settings.d.mts +9 -0
  106. package/node_modules/typebox/build/system/settings/settings.mjs +2 -0
  107. package/node_modules/typebox/build/type/engine/call/distribute_arguments.d.mts +6 -1
  108. package/node_modules/typebox/build/type/engine/call/distribute_arguments.mjs +16 -3
  109. package/node_modules/typebox/build/type/engine/call/instantiate.mjs +34 -4
  110. package/node_modules/typebox/build/type/engine/evaluate/broaden.d.mts +5 -5
  111. package/node_modules/typebox/build/type/engine/evaluate/broaden.mjs +20 -26
  112. package/node_modules/typebox/build/type/engine/evaluate/compare.d.mts +6 -10
  113. package/node_modules/typebox/build/type/engine/evaluate/compare.mjs +9 -13
  114. package/node_modules/typebox/build/type/engine/evaluate/composite.d.mts +7 -4
  115. package/node_modules/typebox/build/type/engine/evaluate/composite.mjs +12 -19
  116. package/node_modules/typebox/build/type/engine/evaluate/distribute.d.mts +4 -20
  117. package/node_modules/typebox/build/type/engine/evaluate/distribute.mjs +8 -20
  118. package/node_modules/typebox/build/type/engine/evaluate/evaluate.d.mts +4 -4
  119. package/node_modules/typebox/build/type/engine/evaluate/evaluate.mjs +11 -8
  120. package/node_modules/typebox/build/type/engine/evaluate/flatten.d.mts +1 -1
  121. package/node_modules/typebox/build/type/engine/evaluate/flatten.mjs +3 -4
  122. package/node_modules/typebox/build/type/engine/evaluate/narrow.d.mts +17 -2
  123. package/node_modules/typebox/build/type/engine/evaluate/narrow.mjs +26 -6
  124. package/node_modules/typebox/build/type/engine/exclude/operation.mjs +3 -4
  125. package/node_modules/typebox/build/type/engine/extract/operation.d.mts +1 -1
  126. package/node_modules/typebox/build/type/engine/extract/operation.mjs +3 -4
  127. package/node_modules/typebox/build/type/engine/priority/priority.d.mts +2 -2
  128. package/node_modules/typebox/build/type/engine/priority/priority.mjs +3 -4
  129. package/node_modules/typebox/build/type/script/mapping.d.mts +32 -29
  130. package/node_modules/typebox/build/type/script/mapping.mjs +18 -25
  131. package/node_modules/typebox/build/type/script/parser.d.mts +19 -25
  132. package/node_modules/typebox/build/type/script/parser.mjs +27 -23
  133. package/node_modules/typebox/build/value/errors/errors.d.mts +2 -2
  134. package/node_modules/typebox/build/value/errors/errors.mjs +1 -1
  135. package/node_modules/typebox/package.json +27 -27
  136. package/node_modules/typebox/readme.md +79 -82
  137. package/openclaw.plugin.json +26 -2
  138. package/package.json +6 -6
  139. package/dist/card-command-CyDSm-OU.js +0 -224
  140. package/dist/channel.runtime-qrUV6wPE.js +0 -4
  141. package/dist/config-schema-Be3azjB_.js +0 -47
  142. package/dist/monitor.runtime-B2z_5ugU.js +0 -2
  143. package/dist/outbound.runtime-DDTeqaBW.js +0 -3
  144. package/dist/probe.runtime-D13ZtXsd.js +0 -2
  145. package/dist/quick-reply-fallback-D86FwAfr.js +0 -56
  146. package/node_modules/typebox/build/format/_idna.d.mts +0 -2
  147. package/node_modules/typebox/build/format/_idna.mjs +0 -246
  148. package/node_modules/typebox/build/format/_puny.d.mts +0 -1
  149. package/node_modules/typebox/build/format/_puny.mjs +0 -77
  150. package/node_modules/typebox/build/schema/resolve/ref.d.mts +0 -3
  151. package/node_modules/typebox/build/schema/resolve/ref.mjs +0 -146
  152. package/node_modules/typebox/build/schema/types/contentEncoding.d.mts +0 -9
  153. package/node_modules/typebox/build/schema/types/contentEncoding.mjs +0 -13
  154. package/node_modules/typebox/build/schema/types/contentMediaType.d.mts +0 -9
  155. package/node_modules/typebox/build/schema/types/contentMediaType.mjs +0 -13
  156. package/dist/{probe-CM03wo6r.js → probe-4gc_YQ2L.js} +1 -1
@@ -1,26 +1,24 @@
1
- import { i as resolveLineAccount, r as resolveDefaultLineAccountId, t as listLineAccountIds } from "./accounts-BqEVsDoB.js";
2
- import { i as hasLineCredentials, r as lineSetupContract, t as lineSetupWizard } from "./setup-surface-W0Dbgu58.js";
3
- import { i as resolveExactLineGroupConfigKey, n as getLineRuntime, t as buildLineQuickReplyFallbackText } from "./quick-reply-fallback-D86FwAfr.js";
4
- import { t as LineChannelConfigSchema } from "./config-schema-Be3azjB_.js";
5
- import { _ as uriAction, a as createAgendaCard, b as resolveLineOutboundMedia, c as createActionCard, g as postbackAction, i as createMediaPlayerCard, n as createAppleTvRemoteCard, o as createEventCard, p as messageAction, r as createDeviceControlCard, t as createLineSendReceipt, v as buildLineMediaMessage, y as hasLineSpecificMediaOptions } from "./send-receipt-DKZzgHMO.js";
1
+ import { i as resolveLineAccount, r as resolveDefaultLineAccountId, t as listLineAccountIds } from "./accounts-BBEFMYbY.js";
2
+ import { t as hasLineCredentials } from "./account-helpers-BSUyZwLm.js";
3
+ import { _ as LineChannelConfigSchema, a as renderLineCard, d as resolveExactLineGroupConfigKey, h as getLineRuntime, n as createLineQuickReply, o as renderLinePresentation, p as resolveLineGroupLookupIds, r as lineMessageActions, t as LINE_PRESENTATION_CAPABILITIES, u as buildLineQuickReplyFallbackText } from "./rich-messages-CIP7xn5E.js";
4
+ import { i as createLineSendReceipt, n as resolveLineNonDispatchRetryable, y as buildLineMediaMessage } from "./send-retry-CUvrarfE.js";
5
+ import { r as lineSetupContract, t as lineSetupWizard } from "./setup-surface-CDlgkTKi.js";
6
6
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
7
7
  import { buildDmGroupAccountAllowlistAdapter, createFlatAllowlistOverrideResolver } from "openclaw/plugin-sdk/allowlist-config-edit";
8
8
  import { buildChannelOutboundSessionRoute, createChatChannelPlugin } from "openclaw/plugin-sdk/channel-core";
9
9
  import { createPairingPrefixStripper } from "openclaw/plugin-sdk/channel-pairing";
10
10
  import { buildChannelGroupsScopeTree, createRestrictSendersChannelSecurity, resolveScopeRequireMention } from "openclaw/plugin-sdk/channel-policy";
11
- import { createEmptyChannelDirectoryAdapter } from "openclaw/plugin-sdk/directory-runtime";
11
+ import { createChannelDirectoryAdapter, createResolvedDirectoryEntriesLister } from "openclaw/plugin-sdk/directory-runtime";
12
12
  import { describeWebhookAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
13
- import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1 } from "openclaw/plugin-sdk/account-id";
14
- import { createScopedChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
15
- import { isRecord, normalizeLowercaseStringOrEmpty, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
16
- import { clearAccountEntryFields } from "openclaw/plugin-sdk/core";
13
+ import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
14
+ import { clearAccountFieldsFromConfigSection, createScopedChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
15
+ import { normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
17
16
  import { createAccountStatusSink, defineChannelMessageAdapter, listMessageReceiptPlatformIds } from "openclaw/plugin-sdk/channel-outbound";
18
- import { createChannelPartialDeliveryError } from "openclaw/plugin-sdk/channel-inbound";
17
+ import { createChannelPartialDeliveryError, isChannelPartialDeliveryError } from "openclaw/plugin-sdk/channel-inbound";
19
18
  import { createAttachedChannelResultAdapter, createEmptyChannelResult } from "openclaw/plugin-sdk/channel-send-result";
19
+ import { PlatformMessageNotDispatchedError } from "openclaw/plugin-sdk/error-runtime";
20
20
  import { resolveOutboundMediaUrls } from "openclaw/plugin-sdk/reply-payload";
21
21
  import { sanitizeAssistantVisibleText } from "openclaw/plugin-sdk/text-chunking";
22
- import { resolveMessagePresentationButtonAction, resolveMessagePresentationOptionAction } from "openclaw/plugin-sdk/interactive-runtime";
23
- import { Type } from "typebox";
24
22
  import { buildTokenChannelStatusSummary, createComputedAccountStatusAdapter, createDefaultChannelRuntimeState, createDependentCredentialStatusIssueCollector } from "openclaw/plugin-sdk/status-helpers";
25
23
  //#region extensions/line/src/bindings.ts
26
24
  function normalizeLineConversationId(raw) {
@@ -121,8 +119,8 @@ const lineChannelPluginCommon = {
121
119
  };
122
120
  //#endregion
123
121
  //#region extensions/line/src/gateway.ts
124
- const loadLineProbeRuntime$1 = createLazyRuntimeModule(() => import("./probe.runtime-D13ZtXsd.js"));
125
- const loadLineMonitorRuntime = createLazyRuntimeModule(() => import("./monitor.runtime-B2z_5ugU.js"));
122
+ const loadLineProbeRuntime$1 = createLazyRuntimeModule(() => import("./probe.runtime-DTxBWvKz.js"));
123
+ const loadLineMonitorRuntime = createLazyRuntimeModule(() => import("./monitor.runtime-CV8EjkIT.js"));
126
124
  const lineGatewayAdapter = {
127
125
  startAccount: async (ctx) => {
128
126
  const account = ctx.account;
@@ -158,22 +156,9 @@ const lineGatewayAdapter = {
158
156
  },
159
157
  logoutAccount: async ({ accountId, cfg }) => {
160
158
  const envToken = process.env.LINE_CHANNEL_ACCESS_TOKEN?.trim() ?? "";
161
- const nextCfg = { ...cfg };
162
- const nextLine = { ...cfg.channels?.line ?? {} };
163
- let cleared = false;
164
- let changed = false;
165
- if (accountId === DEFAULT_ACCOUNT_ID$1) {
166
- if (nextLine.channelAccessToken || nextLine.channelSecret || nextLine.tokenFile || nextLine.secretFile) {
167
- delete nextLine.channelAccessToken;
168
- delete nextLine.channelSecret;
169
- delete nextLine.tokenFile;
170
- delete nextLine.secretFile;
171
- cleared = true;
172
- changed = true;
173
- }
174
- }
175
- const accountCleanup = clearAccountEntryFields({
176
- accounts: nextLine.accounts,
159
+ const { nextConfig, changed, cleared } = clearAccountFieldsFromConfigSection({
160
+ cfg,
161
+ sectionKey: "line",
177
162
  accountId,
178
163
  fields: [
179
164
  "channelAccessToken",
@@ -183,30 +168,12 @@ const lineGatewayAdapter = {
183
168
  ],
184
169
  markClearedOnFieldPresence: true
185
170
  });
186
- if (accountCleanup.changed) {
187
- changed = true;
188
- if (accountCleanup.cleared) cleared = true;
189
- if (accountCleanup.nextAccounts) nextLine.accounts = accountCleanup.nextAccounts;
190
- else delete nextLine.accounts;
191
- }
192
- if (changed) {
193
- if (Object.keys(nextLine).length > 0) nextCfg.channels = {
194
- ...nextCfg.channels,
195
- line: nextLine
196
- };
197
- else {
198
- const nextChannels = { ...nextCfg.channels };
199
- delete nextChannels.line;
200
- if (Object.keys(nextChannels).length > 0) nextCfg.channels = nextChannels;
201
- else delete nextCfg.channels;
202
- }
203
- await getLineRuntime().config.replaceConfigFile({
204
- nextConfig: nextCfg,
205
- afterWrite: { mode: "auto" }
206
- });
207
- }
171
+ if (changed) await getLineRuntime().config.replaceConfigFile({
172
+ nextConfig,
173
+ afterWrite: { mode: "auto" }
174
+ });
208
175
  const loggedOut = resolveLineAccount({
209
- cfg: changed ? nextCfg : cfg,
176
+ cfg: nextConfig,
210
177
  accountId
211
178
  }).tokenSource === "none";
212
179
  return {
@@ -243,234 +210,8 @@ function inferLineTargetChatType(target) {
243
210
  return /^[CR][a-f0-9]{32}$/i.test(normalized) ? "group" : void 0;
244
211
  }
245
212
  //#endregion
246
- //#region extensions/line/src/rich-messages.ts
247
- const nonempty = () => Type.String({ minLength: 1 });
248
- const closed = (properties) => Type.Object(properties, { additionalProperties: false });
249
- const lineCardSchema = Type.Union([
250
- closed({
251
- type: Type.Literal("media_player"),
252
- title: nonempty(),
253
- artist: Type.Optional(nonempty()),
254
- source: Type.Optional(nonempty()),
255
- imageUrl: Type.Optional(Type.String({ pattern: "^https://" })),
256
- status: Type.Optional(Type.Union([Type.Literal("playing"), Type.Literal("paused")]))
257
- }),
258
- closed({
259
- type: Type.Literal("event"),
260
- title: nonempty(),
261
- date: nonempty(),
262
- time: Type.Optional(nonempty()),
263
- location: Type.Optional(nonempty()),
264
- description: Type.Optional(nonempty())
265
- }),
266
- closed({
267
- type: Type.Literal("agenda"),
268
- title: nonempty(),
269
- events: Type.Array(closed({
270
- title: nonempty(),
271
- time: Type.Optional(nonempty()),
272
- location: Type.Optional(nonempty())
273
- }), {
274
- minItems: 1,
275
- maxItems: 6
276
- })
277
- }),
278
- closed({
279
- type: Type.Literal("device"),
280
- name: nonempty(),
281
- deviceType: Type.Optional(nonempty()),
282
- status: Type.Optional(nonempty()),
283
- controls: Type.Optional(Type.Array(closed({
284
- label: nonempty(),
285
- action: nonempty()
286
- }), { maxItems: 6 }))
287
- }),
288
- closed({
289
- type: Type.Literal("appletv_remote"),
290
- name: Type.Optional(nonempty()),
291
- status: Type.Optional(nonempty())
292
- })
293
- ]);
294
- const lineChannelDataSchema = Type.Optional(closed({ line: closed({
295
- location: Type.Optional(closed({
296
- title: nonempty(),
297
- address: nonempty(),
298
- latitude: Type.Number({
299
- minimum: -90,
300
- maximum: 90
301
- }),
302
- longitude: Type.Number({
303
- minimum: -180,
304
- maximum: 180
305
- })
306
- })),
307
- card: Type.Optional(lineCardSchema),
308
- mediaKind: Type.Optional(Type.Union([
309
- Type.Literal("image"),
310
- Type.Literal("video"),
311
- Type.Literal("audio")
312
- ])),
313
- previewImageUrl: Type.Optional(Type.String({ pattern: "^https://" })),
314
- durationMs: Type.Optional(Type.Integer({ minimum: 1 })),
315
- trackingId: Type.Optional(nonempty())
316
- }) }));
317
- const lineMessageActions = {
318
- describeMessageTool: ({ cfg, accountId }) => {
319
- const account = resolveLineAccount({
320
- cfg,
321
- accountId: accountId ?? void 0
322
- });
323
- return account.enabled && hasLineCredentials(account) ? {
324
- actions: ["send"],
325
- capabilities: ["presentation"],
326
- schema: {
327
- actions: ["send"],
328
- properties: { channelData: lineChannelDataSchema }
329
- }
330
- } : {
331
- actions: [],
332
- capabilities: [],
333
- schema: null
334
- };
335
- },
336
- prepareSendPayload: ({ payload }) => payload
337
- };
338
- const LINE_PRESENTATION_CAPABILITIES = {
339
- supported: true,
340
- buttons: true,
341
- selects: true,
342
- context: true,
343
- limits: {
344
- actions: {
345
- maxActions: 4,
346
- maxActionsPerRow: 1,
347
- maxRows: 4,
348
- maxLabelLength: 40
349
- },
350
- selects: {
351
- maxOptions: 13,
352
- maxLabelLength: 20,
353
- maxValueBytes: 300
354
- },
355
- text: { markdownDialect: "plain" }
356
- }
357
- };
358
- function toLineAction(button) {
359
- const normalized = resolveMessagePresentationButtonAction(button);
360
- if (normalized?.type === "command") return messageAction(button.label, normalized.command);
361
- if (normalized?.type === "callback") return postbackAction(button.label, normalized.value, button.label);
362
- if (normalized?.type === "url") return uriAction(button.label, normalized.url);
363
- if (normalized?.type === "web-app" && normalized.url) return uriAction(button.label, normalized.url);
364
- }
365
- function renderLinePresentation(payload, presentation) {
366
- const buttons = presentation.blocks.flatMap((block) => block.type === "buttons" ? block.buttons : []);
367
- const buttonActions = buttons.map(toLineAction);
368
- const options = presentation.blocks.flatMap((block) => block.type === "select" ? block.options : []);
369
- const quickReplyItems = options.flatMap((option) => {
370
- const action = resolveMessagePresentationOptionAction(option);
371
- return action?.type === "command" || action?.type === "callback" ? [{
372
- label: option.label,
373
- action
374
- }] : [];
375
- });
376
- if (buttons.length > 0 && buttonActions.some((action) => !action) || quickReplyItems.length !== options.length || buttons.length === 0 && options.length === 0) return null;
377
- const lineData = isRecord(payload.channelData?.line) ? payload.channelData.line : {};
378
- const text = presentation.blocks.flatMap((block) => block.type === "text" || block.type === "context" ? [block.text] : []).join("\n");
379
- const title = presentation.title || "Choose an option";
380
- const flexMessage = buttonActions.length > 0 ? {
381
- altText: title,
382
- contents: createActionCard(title, text || "Choose an option.", buttons.map((button, index) => ({
383
- label: button.label,
384
- action: buttonActions[index]
385
- })))
386
- } : void 0;
387
- return {
388
- ...payload,
389
- channelData: {
390
- ...payload.channelData,
391
- line: {
392
- ...lineData,
393
- ...flexMessage ? { flexMessage } : {},
394
- quickReplyItems
395
- }
396
- }
397
- };
398
- }
399
- const toSlug = (value) => normalizeLowercaseStringOrEmpty(value).replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "") || "device";
400
- const lineActionData = (action, device) => `line.action=${encodeURIComponent(action)}&line.device=${encodeURIComponent(device)}`;
401
- function renderLineCard(card) {
402
- if (card.type === "media_player") {
403
- const device = toSlug(card.source || card.title);
404
- return {
405
- altText: `🎵 ${card.title}${card.artist ? ` - ${card.artist}` : ""}`,
406
- contents: createMediaPlayerCard({
407
- title: card.title,
408
- subtitle: card.artist,
409
- source: card.source,
410
- imageUrl: card.imageUrl,
411
- isPlaying: card.status ? card.status === "playing" : void 0,
412
- controls: Object.fromEntries([
413
- "previous",
414
- "play",
415
- "pause",
416
- "next"
417
- ].map((action) => [action, { data: lineActionData(action, device) }]))
418
- })
419
- };
420
- }
421
- if (card.type === "event") return {
422
- altText: `📅 ${card.title} - ${card.date}${card.time ? ` ${card.time}` : ""}`,
423
- contents: createEventCard(card)
424
- };
425
- if (card.type === "agenda") return {
426
- altText: `📋 ${card.title} (${card.events.length} events)`,
427
- contents: createAgendaCard(card)
428
- };
429
- const device = toSlug(card.type === "device" ? card.name : card.name || "apple_tv");
430
- if (card.type === "device") return {
431
- altText: `📱 ${card.name}${card.status ? `: ${card.status}` : ""}`,
432
- contents: createDeviceControlCard({
433
- deviceName: card.name,
434
- deviceType: card.deviceType,
435
- status: card.status,
436
- controls: (card.controls ?? []).map((control) => ({
437
- label: control.label,
438
- data: lineActionData(control.action, device)
439
- }))
440
- })
441
- };
442
- const actionData = {
443
- up: lineActionData("up", device),
444
- down: lineActionData("down", device),
445
- left: lineActionData("left", device),
446
- right: lineActionData("right", device),
447
- select: lineActionData("select", device),
448
- menu: lineActionData("menu", device),
449
- home: lineActionData("home", device),
450
- play: lineActionData("play", device),
451
- pause: lineActionData("pause", device),
452
- volumeUp: lineActionData("volume_up", device),
453
- volumeDown: lineActionData("volume_down", device),
454
- mute: lineActionData("mute", device)
455
- };
456
- return {
457
- altText: `📺 ${card.name || "Apple TV"} Remote`,
458
- contents: createAppleTvRemoteCard({
459
- deviceName: card.name || "Apple TV",
460
- status: card.status,
461
- actionData
462
- })
463
- };
464
- }
465
- function createLineQuickReply(items) {
466
- return { items: items.slice(0, 13).map((item) => ({
467
- type: "action",
468
- action: item.action.type === "command" ? messageAction(item.label, item.action.command) : postbackAction(item.label, item.action.value, item.label)
469
- })) };
470
- }
471
- //#endregion
472
213
  //#region extensions/line/src/outbound.ts
473
- const loadLineOutboundRuntime = createLazyRuntimeModule(() => import("./outbound.runtime-DDTeqaBW.js"));
214
+ const loadLineOutboundRuntime = createLazyRuntimeModule(() => import("./outbound.runtime-DLqcz_BQ.js"));
474
215
  const lineOutboundAdapter = {
475
216
  deliveryMode: "direct",
476
217
  chunker: (text, limit) => getLineRuntime().channel.text.chunkMarkdownText(text, limit),
@@ -496,9 +237,23 @@ const lineOutboundAdapter = {
496
237
  const sendLocation = lineRuntime?.pushLocationMessage ?? outboundRuntime.pushLocationMessage;
497
238
  const sendQuickReplies = lineRuntime?.pushTextMessageWithQuickReplies ?? outboundRuntime.pushTextMessageWithQuickReplies;
498
239
  const buildTemplate = lineRuntime?.buildTemplateMessageFromPayload ?? outboundRuntime.buildTemplateMessageFromPayload;
240
+ const sendOptions = {
241
+ verbose: false,
242
+ cfg,
243
+ accountId: accountId ?? void 0
244
+ };
499
245
  let lastResult = null;
500
246
  const recordResult = async (resultPromise) => {
501
- const result = await resultPromise;
247
+ let result;
248
+ try {
249
+ result = await resultPromise;
250
+ } catch (error) {
251
+ const retryable = isChannelPartialDeliveryError(error) ? void 0 : resolveLineNonDispatchRetryable(error);
252
+ throw lastResult === null && retryable !== void 0 ? new PlatformMessageNotDispatchedError(error instanceof Error ? error.message : "LINE rejected the message", {
253
+ cause: error,
254
+ retryable
255
+ }) : error;
256
+ }
502
257
  lastResult = result;
503
258
  try {
504
259
  await onDeliveryResult?.(createEmptyChannelResult("line", { ...result }));
@@ -520,11 +275,7 @@ const lineOutboundAdapter = {
520
275
  if (messages.length === 0) return;
521
276
  for (let i = 0; i < messages.length; i += 5) {
522
277
  const batch = messages.slice(i, i + 5);
523
- await recordResult(sendBatch(to, batch, {
524
- verbose: false,
525
- cfg,
526
- accountId: accountId ?? void 0
527
- }));
278
+ await recordResult(sendBatch(to, batch, sendOptions));
528
279
  }
529
280
  };
530
281
  const sendTextWithQuickReply = async (text) => {
@@ -536,11 +287,7 @@ const lineOutboundAdapter = {
536
287
  }]);
537
288
  return;
538
289
  }
539
- await recordResult(sendQuickReplies(to, text, quickReplies, {
540
- verbose: false,
541
- cfg,
542
- accountId: accountId ?? void 0
543
- }));
290
+ await recordResult(sendQuickReplies(to, text, quickReplies, sendOptions));
544
291
  };
545
292
  const processed = payload.text ? outboundRuntime.processLineMessage(payload.text) : {
546
293
  text: "",
@@ -553,9 +300,8 @@ const lineOutboundAdapter = {
553
300
  })));
554
301
  const chunks = orderedMessages ? orderedMessages.flatMap((message) => message.type === "text" ? [message.text] : []) : processed.text ? runtime.channel.text.chunkMarkdownText(processed.text, chunkLimit) : [];
555
302
  const mediaUrls = resolveOutboundMediaUrls(payload);
556
- const useLineSpecificMedia = hasLineSpecificMediaOptions(lineData);
557
303
  const mediaOptions = {
558
- mediaKind: useLineSpecificMedia ? lineData.mediaKind : "image",
304
+ mediaKind: lineData.mediaKind,
559
305
  previewImageUrl: lineData.previewImageUrl,
560
306
  durationMs: lineData.durationMs,
561
307
  trackingId: lineData.trackingId
@@ -565,82 +311,40 @@ const lineOutboundAdapter = {
565
311
  for (const url of mediaUrls) {
566
312
  const trimmed = url?.trim();
567
313
  if (!trimmed) continue;
568
- if (!useLineSpecificMedia) {
569
- await recordResult((lineRuntime?.sendMessageLine ?? outboundRuntime.sendMessageLine)(to, "", {
570
- verbose: false,
571
- mediaUrl: trimmed,
572
- cfg,
573
- accountId: accountId ?? void 0
574
- }));
575
- continue;
576
- }
577
- const resolved = await resolveLineOutboundMedia(trimmed, mediaOptions);
578
314
  await recordResult((lineRuntime?.sendMessageLine ?? outboundRuntime.sendMessageLine)(to, "", {
579
- verbose: false,
580
- mediaUrl: resolved.mediaUrl,
581
- mediaKind: resolved.mediaKind,
582
- previewImageUrl: resolved.previewImageUrl,
583
- durationMs: resolved.durationMs,
584
- trackingId: resolved.trackingId,
585
- cfg,
586
- accountId: accountId ?? void 0
315
+ ...sendOptions,
316
+ ...mediaOptions,
317
+ mediaUrl: trimmed
587
318
  }));
588
319
  }
589
320
  };
590
321
  if (!shouldSendQuickRepliesInline) {
591
322
  if (lineData.flexMessage) {
592
323
  const flexContents = lineData.flexMessage.contents;
593
- await recordResult(sendFlex(to, lineData.flexMessage.altText, flexContents, {
594
- verbose: false,
595
- cfg,
596
- accountId: accountId ?? void 0
597
- }));
324
+ await recordResult(sendFlex(to, lineData.flexMessage.altText, flexContents, sendOptions));
598
325
  }
599
326
  if (lineData.templateMessage) {
600
327
  const template = buildTemplate(lineData.templateMessage);
601
- if (template) await recordResult(sendTemplate(to, template, {
602
- verbose: false,
603
- cfg,
604
- accountId: accountId ?? void 0
605
- }));
328
+ if (template) await recordResult(sendTemplate(to, template, sendOptions));
606
329
  }
607
- if (location) await recordResult(sendLocation(to, location, {
608
- verbose: false,
609
- cfg,
610
- accountId: accountId ?? void 0
611
- }));
612
- if (!orderedMessages) for (const flexMsg of processed.flexMessages) await recordResult(sendFlex(to, flexMsg.altText, flexMsg.contents, {
613
- verbose: false,
614
- cfg,
615
- accountId: accountId ?? void 0
616
- }));
330
+ if (location) await recordResult(sendLocation(to, location, sendOptions));
331
+ if (!orderedMessages) for (const flexMsg of processed.flexMessages) await recordResult(sendFlex(to, flexMsg.altText, flexMsg.contents, sendOptions));
617
332
  }
618
333
  const sendMediaAfterText = !(hasQuickReplies && chunks.length > 0);
619
334
  if (mediaUrls.length > 0 && !shouldSendQuickRepliesInline && !sendMediaAfterText) await sendMediaMessages();
620
- if (orderedMessages) for (const [index, message] of orderedMessages.entries()) {
335
+ if (orderedMessages && !shouldSendQuickRepliesInline) for (const [index, message] of orderedMessages.entries()) {
621
336
  const isLast = index === orderedMessages.length - 1;
622
- if (message.type === "flex") if (isLast && quickReply) await sendMessageBatch([{
623
- ...message,
624
- quickReply
625
- }]);
626
- else await recordResult(sendFlex(to, message.altText, message.contents, {
627
- verbose: false,
628
- cfg,
629
- accountId: accountId ?? void 0
630
- }));
631
- else if (isLast && hasQuickReplies) await sendTextWithQuickReply(message.text);
632
- else await recordResult(sendText(to, message.text, {
633
- verbose: false,
634
- cfg,
635
- accountId: accountId ?? void 0
636
- }));
337
+ if (message.type === "flex") {
338
+ if (isLast && quickReply) await sendMessageBatch([{
339
+ ...message,
340
+ quickReply
341
+ }]);
342
+ else await recordResult(sendFlex(to, message.altText, message.contents, sendOptions));
343
+ } else if (isLast && hasQuickReplies) await sendTextWithQuickReply(message.text);
344
+ else await recordResult(sendText(to, message.text, sendOptions));
637
345
  }
638
346
  else if (chunks.length > 0) for (const [i, chunk] of chunks.entries()) if (i === chunks.length - 1 && hasQuickReplies) await sendTextWithQuickReply(chunk);
639
- else await recordResult(sendText(to, chunk, {
640
- verbose: false,
641
- cfg,
642
- accountId: accountId ?? void 0
643
- }));
347
+ else await recordResult(sendText(to, chunk, sendOptions));
644
348
  else if (shouldSendQuickRepliesInline) {
645
349
  const quickReplyMessages = [];
646
350
  if (lineData.flexMessage) quickReplyMessages.push(outboundRuntime.createFlexMessage(lineData.flexMessage.altText, lineData.flexMessage.contents));
@@ -740,7 +444,7 @@ const lineMessageAdapter = defineChannelMessageAdapter({
740
444
  });
741
445
  //#endregion
742
446
  //#region extensions/line/src/status.ts
743
- const loadLineProbeRuntime = createLazyRuntimeModule(() => import("./probe.runtime-D13ZtXsd.js"));
447
+ const loadLineProbeRuntime = createLazyRuntimeModule(() => import("./probe.runtime-DTxBWvKz.js"));
744
448
  const collectLineStatusIssues = createDependentCredentialStatusIssueCollector({
745
449
  channel: "line",
746
450
  dependencySourceKey: "tokenSource",
@@ -748,7 +452,7 @@ const collectLineStatusIssues = createDependentCredentialStatusIssueCollector({
748
452
  missingDependentMessage: "LINE channel secret not configured"
749
453
  });
750
454
  const lineStatusAdapter = createComputedAccountStatusAdapter({
751
- defaultRuntime: createDefaultChannelRuntimeState(DEFAULT_ACCOUNT_ID$1),
455
+ defaultRuntime: createDefaultChannelRuntimeState(DEFAULT_ACCOUNT_ID),
752
456
  collectStatusIssues: collectLineStatusIssues,
753
457
  buildChannelSummary: ({ snapshot }) => buildTokenChannelStatusSummary(snapshot),
754
458
  probeAccount: async ({ account, timeoutMs }) => await (await loadLineProbeRuntime()).probeLineBot(account.channelAccessToken, timeoutMs),
@@ -768,7 +472,7 @@ const lineStatusAdapter = createComputedAccountStatusAdapter({
768
472
  });
769
473
  //#endregion
770
474
  //#region extensions/line/src/channel.ts
771
- const loadLineChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime-qrUV6wPE.js"));
475
+ const loadLineChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime-Ih7sq1GN.js"));
772
476
  const lineSecurityAdapter = createRestrictSendersChannelSecurity({
773
477
  channelKey: "line",
774
478
  resolveDmPolicy: (account) => account.config.dmPolicy,
@@ -784,6 +488,10 @@ const lineSecurityAdapter = createRestrictSendersChannelSecurity({
784
488
  approveHint: "openclaw pairing approve line <code>",
785
489
  normalizeDmEntry: (raw) => raw.replace(/^line:(?:user:)?/i, "")
786
490
  });
491
+ function normalizeLineDirectoryId(entry, kind) {
492
+ const id = normalizeLineMessagingTarget(entry);
493
+ return id && inferLineTargetChatType(id) === kind ? id : null;
494
+ }
787
495
  const linePlugin = createChatChannelPlugin({
788
496
  base: {
789
497
  id: "line",
@@ -845,10 +553,42 @@ const linePlugin = createChatChannelPlugin({
845
553
  hint: "<userId|groupId|roomId>"
846
554
  }
847
555
  },
848
- directory: createEmptyChannelDirectoryAdapter(),
556
+ directory: createChannelDirectoryAdapter({
557
+ listPeers: createResolvedDirectoryEntriesLister({
558
+ kind: "user",
559
+ resolveAccount: (cfg, accountId) => resolveLineAccount({
560
+ cfg,
561
+ accountId: accountId ?? void 0
562
+ }),
563
+ resolveSources: ({ config }) => [
564
+ config.allowFrom ?? [],
565
+ config.groupAllowFrom ?? [],
566
+ ...Object.values(config.groups ?? {}).map((group) => group?.allowFrom ?? [])
567
+ ],
568
+ normalizeId: (entry) => normalizeLineDirectoryId(entry, "direct")
569
+ }),
570
+ listGroups: createResolvedDirectoryEntriesLister({
571
+ kind: "group",
572
+ resolveAccount: (cfg, accountId) => resolveLineAccount({
573
+ cfg,
574
+ accountId: accountId ?? void 0
575
+ }),
576
+ resolveSources: ({ config }) => [Object.keys(config.groups ?? {})],
577
+ normalizeId: (entry) => normalizeLineDirectoryId(resolveLineGroupLookupIds(entry)[0] ?? "", "group")
578
+ })
579
+ }),
849
580
  setupContract: lineSetupContract,
850
581
  status: lineStatusAdapter,
851
582
  gateway: lineGatewayAdapter,
583
+ heartbeat: { sendTyping: async ({ cfg, to, accountId }) => {
584
+ const chatId = normalizeLineMessagingTarget(to);
585
+ if (!chatId || inferLineTargetChatType(chatId) !== "direct") return;
586
+ const { showLoadingAnimation } = await loadLineChannelRuntime();
587
+ await showLoadingAnimation(chatId, {
588
+ cfg,
589
+ accountId: accountId ?? void 0
590
+ });
591
+ } },
852
592
  message: lineMessageAdapter,
853
593
  actions: lineMessageActions,
854
594
  bindings: lineBindingsAdapter,
@@ -1,2 +1,2 @@
1
- import { t as linePlugin } from "./channel-DmoKZXmG.js";
1
+ import { t as linePlugin } from "./channel-CLCy4jAa.js";
2
2
  export { linePlugin };
@@ -0,0 +1,4 @@
1
+ import { t as monitorLineProvider } from "./monitor-CSpwQCBI.js";
2
+ import { t as probeLineBot } from "./probe-4gc_YQ2L.js";
3
+ import { _ as showLoadingAnimation, d as pushMessageLine } from "./send-wVUV00WS.js";
4
+ export { monitorLineProvider, probeLineBot, pushMessageLine, showLoadingAnimation };
@@ -1,2 +1,2 @@
1
- import { i as resolveLineAccount, r as resolveDefaultLineAccountId, t as listLineAccountIds } from "./accounts-BqEVsDoB.js";
1
+ import { i as resolveLineAccount, r as resolveDefaultLineAccountId, t as listLineAccountIds } from "./accounts-BBEFMYbY.js";
2
2
  export { listLineAccountIds, resolveDefaultLineAccountId, resolveLineAccount };