@openclaw/zalouser 2026.5.14-beta.2 → 2026.5.16-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.
@@ -1,10 +1,10 @@
1
- import "./setup-surface-Dv3nk0fI.js";
2
- import "./shared-O0YC-vIX.js";
3
- import "./channel-BbRxSL6F.js";
1
+ import "./setup-surface-BOEnAElK.js";
2
+ import "./shared-BZ67dMHg.js";
3
+ import "./channel-ChrMP7B9.js";
4
4
  import { r as parseZalouserOutboundTarget } from "./session-route-DWMin5CB.js";
5
5
  import "./security-audit-DUQOetcM.js";
6
6
  import { i as listZaloFriendsMatching, n as getZaloUserInfo, s as listZaloGroupsMatching, t as checkZaloAuthenticated } from "./zalo-js-QSY2SsUF.js";
7
- import "./channel.setup-D-TSDzJ-.js";
7
+ import "./channel.setup-q1_Y8eHR.js";
8
8
  import { i as sendMessageZalouser, n as sendImageZalouser, r as sendLinkZalouser } from "./send-SPumHuhS.js";
9
9
  import { stringEnum } from "openclaw/plugin-sdk/channel-actions";
10
10
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
package/dist/api.js CHANGED
@@ -1,7 +1,7 @@
1
- import { n as zalouserSetupWizard } from "./setup-surface-Dv3nk0fI.js";
2
- import { n as createZalouserSetupWizardProxy, r as zalouserSetupAdapter } from "./shared-O0YC-vIX.js";
3
- import { t as zalouserPlugin } from "./channel-BbRxSL6F.js";
1
+ import { n as zalouserSetupWizard } from "./setup-surface-BOEnAElK.js";
2
+ import { n as createZalouserSetupWizardProxy, r as zalouserSetupAdapter } from "./shared-BZ67dMHg.js";
3
+ import { t as zalouserPlugin } from "./channel-ChrMP7B9.js";
4
4
  import { n as isZalouserMutableGroupEntry, t as collectZalouserSecurityAuditFindings } from "./security-audit-DUQOetcM.js";
5
- import { t as zalouserSetupPlugin } from "./channel.setup-D-TSDzJ-.js";
6
- import { t as createZalouserTool } from "./api-BKTe9er6.js";
5
+ import { t as zalouserSetupPlugin } from "./channel.setup-q1_Y8eHR.js";
6
+ import { t as createZalouserTool } from "./api-Cn_gTKvR.js";
7
7
  export { collectZalouserSecurityAuditFindings, createZalouserSetupWizardProxy, createZalouserTool, isZalouserMutableGroupEntry, zalouserPlugin, zalouserSetupAdapter, zalouserSetupPlugin, zalouserSetupWizard };
@@ -1,5 +1,5 @@
1
1
  import { a as resolveZalouserAccountSync, i as resolveDefaultZalouserAccountId, r as listZalouserAccountIds, t as checkZcaAuthenticated } from "./accounts-CTecjIqR.js";
2
- import { a as DEFAULT_ACCOUNT_ID, c as isNumericTargetId, i as writeQrDataUrlToTempFile, l as normalizeAccountId, n as createZalouserSetupWizardProxy, o as chunkTextForOutbound, r as zalouserSetupAdapter, s as isDangerousNameMatchingEnabled, t as createZalouserPluginBase, u as sendPayloadWithChunkedTextAndMedia } from "./shared-O0YC-vIX.js";
2
+ import { a as DEFAULT_ACCOUNT_ID, c as isNumericTargetId, i as writeQrDataUrlToTempFile, l as normalizeAccountId, n as createZalouserSetupWizardProxy, o as chunkTextForOutbound, r as zalouserSetupAdapter, s as isDangerousNameMatchingEnabled, t as createZalouserPluginBase, u as sendPayloadWithChunkedTextAndMedia } from "./shared-BZ67dMHg.js";
3
3
  import { i as resolveZalouserOutboundSessionRoute, n as parseZalouserDirectoryGroupId, r as parseZalouserOutboundTarget, t as normalizeZalouserTarget } from "./session-route-DWMin5CB.js";
