@openclaw/line 2026.7.2-beta.1 → 2026.7.2-beta.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.
@@ -2,7 +2,7 @@ import { i as createMediaPlayerCard, l as createAgendaCard, n as createAppleTvRe
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";
5
- import { buildChannelConfigSchema, requireOpenAllowFrom } from "openclaw/plugin-sdk/channel-config-schema";
5
+ import { DmPolicySchema, GroupPolicySchema, buildChannelConfigSchema, buildGroupEntrySchema, buildMultiAccountChannelSchema, requireOpenAllowFrom } from "openclaw/plugin-sdk/channel-config-schema";
6
6
  import { requireChannelOpenAllowFrom } from "openclaw/plugin-sdk/extension-shared";
7
7
  import { z } from "zod";
8
8
  import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
@@ -49,17 +49,6 @@ function resolveExactLineGroupConfigKey(params) {
49
49
  }
50
50
  //#endregion
51
51
  //#region extensions/line/src/config-schema.ts
52
- const DmPolicySchema = z.enum([
53
- "open",
54
- "allowlist",
55
- "pairing",
56
- "disabled"
57
- ]);
58
- const GroupPolicySchema = z.enum([
59
- "open",
60
- "allowlist",
61
- "disabled"
62
- ]);
63
52
  const ThreadBindingsSchema = z.object({
64
53
  enabled: z.boolean().optional(),
65
54
  idleHours: z.number().optional(),
@@ -85,34 +74,21 @@ const LineCommonConfigSchemaBase = z.object({
85
74
  webhookPath: z.string().optional(),
86
75
  threadBindings: ThreadBindingsSchema.optional()
87
76
  });
88
- const LineGroupConfigSchema = z.object({
89
- enabled: z.boolean().optional(),
90
- allowFrom: z.array(z.union([z.string(), z.number()])).optional(),
91
- requireMention: z.boolean().optional(),
92
- systemPrompt: z.string().optional(),
93
- skills: z.array(z.string()).optional()
94
- }).strict();
95
- const LineAccountConfigSchema = LineCommonConfigSchemaBase.extend({ groups: z.record(z.string(), LineGroupConfigSchema.optional()).optional() }).strict().superRefine((value, ctx) => {
96
- requireChannelOpenAllowFrom({
97
- channel: "line",
98
- policy: value.dmPolicy,
99
- allowFrom: value.allowFrom,
100
- ctx,
101
- requireOpenAllowFrom
102
- });
77
+ const LineGroupConfigSchema = buildGroupEntrySchema().omit({
78
+ tools: true,
79
+ toolsBySender: true
103
80
  });
104
- const LineConfigSchema = LineCommonConfigSchemaBase.extend({
105
- accounts: z.record(z.string(), LineAccountConfigSchema.optional()).optional(),
106
- defaultAccount: z.string().optional(),
107
- groups: z.record(z.string(), LineGroupConfigSchema.optional()).optional()
108
- }).strict().superRefine((value, ctx) => {
109
- requireChannelOpenAllowFrom({
110
- channel: "line",
111
- policy: value.dmPolicy,
112
- allowFrom: value.allowFrom,
113
- ctx,
114
- requireOpenAllowFrom
115
- });
81
+ const LineConfigSchema = buildMultiAccountChannelSchema(LineCommonConfigSchemaBase.extend({ groups: z.record(z.string(), LineGroupConfigSchema.optional()).optional() }).strict(), {
82
+ optionalAccount: true,
83
+ refine: (value, ctx) => {
84
+ requireChannelOpenAllowFrom({
85
+ channel: "line",
86
+ policy: value.dmPolicy,
87
+ allowFrom: value.allowFrom,
88
+ ctx,
89
+ requireOpenAllowFrom
90
+ });
91
+ }
116
92
  });
117
93
  const LineChannelConfigSchema = buildChannelConfigSchema(LineConfigSchema);
118
94
  //#endregion
@@ -129,9 +105,9 @@ async function validateLineMediaUrl(url) {
129
105
  try {
130
106
  parsed = new URL(url);
131
107
  } catch {
132
- throw new Error(`LINE outbound media URL must be a valid URL: ${url}`);
108
+ throw new Error("LINE outbound media URL must be a valid URL");
133
109
  }
134
- if (parsed.protocol !== "https:") throw new Error(`LINE outbound media URL must use HTTPS: ${url}`);
110
+ if (parsed.protocol !== "https:") throw new Error("LINE outbound media URL must use HTTPS");
135
111
  if (url.length > 2e3) throw new Error(`LINE outbound media URL must be 2000 chars or less (got ${url.length})`);
136
112
  await resolvePinnedHostnameWithPolicy(parsed.hostname, { policy: LINE_OUTBOUND_MEDIA_SSRF_POLICY });
137
113
  }
@@ -166,13 +142,47 @@ async function resolveLineOutboundMedia(mediaUrl, opts = {}) {
166
142
  ...opts.trackingId ? { trackingId: opts.trackingId } : {}
167
143
  };
168
144
  }
145
+ let parsed;
169
146
  try {
170
- if (new URL(trimmedUrl).protocol !== "https:") throw new Error(`LINE outbound media URL must use HTTPS: ${trimmedUrl}`);
171
- } catch (e) {
172
- if (e instanceof Error && e.message.startsWith("LINE outbound")) throw e;
173
- }
147
+ parsed = new URL(trimmedUrl);
148
+ } catch {}
149
+ if (parsed) throw new Error("LINE outbound media URL must use HTTPS");
174
150
  throw new Error("LINE outbound media currently requires a public HTTPS URL");
175
151
  }
152
+ function isLineUserTarget(target) {
153
+ const normalized = target.trim().replace(/^line:(group|room|user):/i, "").replace(/^line:/i, "");
154
+ return /^U/i.test(normalized);
155
+ }
156
+ function hasLineSpecificMediaOptions(lineData) {
157
+ return lineData.mediaKind !== void 0 || Boolean(lineData.previewImageUrl?.trim()) || typeof lineData.durationMs === "number" || Boolean(lineData.trackingId?.trim());
158
+ }
159
+ function buildLineMediaMessageObject(resolved, opts) {
160
+ switch (resolved.mediaKind) {
161
+ case "video": {
162
+ const previewImageUrl = resolved.previewImageUrl?.trim();
163
+ if (!previewImageUrl) throw new Error("LINE video messages require previewImageUrl to reference an image URL");
164
+ return {
165
+ type: "video",
166
+ originalContentUrl: resolved.mediaUrl,
167
+ previewImageUrl,
168
+ ...opts?.allowTrackingId && resolved.trackingId ? { trackingId: resolved.trackingId } : {}
169
+ };
170
+ }
171
+ case "audio": return {
172
+ type: "audio",
173
+ originalContentUrl: resolved.mediaUrl,
174
+ duration: resolved.durationMs ?? 6e4
175
+ };
176
+ default: return {
177
+ type: "image",
178
+ originalContentUrl: resolved.mediaUrl,
179
+ previewImageUrl: resolved.previewImageUrl ?? resolved.mediaUrl
180
+ };
181
+ }
182
+ }
183
+ async function buildLineMediaMessage(mediaUrl, opts, target) {
184
+ return buildLineMediaMessageObject(await resolveLineOutboundMedia(mediaUrl, opts), { allowTrackingId: isLineUserTarget(target) });
185
+ }
176
186
  //#endregion
177
187
  //#region extensions/line/src/quick-reply-fallback.ts
178
188
  function buildLineQuickReplyFallbackText(labels) {
@@ -420,7 +430,7 @@ function parseLineDirectives(payload) {
420
430
  const parts = expectDefined(agendaMatch[1], "agenda directive body").split("|").map((s) => s.trim());
421
431
  if (parts.length >= 2) {
422
432
  const title = expectDefined(parts[0], "agenda title field");
423
- const events = expectDefined(parts[1], "agenda events field").split(",").map((eventStr) => {
433
+ const events = normalizeStringEntries(expectDefined(parts[1], "agenda events field").split(",")).map((eventStr) => {
424
434
  const trimmed = eventStr.trim();
425
435
  const colonIdx = trimmed.lastIndexOf(":");
426
436
  if (colonIdx > 0) return {
@@ -447,14 +457,15 @@ function parseLineDirectives(payload) {
447
457
  const deviceName = expectDefined(parts[0], "device name field");
448
458
  const [, deviceType, status, controlsStr] = parts;
449
459
  const deviceKey = toSlug(deviceName || "device");
450
- const controls = controlsStr ? controlsStr.split(",").map((ctrlStr) => {
460
+ const controls = controlsStr ? normalizeStringEntries(controlsStr.split(",")).flatMap((ctrlStr) => {
451
461
  const controlParts = ctrlStr.split(":").map((s) => s.trim());
452
462
  const label = expectDefined(controlParts[0], "device control label");
463
+ if (!label) return [];
453
464
  const action = controlParts[1] || normalizeLowercaseStringOrEmpty(label).replace(/\s+/g, "_");
454
- return {
465
+ return [{
455
466
  label,
456
467
  data: lineActionData(action, { "line.device": deviceKey })
457
- };
468
+ }];
458
469
  }) : [];
459
470
  const card = createDeviceControlCard({
460
471
  deviceName: deviceName || "Device",
@@ -481,4 +492,4 @@ function hasLineDirectives(text) {
481
492
  return /\[\[(quick_replies|location|confirm|buttons|media_player|event|agenda|device|appletv_remote):/i.test(text);
482
493
  }
483
494
  //#endregion
484
- 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 };
495
+ export { buildLineMediaMessage as a, validateLineMediaUrl as c, LineChannelConfigSchema as d, LineConfigSchema as f, resolveLineGroupsConfig as g, resolveLineGroupLookupIds as h, buildLineQuickReplyFallbackText as i, getLineRuntime as l, resolveLineGroupConfigEntry as m, parseLineDirectives as n, hasLineSpecificMediaOptions as o, resolveExactLineGroupConfigKey as p, createLineSendReceipt as r, resolveLineOutboundMedia as s, hasLineDirectives as t, setLineRuntime as u };
@@ -1,16 +1,17 @@
1
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-BsbwCJGH.js";
2
+ import { d as LineChannelConfigSchema, f as LineConfigSchema, g as resolveLineGroupsConfig, h as resolveLineGroupLookupIds, m as resolveLineGroupConfigEntry, n as parseLineDirectives, p as resolveExactLineGroupConfigKey, t as hasLineDirectives, u as setLineRuntime } from "./reply-payload-transform-r9sa-TYT.js";
3
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-K1lS9i8L.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-q3UE2J1g.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-Db2rZsSX.js";
5
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-CixmAKiG.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-XceqeKRP.js";
7
7
  import { clearAccountEntryFields } from "openclaw/plugin-sdk/core";
8
8
  import { buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";
9
9
  import { createMessageReceiveContext } from "openclaw/plugin-sdk/channel-outbound";
10
10
  import { DEFAULT_ACCOUNT_ID, formatDocsLink, setSetupChannelEnabled, splitSetupEntries } from "openclaw/plugin-sdk/setup";
11
11
  import { buildComputedAccountStatusSnapshot, buildTokenChannelStatusSummary } from "openclaw/plugin-sdk/status-helpers";
12
- import { messagingApi } from "@line/bot-sdk";
13
12
  import { danger, logVerbose } from "openclaw/plugin-sdk/runtime-env";
13
+ import { messagingApi } from "@line/bot-sdk";
14
+ import { runDetachedWebhookWork } from "openclaw/plugin-sdk/webhook-request-guards";
14
15
  import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/agent-media-payload";
15
16
  import { mimeTypeFromFilePath } from "openclaw/plugin-sdk/media-mime";
16
17
  import { loadWebMediaRaw } from "openclaw/plugin-sdk/web-media";
@@ -69,7 +70,7 @@ function createLineWebhookMiddleware(options) {
69
70
  if (receiveContext.shouldAckAfter("receive_record")) await receiveContext.ack();
70
71
  if (body.events && body.events.length > 0) {
71
72
  logVerbose(`line: received ${body.events.length} webhook events`);
72
- Promise.resolve().then(() => onEvents(body)).catch((err) => logLineWebhookDispatchError(runtime, err));
73
+ runDetachedWebhookWork(() => onEvents(body)).catch((err) => logLineWebhookDispatchError(runtime, err));
73
74
  }
74
75
  } catch (err) {
75
76
  await receiveContext?.nack(err);
package/dist/setup-api.js CHANGED
@@ -1,2 +1,2 @@
1
- import { n as lineSetupAdapter, t as lineSetupWizard } from "./setup-surface-Bc36YSS3.js";
1
+ import { n as lineSetupAdapter, t as lineSetupWizard } from "./setup-surface-B7W6pwn3.js";
2
2
  export { lineSetupAdapter, lineSetupWizard };
@@ -1,6 +1,6 @@
1
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
- import { DEFAULT_ACCOUNT_ID, createAllowFromSection, createSetupInputPresenceValidator, createSetupTranslator, createStandardChannelSetupStatus, formatDocsLink, mergeAllowFromEntries, setSetupChannelEnabled, splitSetupEntries } from "openclaw/plugin-sdk/setup";
3
+ import { DEFAULT_ACCOUNT_ID, createAllowFromSection, createSetupInputPresenceValidator, createSetupTranslator, createStandardChannelSetupStatus, defineTokenCredential, formatDocsLink, mergeAllowFromEntries, setSetupChannelEnabled, splitSetupEntries } from "openclaw/plugin-sdk/setup";
4
4
  //#region extensions/line/src/account-helpers.ts
5
5
  function hasLineCredentials(account) {
6
6
  return Boolean(account.channelAccessToken?.trim() && account.channelSecret?.trim());
@@ -173,8 +173,10 @@ const lineSetupWizard = {
173
173
  lines: LINE_SETUP_HELP_LINES,
174
174
  shouldShow: ({ cfg, accountId }) => !isLineConfigured(cfg, accountId ?? resolveDefaultLineAccountId(cfg))
175
175
  },
176
- credentials: [{
176
+ credentials: [defineTokenCredential({
177
177
  inputKey: "token",
178
+ configKey: "channelAccessToken",
179
+ configuredFields: ["channelAccessToken", "tokenFile"],
178
180
  providerHint: channel,
179
181
  credentialLabel: t("wizard.line.channelAccessToken"),
180
182
  preferredEnvVar: "LINE_CHANNEL_ACCESS_TOKEN",
@@ -184,34 +186,30 @@ const lineSetupWizard = {
184
186
  keepPrompt: t("wizard.line.tokenKeepPrompt"),
185
187
  inputPrompt: t("wizard.line.tokenInputPrompt"),
186
188
  allowEnv: ({ accountId }) => accountId === DEFAULT_ACCOUNT_ID,
187
- inspect: ({ cfg, accountId }) => {
188
- const resolved = resolveLineAccount({
189
- cfg,
190
- accountId
191
- });
192
- return {
193
- accountConfigured: Boolean(normalizeOptionalString(resolved.channelAccessToken) && normalizeOptionalString(resolved.channelSecret)),
194
- hasConfiguredValue: Boolean(normalizeOptionalString(resolved.config.channelAccessToken) ?? normalizeOptionalString(resolved.config.tokenFile)),
195
- resolvedValue: normalizeOptionalString(resolved.channelAccessToken),
196
- envValue: accountId === DEFAULT_ACCOUNT_ID ? normalizeOptionalString(process.env.LINE_CHANNEL_ACCESS_TOKEN) : void 0
197
- };
198
- },
199
- applyUseEnv: ({ cfg, accountId }) => patchLineAccountConfig({
189
+ resolveAccount: ({ cfg, accountId }) => resolveLineAccount({
200
190
  cfg,
201
- accountId,
202
- enabled: true,
203
- clearFields: ["channelAccessToken", "tokenFile"],
204
- patch: {}
191
+ accountId
205
192
  }),
206
- applySet: ({ cfg, accountId, resolvedValue }) => patchLineAccountConfig({
193
+ accountConfigured: (account) => Boolean(normalizeOptionalString(account.channelAccessToken) && normalizeOptionalString(account.channelSecret)),
194
+ hasConfiguredValue: (account) => Boolean(normalizeOptionalString(account.config.channelAccessToken) ?? normalizeOptionalString(account.config.tokenFile)),
195
+ resolvedValue: (account) => normalizeOptionalString(account.channelAccessToken),
196
+ envValue: ({ accountId }) => accountId === DEFAULT_ACCOUNT_ID ? normalizeOptionalString(process.env.LINE_CHANNEL_ACCESS_TOKEN) : void 0,
197
+ patchAccount: ({ cfg, accountId, patch, clearFields }) => patchLineAccountConfig({
207
198
  cfg,
208
199
  accountId,
209
200
  enabled: true,
201
+ clearFields,
202
+ patch
203
+ }),
204
+ useEnv: { clearFields: ["channelAccessToken", "tokenFile"] },
205
+ set: {
210
206
  clearFields: ["tokenFile"],
211
- patch: { channelAccessToken: resolvedValue }
212
- })
213
- }, {
207
+ value: "resolved"
208
+ }
209
+ }), defineTokenCredential({
214
210
  inputKey: "password",
211
+ configKey: "channelSecret",
212
+ configuredFields: ["channelSecret", "secretFile"],
215
213
  providerHint: "line-secret",
216
214
  credentialLabel: t("wizard.line.channelSecret"),
217
215
  preferredEnvVar: "LINE_CHANNEL_SECRET",
@@ -221,33 +219,27 @@ const lineSetupWizard = {
221
219
  keepPrompt: t("wizard.line.secretKeepPrompt"),
222
220
  inputPrompt: t("wizard.line.secretInputPrompt"),
223
221
  allowEnv: ({ accountId }) => accountId === DEFAULT_ACCOUNT_ID,
224
- inspect: ({ cfg, accountId }) => {
225
- const resolved = resolveLineAccount({
226
- cfg,
227
- accountId
228
- });
229
- return {
230
- accountConfigured: Boolean(normalizeOptionalString(resolved.channelAccessToken) && normalizeOptionalString(resolved.channelSecret)),
231
- hasConfiguredValue: Boolean(normalizeOptionalString(resolved.config.channelSecret) ?? normalizeOptionalString(resolved.config.secretFile)),
232
- resolvedValue: normalizeOptionalString(resolved.channelSecret),
233
- envValue: accountId === DEFAULT_ACCOUNT_ID ? normalizeOptionalString(process.env.LINE_CHANNEL_SECRET) : void 0
234
- };
235
- },
236
- applyUseEnv: ({ cfg, accountId }) => patchLineAccountConfig({
222
+ resolveAccount: ({ cfg, accountId }) => resolveLineAccount({
237
223
  cfg,
238
- accountId,
239
- enabled: true,
240
- clearFields: ["channelSecret", "secretFile"],
241
- patch: {}
224
+ accountId
242
225
  }),
243
- applySet: ({ cfg, accountId, resolvedValue }) => patchLineAccountConfig({
226
+ accountConfigured: (account) => Boolean(normalizeOptionalString(account.channelAccessToken) && normalizeOptionalString(account.channelSecret)),
227
+ hasConfiguredValue: (account) => Boolean(normalizeOptionalString(account.config.channelSecret) ?? normalizeOptionalString(account.config.secretFile)),
228
+ resolvedValue: (account) => normalizeOptionalString(account.channelSecret),
229
+ envValue: ({ accountId }) => accountId === DEFAULT_ACCOUNT_ID ? normalizeOptionalString(process.env.LINE_CHANNEL_SECRET) : void 0,
230
+ patchAccount: ({ cfg, accountId, patch, clearFields }) => patchLineAccountConfig({
244
231
  cfg,
245
232
  accountId,
246
233
  enabled: true,
234
+ clearFields,
235
+ patch
236
+ }),
237
+ useEnv: { clearFields: ["channelSecret", "secretFile"] },
238
+ set: {
247
239
  clearFields: ["secretFile"],
248
- patch: { channelSecret: resolvedValue }
249
- })
250
- }],
240
+ value: "resolved"
241
+ }
242
+ })],
251
243
  allowFrom: createAllowFromSection({
252
244
  helpTitle: t("wizard.line.allowlistTitle"),
253
245
  helpLines: LINE_ALLOW_FROM_HELP_LINES,
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@openclaw/line",
3
- "version": "2026.7.2-beta.1",
3
+ "version": "2026.7.2-beta.2",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@openclaw/line",
9
- "version": "2026.7.2-beta.1",
9
+ "version": "2026.7.2-beta.2",
10
10
  "dependencies": {
11
11
  "@line/bot-sdk": "11.1.0",
12
12
  "zod": "4.4.3"
13
13
  },
14
14
  "peerDependencies": {
15
- "openclaw": ">=2026.7.2-beta.1"
15
+ "openclaw": ">=2026.7.2-beta.2"
16
16
  },
17
17
  "peerDependenciesMeta": {
18
18
  "openclaw": {
@@ -74,9 +74,9 @@
74
74
  "default": "pairing",
75
75
  "type": "string",
76
76
  "enum": [
77
- "open",
78
- "allowlist",
79
77
  "pairing",
78
+ "allowlist",
79
+ "open",
80
80
  "disabled"
81
81
  ]
82
82
  },
@@ -85,8 +85,8 @@
85
85
  "type": "string",
86
86
  "enum": [
87
87
  "open",
88
- "allowlist",
89
- "disabled"
88
+ "disabled",
89
+ "allowlist"
90
90
  ]
91
91
  },
92
92
  "responsePrefix": {
@@ -129,6 +129,46 @@
129
129
  },
130
130
  "additionalProperties": false
131
131
  },
132
+ "groups": {
133
+ "type": "object",
134
+ "propertyNames": {
135
+ "type": "string"
136
+ },
137
+ "additionalProperties": {
138
+ "type": "object",
139
+ "properties": {
140
+ "requireMention": {
141
+ "type": "boolean"
142
+ },
143
+ "skills": {
144
+ "type": "array",
145
+ "items": {
146
+ "type": "string"
147
+ }
148
+ },
149
+ "enabled": {
150
+ "type": "boolean"
151
+ },
152
+ "allowFrom": {
153
+ "type": "array",
154
+ "items": {
155
+ "anyOf": [
156
+ {
157
+ "type": "string"
158
+ },
159
+ {
160
+ "type": "number"
161
+ }
162
+ ]
163
+ }
164
+ },
165
+ "systemPrompt": {
166
+ "type": "string"
167
+ }
168
+ },
169
+ "additionalProperties": false
170
+ }
171
+ },
132
172
  "accounts": {
133
173
  "type": "object",
134
174
  "propertyNames": {
@@ -185,9 +225,9 @@
185
225
  "default": "pairing",
186
226
  "type": "string",
187
227
  "enum": [
188
- "open",
189
- "allowlist",
190
228
  "pairing",
229
+ "allowlist",
230
+ "open",
191
231
  "disabled"
192
232
  ]
193
233
  },
@@ -196,8 +236,8 @@
196
236
  "type": "string",
197
237
  "enum": [
198
238
  "open",
199
- "allowlist",
200
- "disabled"
239
+ "disabled",
240
+ "allowlist"
201
241
  ]
202
242
  },
203
243
  "responsePrefix": {
@@ -248,6 +288,15 @@
248
288
  "additionalProperties": {
249
289
  "type": "object",
250
290
  "properties": {
291
+ "requireMention": {
292
+ "type": "boolean"
293
+ },
294
+ "skills": {
295
+ "type": "array",
296
+ "items": {
297
+ "type": "string"
298
+ }
299
+ },
251
300
  "enabled": {
252
301
  "type": "boolean"
253
302
  },
@@ -264,17 +313,8 @@
264
313
  ]
265
314
  }
266
315
  },
267
- "requireMention": {
268
- "type": "boolean"
269
- },
270
316
  "systemPrompt": {
271
317
  "type": "string"
272
- },
273
- "skills": {
274
- "type": "array",
275
- "items": {
276
- "type": "string"
277
- }
278
318
  }
279
319
  },
280
320
  "additionalProperties": false
@@ -290,46 +330,6 @@
290
330
  },
291
331
  "defaultAccount": {
292
332
  "type": "string"
293
- },
294
- "groups": {
295
- "type": "object",
296
- "propertyNames": {
297
- "type": "string"
298
- },
299
- "additionalProperties": {
300
- "type": "object",
301
- "properties": {
302
- "enabled": {
303
- "type": "boolean"
304
- },
305
- "allowFrom": {
306
- "type": "array",
307
- "items": {
308
- "anyOf": [
309
- {
310
- "type": "string"
311
- },
312
- {
313
- "type": "number"
314
- }
315
- ]
316
- }
317
- },
318
- "requireMention": {
319
- "type": "boolean"
320
- },
321
- "systemPrompt": {
322
- "type": "string"
323
- },
324
- "skills": {
325
- "type": "array",
326
- "items": {
327
- "type": "string"
328
- }
329
- }
330
- },
331
- "additionalProperties": false
332
- }
333
333
  }
334
334
  },
335
335
  "required": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/line",
3
- "version": "2026.7.2-beta.1",
3
+ "version": "2026.7.2-beta.2",
4
4
  "description": "OpenClaw LINE channel plugin for LINE Bot API chats.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -12,7 +12,7 @@
12
12
  "zod": "4.4.3"
13
13
  },
14
14
  "peerDependencies": {
15
- "openclaw": ">=2026.7.2-beta.1"
15
+ "openclaw": ">=2026.7.2-beta.2"
16
16
  },
17
17
  "peerDependenciesMeta": {
18
18
  "openclaw": {
@@ -42,10 +42,10 @@
42
42
  "minHostVersion": ">=2026.4.10"
43
43
  },
44
44
  "compat": {
45
- "pluginApi": ">=2026.7.2-beta.1"
45
+ "pluginApi": ">=2026.7.2-beta.2"
46
46
  },
47
47
  "build": {
48
- "openclawVersion": "2026.7.2-beta.1"
48
+ "openclawVersion": "2026.7.2-beta.2"
49
49
  },
50
50
  "release": {
51
51
  "publishToClawHub": true,
@@ -1,4 +0,0 @@
1
- import { t as monitorLineProvider } from "./monitor-q3UE2J1g.js";
2
- import { t as probeLineBot } from "./probe-BslD77tJ.js";
3
- import { S as pushMessageLine } from "./markdown-to-line-CixmAKiG.js";
4
- export { monitorLineProvider, probeLineBot, pushMessageLine };
@@ -1,2 +0,0 @@
1
- import { t as monitorLineProvider } from "./monitor-q3UE2J1g.js";
2
- export { monitorLineProvider };