4
4
  import { createChatChannelPlugin } from "openclaw/plugin-sdk/channel-core";
5
5
  import { createAccountStatusSink } from "openclaw/plugin-sdk/channel-lifecycle";
@@ -449,7 +449,7 @@ function collectZalouserStatusIssues(accounts) {
449
449
  //#endregion
450
450
  //#region extensions/zalouser/src/channel.ts
451
451
  const loadZalouserChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime-oMRJXO6B.js"));
452
- const zalouserSetupWizardProxy = createZalouserSetupWizardProxy(async () => (await import("./setup-surface-Dv3nk0fI.js").then((n) => n.t)).zalouserSetupWizard);
452
+ const zalouserSetupWizardProxy = createZalouserSetupWizardProxy(async () => (await import("./setup-surface-BOEnAElK.js").then((n) => n.t)).zalouserSetupWizard);
453
453
  function mapUser(params) {
454
454
  return {
455
455
  kind: "user",
@@ -566,7 +566,7 @@ const zalouserPlugin = createChatChannelPlugin({
566
566
  setStatus: ctx.setStatus
567
567
  });
568
568
  ctx.log?.info(`[${account.accountId}] starting zalouser provider${userLabel}`);
569
- const { monitorZalouserProvider } = await import("./monitor-_QHUT-X9.js");
569
+ const { monitorZalouserProvider } = await import("./monitor-CZ3mU8vM.js");
570
570
  return monitorZalouserProvider({
571
571
  account,
572
572
  config: ctx.cfg,
@@ -1,2 +1,2 @@
1
- import { t as zalouserPlugin } from "./channel-BbRxSL6F.js";
1
+ import { t as zalouserPlugin } from "./channel-ChrMP7B9.js";
2
2
  export { zalouserPlugin };
@@ -1,5 +1,5 @@
1
- import { n as zalouserSetupWizard } from "./setup-surface-Dv3nk0fI.js";
2
- import { r as zalouserSetupAdapter, t as createZalouserPluginBase } from "./shared-O0YC-vIX.js";
1
+ import { n as zalouserSetupWizard } from "./setup-surface-BOEnAElK.js";
2
+ import { r as zalouserSetupAdapter, t as createZalouserPluginBase } from "./shared-BZ67dMHg.js";
3
3
  //#region extensions/zalouser/src/channel.setup.ts
4
4
  const zalouserSetupPlugin = { ...createZalouserPluginBase({
5
5
  setupWizard: zalouserSetupWizard,
@@ -1,4 +1,4 @@
1
- import { a as resolveZalouserMessageSid, c as isZalouserGroupEntryAllowed, i as formatZalouserMessageSidFull, n as getZalouserRuntime, o as buildZalouserGroupCandidates, s as findZalouserGroupEntry } from "./channel-BbRxSL6F.js";
1
+ import { a as resolveZalouserMessageSid, c as isZalouserGroupEntryAllowed, i as formatZalouserMessageSidFull, n as getZalouserRuntime, o as buildZalouserGroupCandidates, s as findZalouserGroupEntry } from "./channel-ChrMP7B9.js";
2
2
  import { o as listZaloGroups, r as listZaloFriends, u as resolveZaloGroupContext, v as startZaloListener } from "./zalo-js-QSY2SsUF.js";
3
3
  import { i as sendMessageZalouser, o as sendSeenZalouser, s as sendTypingZalouser, t as sendDeliveredZalouser } from "./send-SPumHuhS.js";
4
4
  import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
@@ -11,7 +11,7 @@ import { createChannelPairingController } from "openclaw/plugin-sdk/channel-pair
11
11
  import { resolveDefaultGroupPolicy, resolveOpenProviderRuntimeGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
12
12
  import { implicitMentionKindWhen, resolveInboundMentionDecision } from "openclaw/plugin-sdk/channel-inbound";
13
13
  import { resolveStableChannelMessageIngress } from "openclaw/plugin-sdk/channel-ingress-runtime";
14
- import { DEFAULT_GROUP_HISTORY_LIMIT, buildPendingHistoryContextFromMap, clearHistoryEntriesIfEnabled, recordPendingHistoryEntryIfEnabled } from "openclaw/plugin-sdk/reply-history";
14
+ import { DEFAULT_GROUP_HISTORY_LIMIT, createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
15
15
  //#region extensions/zalouser/src/monitor.ts
16
16
  const ZALOUSER_TEXT_LIMIT = 2e3;
17
17
  function buildNameIndex(items, nameFn) {
@@ -296,6 +296,7 @@ async function processMessage(message, account, config, core, runtime, historySt
296
296
  }
297
297
  });
298
298
  const historyKey = isGroup ? route.sessionKey : void 0;
299
+ const channelHistory = createChannelHistoryWindow({ historyMap: historyState.groupHistories });
299
300
  const requireMention = isGroup ? resolveGroupRequireMention({
300
301
  groupId: chatId,
301
302
  groupName,
@@ -337,8 +338,7 @@ async function processMessage(message, account, config, core, runtime, historySt
337
338
  return;
338
339
  }
339
340
  if (isGroup && mentionDecision.shouldSkip) {
340
- recordPendingHistoryEntryIfEnabled({
341
- historyMap: historyState.groupHistories,
341
+ channelHistory.record({
342
342
  historyKey: historyKey ?? "",
343
343
  limit: historyState.historyLimit,
344
344
  entry: historyKey && rawBody ? {
@@ -378,8 +378,7 @@ async function processMessage(message, account, config, core, runtime, historySt
378
378
  envelope: envelopeOptions,
379
379
  body: rawBody
380
380
  });
381
- const combinedBody = isGroup && historyKey ? buildPendingHistoryContextFromMap({
382
- historyMap: historyState.groupHistories,
381
+ const combinedBody = isGroup && historyKey ? channelHistory.buildPendingContext({
383
382
  historyKey,
384
383
  limit: historyState.historyLimit,
385
384
  currentMessage: body,
@@ -391,11 +390,10 @@ async function processMessage(message, account, config, core, runtime, historySt
391
390
  body: `${entry.sender}: ${entry.body}${entry.messageId ? ` [id:${entry.messageId}]` : ""}`
392
391
  })
393
392
  }) : body;
394
- const inboundHistory = isGroup && historyKey && historyState.historyLimit > 0 ? (historyState.groupHistories.get(historyKey) ?? []).map((entry) => ({
395
- sender: entry.sender,
396
- body: entry.body,
397
- timestamp: entry.timestamp
398
- })) : void 0;
393
+ const inboundHistory = isGroup && historyKey && historyState.historyLimit > 0 ? channelHistory.buildInboundHistory({
394
+ historyKey,
395
+ limit: historyState.historyLimit
396
+ }) : void 0;
399
397
  const normalizedTo = isGroup ? `zalouser:group:${chatId}` : `zalouser:${chatId}`;
400
398
  const messageSid = resolveZalouserMessageSid({
401
399
  msgId: message.msgId,
@@ -512,8 +510,7 @@ async function processMessage(message, account, config, core, runtime, historySt
512
510
  runtime.error?.(`zalouser: failed updating session meta: ${String(err)}`);
513
511
  } }
514
512
  });
515
- if (isGroup && historyKey) clearHistoryEntriesIfEnabled({
516
- historyMap: historyState.groupHistories,
513
+ if (isGroup && historyKey) channelHistory.clear({
517
514
  historyKey,
518
515
  limit: historyState.historyLimit
519
516
  });
@@ -1,9 +1,9 @@
1
- import { n as zalouserSetupWizard } from "./setup-surface-Dv3nk0fI.js";
2
- import { n as createZalouserSetupWizardProxy, r as zalouserSetupAdapter } from "./shared-O0YC-vIX.js";
3
- import { r as setZalouserRuntime, t as zalouserPlugin } from "./channel-BbRxSL6F.js";
1
+ import { n as zalouserSetupWizard } from "./setup-surface-BOEnAElK.js";
2
+ import { n as createZalouserSetupWizardProxy, r as zalouserSetupAdapter } from "./shared-BZ67dMHg.js";
3
+ import { r as setZalouserRuntime, t as zalouserPlugin } from "./channel-ChrMP7B9.js";
4
4
  import { n as isZalouserMutableGroupEntry, t as collectZalouserSecurityAuditFindings } from "./security-audit-DUQOetcM.js";
5
- import { t as zalouserSetupPlugin } from "./channel.setup-D-TSDzJ-.js";
6
- import { t as createZalouserTool } from "./api-BKTe9er6.js";
5
+ import { t as zalouserSetupPlugin } from "./channel.setup-q1_Y8eHR.js";
6
+ import { t as createZalouserTool } from "./api-Cn_gTKvR.js";
7
7
  import { buildBaseAccountStatusSnapshot } from "openclaw/plugin-sdk/status-helpers";
8
8
  import { formatAllowFromLowercase, mergeAllowlist, summarizeMapping } from "openclaw/plugin-sdk/allow-from";
9
9
  import { DEFAULT_ACCOUNT_ID, buildChannelConfigSchema, normalizeAccountId } from "openclaw/plugin-sdk/core";
@@ -1,2 +1,2 @@
1
- import { t as zalouserSetupPlugin } from "./channel.setup-D-TSDzJ-.js";
1
+ import { t as zalouserSetupPlugin } from "./channel.setup-q1_Y8eHR.js";
2
2
  export { zalouserSetupPlugin };
@@ -1,7 +1,7 @@
1
1
  import { a as resolveZalouserAccountSync, i as resolveDefaultZalouserAccountId, r as listZalouserAccountIds, t as checkZcaAuthenticated } from "./accounts-CTecjIqR.js";
2
- import { i as writeQrDataUrlToTempFile } from "./shared-O0YC-vIX.js";
2
+ import { i as writeQrDataUrlToTempFile } from "./shared-BZ67dMHg.js";
3
3
  import { b as waitForZaloQrLogin, c as logoutZaloProfile, d as resolveZaloGroupsByEntries, l as resolveZaloAllowFromEntries, y as startZaloQrLogin } from "./zalo-js-QSY2SsUF.js";
4
- import { DEFAULT_ACCOUNT_ID, addWildcardAllowFrom, formatCliCommand, formatDocsLink, formatResolvedUnresolvedNote, mergeAllowFromEntries, normalizeAccountId, patchScopedAccountConfig } from "openclaw/plugin-sdk/setup";
4
+ import { DEFAULT_ACCOUNT_ID, addWildcardAllowFrom, createSetupTranslator, formatCliCommand, formatDocsLink, formatResolvedUnresolvedNote, mergeAllowFromEntries, normalizeAccountId, patchScopedAccountConfig } from "openclaw/plugin-sdk/setup";
5
5
  //#region \0rolldown/runtime.js
6
6
  var __defProp = Object.defineProperty;
7
7
  var __exportAll = (all, no_symbols) => {
@@ -16,12 +16,13 @@ var __exportAll = (all, no_symbols) => {
16
16
  //#endregion
17
17
  //#region extensions/zalouser/src/setup-surface.ts
18
18
  var setup_surface_exports = /* @__PURE__ */ __exportAll({ zalouserSetupWizard: () => zalouserSetupWizard });
19
+ const t = createSetupTranslator();
19
20
  const channel = "zalouser";
20
- const ZALOUSER_ALLOW_FROM_PLACEHOLDER = "Alice, 123456789, or leave empty to configure later";
21
- const ZALOUSER_GROUPS_PLACEHOLDER = "Family, Work, 123456789, or leave empty for now";
22
- const ZALOUSER_DM_ACCESS_TITLE = "Zalo Personal DM access";
23
- const ZALOUSER_ALLOWLIST_TITLE = "Zalo Personal allowlist";
24
- const ZALOUSER_GROUPS_TITLE = "Zalo groups";
21
+ const ZALOUSER_ALLOW_FROM_PLACEHOLDER = t("wizard.zalouser.allowFromPlaceholder");
22
+ const ZALOUSER_GROUPS_PLACEHOLDER = t("wizard.zalouser.groupsPlaceholder");
23
+ const ZALOUSER_DM_ACCESS_TITLE = t("wizard.zalouser.dmAccessTitle");
24
+ const ZALOUSER_ALLOWLIST_TITLE = t("wizard.zalouser.allowlistTitle");
25
+ const ZALOUSER_GROUPS_TITLE = t("wizard.zalouser.groupsTitle");
25
26
  function parseZalouserEntries(raw) {
26
27
  return raw.split(/[\n,;]+/g).map((entry) => entry.trim()).filter(Boolean);
27
28
  }
@@ -83,12 +84,12 @@ function ensureZalouserPluginEnabled(cfg) {
83
84
  }
84
85
  async function noteZalouserHelp(prompter) {
85
86
  await prompter.note([
86
- "Zalo Personal Account login via QR code.",
87
+ t("wizard.zalouser.helpQrLogin"),
87
88
  "",
88
- "This plugin uses zca-js directly (no external CLI dependency).",
89
+ t("wizard.zalouser.helpZcaJs"),
89
90
  "",
90
91
  `Docs: ${formatDocsLink("/channels/zalouser", "zalouser")}`
91
- ].join("\n"), "Zalo Personal Setup");
92
+ ].join("\n"), t("wizard.zalouser.setupTitle"));
92
93
  }
93
94
  async function promptZalouserAllowFrom(params) {
94
95
  const { cfg, prompter, accountId } = params;
@@ -99,15 +100,15 @@ async function promptZalouserAllowFrom(params) {
99
100
  const existingAllowFrom = resolved.config.allowFrom ?? [];
100
101
  while (true) {
101
102
  const parts = parseZalouserEntries(await prompter.text({
102
- message: "Zalouser allowFrom (name or user id)",
103
+ message: t("wizard.zalouser.allowFromPrompt"),
103
104
  placeholder: ZALOUSER_ALLOW_FROM_PLACEHOLDER,
104
105
  initialValue: existingAllowFrom.length > 0 ? existingAllowFrom.join(", ") : void 0
105
106
  }));
106
107
  if (parts.length === 0) {
107
108
  await prompter.note([
108
- "No DM allowlist entries added yet.",
109
- "Direct chats will stay blocked until you add people later.",
110
- `Tip: use \`${formatCliCommand("openclaw directory peers list --channel zalouser")}\` to look up people after onboarding.`
109
+ t("wizard.zalouser.noDmAllowlist"),
110
+ t("wizard.zalouser.directChatsBlocked"),
111
+ t("wizard.zalouser.peersLookupTip", { command: formatCliCommand("openclaw directory peers list --channel zalouser") })
111
112
  ].join("\n"), ZALOUSER_ALLOWLIST_TITLE);
112
113
  return setZalouserAccountScopedConfig(cfg, accountId, {
113
114
  dmPolicy: "allowlist",
@@ -120,7 +121,7 @@ async function promptZalouserAllowFrom(params) {
120
121
  });
121
122
  const unresolved = resolvedEntries.filter((item) => !item.resolved).map((item) => item.input);
122
123
  if (unresolved.length > 0) {
123
- await prompter.note(`Could not resolve: ${unresolved.join(", ")}. Use numeric user ids or exact friend names.`, ZALOUSER_ALLOWLIST_TITLE);
124
+ await prompter.note(t("wizard.zalouser.couldNotResolve", { entries: unresolved.join(", ") }), ZALOUSER_ALLOWLIST_TITLE);
124
125
  continue;
125
126
  }
126
127
  const unique = mergeAllowFromEntries(existingAllowFrom, resolvedEntries.filter((item) => item.resolved && item.id).map((item) => item.id));
@@ -167,33 +168,33 @@ async function promptZalouserQuickstartDmPolicy(params) {
167
168
  const existingAllowFrom = resolved.config.allowFrom ?? [];
168
169
  const existingLabel = existingAllowFrom.length > 0 ? existingAllowFrom.join(", ") : "unset";
169
170
  await prompter.note([
170
- "Direct chats are configured separately from group chats.",
171
- "- pairing (default): unknown people get a pairing code",
172
- "- allowlist: only listed people can DM",
173
- "- open: anyone can DM",
174
- "- disabled: ignore DMs",
171
+ t("wizard.zalouser.dmHelpSeparate"),
172
+ t("wizard.zalouser.dmHelpPairing"),
173
+ t("wizard.zalouser.dmHelpAllowlist"),
174
+ t("wizard.zalouser.dmHelpOpen"),
175
+ t("wizard.zalouser.dmHelpDisabled"),
175
176
  "",
176
177
  `Current: dmPolicy=${existingPolicy}, allowFrom=${existingLabel}`,
177
- "If you choose allowlist now, you can leave it empty and add people later."
178
+ t("wizard.zalouser.dmHelpAllowlistEmpty")
178
179
  ].join("\n"), ZALOUSER_DM_ACCESS_TITLE);
179
180
  const policy = await prompter.select({
180
- message: "Zalo Personal DM policy",
181
+ message: t("wizard.zalouser.dmPolicyPrompt"),
181
182
  options: [
182
183
  {
183
184
  value: "pairing",
184
- label: "Pairing (recommended)"
185
+ label: t("wizard.channels.dmPolicyPairing")
185
186
  },
186
187
  {
187
188
  value: "allowlist",
188
- label: "Allowlist (specific users only)"
189
+ label: t("wizard.channels.dmPolicyAllowlistOption")
189
190
  },
190
191
  {
191
192
  value: "open",
192
- label: "Open (public inbound DMs)"
193
+ label: t("wizard.channels.dmPolicyOpenOption")
193
194
  },
194
195
  {
195
196
  value: "disabled",
196
- label: "Disabled (ignore DMs)"
197
+ label: t("wizard.channels.dmPolicyDisabledOption")
197
198
  }
198
199
  ],
199
200
  initialValue: existingPolicy
@@ -208,10 +209,10 @@ async function promptZalouserQuickstartDmPolicy(params) {
208
209
  const zalouserSetupWizard = {
209
210
  channel,
210
211
  status: {
211
- configuredLabel: "logged in",
212
- unconfiguredLabel: "needs QR login",
213
- configuredHint: "recommended · logged in",
214
- unconfiguredHint: "recommended · QR login",
212
+ configuredLabel: t("wizard.channels.statusLoggedIn"),
213
+ unconfiguredLabel: t("wizard.channels.statusNeedsQrLogin"),
214
+ configuredHint: t("wizard.channels.statusRecommendedLoggedIn"),
215
+ unconfiguredHint: t("wizard.channels.statusRecommendedQrLogin"),
215
216
  configuredScore: 1,
216
217
  unconfiguredScore: 15,
217
218
  resolveConfigured: async ({ cfg, accountId }) => {
@@ -235,7 +236,7 @@ const zalouserSetupWizard = {
235
236
  if (!await checkZcaAuthenticated(account.profile)) {
236
237
  await noteZalouserHelp(prompter);
237
238
  if (await prompter.confirm({
238
- message: "Login via QR code now?",
239
+ message: t("wizard.zalouser.loginQrPrompt"),
239
240
  initialValue: true
240
241
  })) {
241
242
  const start = await startZaloQrLogin({
@@ -246,23 +247,23 @@ const zalouserSetupWizard = {
246
247
  const qrPath = await writeQrDataUrlToTempFile(start.qrDataUrl, account.profile);
247
248
  await prompter.note([
248
249
  start.message,
249
- qrPath ? `QR image saved to: ${qrPath}` : "Could not write QR image file; use gateway web login UI instead.",
250
- "Scan + approve on phone, then continue."
251
- ].join("\n"), "QR Login");
250
+ qrPath ? t("wizard.zalouser.qrImageSaved", { path: qrPath }) : t("wizard.zalouser.qrImageWriteFailed"),
251
+ t("wizard.zalouser.scanApproveContinue")
252
+ ].join("\n"), t("wizard.zalouser.qrLoginTitle"));
252
253
  if (await prompter.confirm({
253
- message: "Did you scan and approve the QR on your phone?",
254
+ message: t("wizard.zalouser.qrScannedPrompt"),
254
255
  initialValue: true
255
256
  })) {
256
257
  const waited = await waitForZaloQrLogin({
257
258
  profile: account.profile,
258
259
  timeoutMs: 12e4
259
260
  });
260
- await prompter.note(waited.message, waited.connected ? "Success" : "Login pending");
261
+ await prompter.note(waited.message, waited.connected ? t("common.done") : t("wizard.zalouser.loginPendingTitle"));
261
262
  }
262
- } else await prompter.note(start.message, "Login pending");
263
+ } else await prompter.note(start.message, t("wizard.zalouser.loginPendingTitle"));
263
264
  }
264
265
  } else if (!await prompter.confirm({
265
- message: "Zalo Personal already logged in. Keep session?",
266
+ message: t("wizard.zalouser.keepSessionPrompt"),
266
267
  initialValue: true
267
268
  })) {
268
269
  await logoutZaloProfile(account.profile);
@@ -273,12 +274,12 @@ const zalouserSetupWizard = {
273
274
  });
274
275
  if (start.qrDataUrl) {
275
276
  const qrPath = await writeQrDataUrlToTempFile(start.qrDataUrl, account.profile);
276
- await prompter.note([start.message, qrPath ? `QR image saved to: ${qrPath}` : void 0].filter(Boolean).join("\n"), "QR Login");
277
+ await prompter.note([start.message, qrPath ? t("wizard.zalouser.qrImageSaved", { path: qrPath }) : void 0].filter(Boolean).join("\n"), t("wizard.zalouser.qrLoginTitle"));
277
278
  const waited = await waitForZaloQrLogin({
278
279
  profile: account.profile,
279
280
  timeoutMs: 12e4
280
281
  });
281
- await prompter.note(waited.message, waited.connected ? "Success" : "Login pending");
282
+ await prompter.note(waited.message, waited.connected ? t("common.done") : t("wizard.zalouser.loginPendingTitle"));
282
283
  }
283
284
  }
284
285
  next = setZalouserAccountScopedConfig(next, accountId, { profile: account.profile !== "default" ? account.profile : void 0 }, {
@@ -312,10 +313,10 @@ const zalouserSetupWizard = {
312
313
  resolveAllowlist: async ({ cfg, accountId, entries, prompter }) => {
313
314
  if (entries.length === 0) {
314
315
  await prompter.note([
315
- "No group allowlist entries added yet.",
316
- "Group chats will stay blocked until you add groups later.",
317
- `Tip: use \`${formatCliCommand("openclaw directory groups list --channel zalouser")}\` after onboarding to find group IDs.`,
318
- "Mention requirement stays on by default for groups you allow later."
316
+ t("wizard.zalouser.noGroupAllowlist"),
317
+ t("wizard.zalouser.groupChatsBlocked"),
318
+ t("wizard.zalouser.groupsLookupTip", { command: formatCliCommand("openclaw directory groups list --channel zalouser") }),
319
+ t("wizard.zalouser.groupMentionRequirement")
319
320
  ].join("\n"), ZALOUSER_GROUPS_TITLE);
320
321
  return [];
321
322
  }
@@ -338,7 +339,7 @@ const zalouserSetupWizard = {
338
339
  if (resolution) await prompter.note(resolution, ZALOUSER_GROUPS_TITLE);
339
340
  return keys;
340
341
  } catch (err) {
341
- await prompter.note(`Group lookup failed; keeping entries as typed. ${String(err)}`, ZALOUSER_GROUPS_TITLE);
342
+ await prompter.note(t("wizard.zalouser.groupLookupFailed", { error: String(err) }), ZALOUSER_GROUPS_TITLE);
342
343
  return entries.map((entry) => entry.trim()).filter(Boolean);
343
344
  }
344
345
  },
@@ -11,7 +11,7 @@ import { adaptScopedAccountAccessor, createScopedChannelConfigAdapter } from "op
11
11
  import fsp from "node:fs/promises";
12
12
  import path from "node:path";
13
13
  import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/temp-path";
14
- import { createDelegatedSetupWizardProxy, createPatchedAccountSetupAdapter } from "openclaw/plugin-sdk/setup-runtime";
14
+ import { createDelegatedSetupWizardProxy, createPatchedAccountSetupAdapter, createSetupTranslator } from "openclaw/plugin-sdk/setup-runtime";
15
15
  import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
16
16
  import { z } from "zod";
17
17
  import { createDangerousNameMatchingMutableAllowlistWarningCollector } from "openclaw/plugin-sdk/channel-policy";
@@ -26,6 +26,7 @@ async function writeQrDataUrlToTempFile(qrDataUrl, profile) {
26
26
  }
27
27
  //#endregion
28
28
  //#region extensions/zalouser/src/setup-core.ts
29
+ const t = createSetupTranslator();
29
30
  const channel = "zalouser";
30
31
  const zalouserSetupAdapter = createPatchedAccountSetupAdapter({
31
32
  channelKey: channel,
@@ -37,10 +38,10 @@ function createZalouserSetupWizardProxy(loadWizard) {
37
38
  channel,
38
39
  loadWizard,
39
40
  status: {
40
- configuredLabel: "logged in",
41
- unconfiguredLabel: "needs QR login",
42
- configuredHint: "recommended · logged in",
43
- unconfiguredHint: "recommended · QR login",
41
+ configuredLabel: t("wizard.channels.statusLoggedIn"),
42
+ unconfiguredLabel: t("wizard.channels.statusNeedsQrLogin"),
43
+ configuredHint: t("wizard.channels.statusRecommendedLoggedIn"),
44
+ unconfiguredHint: t("wizard.channels.statusRecommendedQrLogin"),
44
45
  configuredScore: 1,
45
46
  unconfiguredScore: 15
46
47
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/zalouser",
3
- "version": "2026.5.14-beta.2",
3
+ "version": "2026.5.16-beta.1",
4
4
  "description": "OpenClaw Zalo Personal Account plugin via native zca-js integration",
5
5
  "repository": {
6
6
  "type": "git",
@@ -17,7 +17,7 @@
17
17
  "openclaw": "workspace:*"
18
18
  },
19
19
  "peerDependencies": {
20
- "openclaw": ">=2026.5.14-beta.2"
20
+ "openclaw": ">=2026.5.16-beta.1"
21
21
  },
22
22
  "peerDependenciesMeta": {
23
23
  "openclaw": {
@@ -54,10 +54,10 @@
54
54
  "minHostVersion": ">=2026.4.10"
55
55
  },
56
56
  "compat": {
57
- "pluginApi": ">=2026.5.14-beta.2"
57
+ "pluginApi": ">=2026.5.16-beta.1"
58
58
  },
59
59
  "build": {
60
- "openclawVersion": "2026.5.14-beta.2"
60
+ "openclawVersion": "2026.5.16-beta.1"
61
61
  },
62
62
  "release": {
63
63
  "publishToClawHub": true,