cclawd 1.0.0 → 1.0.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.
- package/dist/{active-listener-DYmI7imH.js → active-listener-BLd27Pxd.js} +2 -2
- package/dist/{api-key-rotation-DLU4jvSu.js → api-key-rotation-Dg3JlNDQ.js} +1 -1
- package/dist/{audio-preflight-C9TMbRb4.js → audio-preflight-eV5m9mMp.js} +15 -15
- package/dist/{audio-transcription-runner-Q5zG_hYd.js → audio-transcription-runner-CQU4Eg1M.js} +10 -10
- package/dist/{audit-membership-runtime-DhxSwFnF.js → audit-membership-runtime-hXUuer4x.js} +6 -6
- package/dist/build-info.json +3 -3
- package/dist/bundled/boot-md/handler.js +35 -35
- package/dist/bundled/bootstrap-extra-files/handler.js +5 -5
- package/dist/bundled/command-logger/handler.js +2 -2
- package/dist/bundled/session-memory/handler.js +35 -35
- package/dist/{channel-activity-Bx08UTAg.js → channel-activity-dT3cYb0e.js} +2 -2
- package/dist/{commands-registry-llLVCTH9.js → commands-registry-CyLMCPuP.js} +2 -2
- package/dist/compact.runtime-DGRl4st4.js +39 -0
- package/dist/{deliver-DJf2ZBpe.js → deliver-B6eTtXSk.js} +19 -19
- package/dist/deliver-runtime-CLDpY6AW.js +19 -0
- package/dist/deps-send-discord.runtime-CxADlame.js +19 -0
- package/dist/deps-send-imessage.runtime-Wi79xm6H.js +18 -0
- package/dist/deps-send-signal.runtime-BDtzvsnR.js +17 -0
- package/dist/deps-send-slack.runtime-CgX24hgT.js +17 -0
- package/dist/deps-send-telegram.runtime-CEWc7ePn.js +20 -0
- package/dist/deps-send-whatsapp.runtime-B1KJ7YOp.js +43 -0
- package/dist/{diagnostic-BCCMF3O_.js → diagnostic-BZmAxdu9.js} +2 -2
- package/dist/{env-aYXLHjfZ.js → env-lw2hsIUY.js} +1 -1
- package/dist/{fetch-bvgIiupu.js → fetch-C0iyt-Iz.js} +3 -3
- package/dist/{fetch-DCTUdr1U.js → fetch-CMLoICyN.js} +5 -5
- package/dist/{fetch-guard-CqpEmMQ2.js → fetch-guard-DCj3k042.js} +2 -2
- package/dist/{frontmatter-DjZuS525.js → frontmatter-C_obXuTp.js} +3 -3
- package/dist/{github-copilot-token-CQmATy5E.js → github-copilot-token-8N63GdbE.js} +7 -7
- package/dist/{image-Q8E1-lZn.js → image-Bt49ybRv.js} +4 -4
- package/dist/image-runtime-Cilhq73U.js +12 -0
- package/dist/{ir-CzM3SxId.js → ir-CVtBjUiL.js} +6 -6
- package/dist/llm-slug-generator.js +35 -35
- package/dist/{logger-ChbX1G7s.js → logger-CbUVl62f.js} +7 -7
- package/dist/{login-B0mtU11X.js → login-D0fUoX-p.js} +4 -4
- package/dist/{login-qr-DY_i60f5.js → login-qr-ClBxstxZ.js} +10 -10
- package/dist/{manager-FAQPC0uO.js → manager-DSfEj66R.js} +12 -12
- package/dist/manager-runtime-BrZlGJsj.js +15 -0
- package/dist/{model-selection-wf3OY5DX.js → model-selection-CMEj8bpy.js} +130 -130
- package/dist/{outbound-Bw0dOVS7.js → outbound-BxIJyMzV.js} +6 -6
- package/dist/{outbound-attachment-1R6r9Pg_.js → outbound-attachment-CVJwpypG.js} +2 -2
- package/dist/{paths-C0HLtPu0.js → paths-CehYKFsO.js} +7 -7
- package/dist/{paths-hfkBoC7i.js → paths-DkxwiA8g.js} +5 -5
- package/dist/{pi-embedded-BAHaY-Oh.js → pi-embedded-CHNPEUAv.js} +159 -159
- package/dist/{pi-model-discovery-ItS07aJB.js → pi-model-discovery-D-r5y7kV.js} +7 -7
- package/dist/pi-model-discovery-runtime-DZQXYmdu.js +12 -0
- package/dist/{pi-tools.before-tool-call.runtime-D_mthvtC.js → pi-tools.before-tool-call.runtime-DagGpfw0.js} +10 -10
- package/dist/{proxy-fetch-c1ZUFFcO.js → proxy-fetch-BOh1PLOW.js} +1 -1
- package/dist/{pw-ai-Ok6KGelf.js → pw-ai-CoIUdns_.js} +9 -9
- package/dist/{qmd-manager-DhfEz4Ar.js → qmd-manager-DEscZz5_.js} +6 -6
- package/dist/{query-expansion-GqNV2iIE.js → query-expansion-BErUY8P2.js} +4 -4
- package/dist/runtime-whatsapp-login.runtime-ChqE9BkX.js +13 -0
- package/dist/runtime-whatsapp-outbound.runtime-yiy6jzKk.js +17 -0
- package/dist/{send-DPflcjM5.js → send-4rRrSKp9.js} +6 -6
- package/dist/{send-CEg4P96c.js → send-BKO1-P1t.js} +5 -5
- package/dist/{send-CS0ocZHl.js → send-EDBPXjTT.js} +3 -3
- package/dist/{send-6R8b9zsj.js → send-K2mAG7KC.js} +5 -5
- package/dist/{send-DwAoiT2p.js → send-V1MRV7QF.js} +25 -25
- package/dist/{session-BoIID5UR.js → session-CuVCho2m.js} +7 -7
- package/dist/{skill-commands-DhdiziMs.js → skill-commands-B55LOaMB.js} +9 -9
- package/dist/slash-commands.runtime-BchS0VkW.js +12 -0
- package/dist/slash-dispatch.runtime-BIKRY3fr.js +39 -0
- package/dist/slash-skill-commands.runtime-BP4jBHU9.js +13 -0
- package/dist/subagent-registry-runtime-DjEYzSyM.js +39 -0
- package/dist/{subsystem-C8z6w6xC.js → subsystem-DfXy5gUB.js} +14 -14
- package/dist/{tables-DQusRhkD.js → tables-BAGqh2XD.js} +1 -1
- package/dist/{target-errors-CfavnC9U.js → target-errors-CeBF8Pws.js} +1 -1
- package/dist/{tokens-BWDIKewp.js → tokens-6ul2IrzG.js} +1 -1
- package/dist/{web-CrcrTQ2c.js → web-BRSmQdtm.js} +39 -39
- package/dist/{whatsapp-actions-B0u0ZAme.js → whatsapp-actions-Dxb2K2Xh.js} +15 -15
- package/dist/{workspace-CWDYHR27.js → workspace-DGIcKCCW.js} +20 -20
- package/extensions/mfa-auth/README.md +33 -38
- package/extensions/mfa-auth/index.ts +97 -92
- package/extensions/mfa-auth/node_modules/.bin/qrcode-terminal +1 -6
- package/extensions/mfa-auth/node_modules/.bin/qrcode-terminal.cmd +17 -0
- package/extensions/mfa-auth/node_modules/.bin/qrcode-terminal.ps1 +0 -13
- package/extensions/mfa-auth/node_modules/.bin/tsx +1 -6
- package/extensions/mfa-auth/node_modules/.bin/tsx.cmd +17 -0
- package/extensions/mfa-auth/node_modules/.bin/tsx.ps1 +0 -13
- package/extensions/mfa-auth/node_modules/.package-lock.json +103 -0
- package/extensions/mfa-auth/package-lock.json +115 -0
- package/extensions/mfa-auth/package.json +1 -1
- package/extensions/mfa-auth/src/auth-manager.ts +4 -2
- package/extensions/mfa-auth/src/config.ts +1 -4
- package/extensions/mfa-auth/src/dabby-client.test.ts +68 -147
- package/extensions/mfa-auth/src/dabby-client.ts +70 -89
- package/extensions/mfa-auth/src/feishu-support/index.ts +2 -2
- package/extensions/mfa-auth/src/notification-service.ts +19 -14
- package/extensions/mfa-auth/src/providers/base.ts +0 -1
- package/extensions/mfa-auth/src/providers/qr-code.ts +3 -506
- package/extensions/mfa-auth/src/server.ts +3 -223
- package/extensions/mfa-auth/src/types.ts +13 -36
- package/package.json +458 -460
- package/dist/compact.runtime-BEn3giMt.js +0 -39
- package/dist/deliver-runtime-DkQ3XzGv.js +0 -19
- package/dist/deps-send-discord.runtime-BLpqSj6s.js +0 -19
- package/dist/deps-send-imessage.runtime-BFzyYqvR.js +0 -18
- package/dist/deps-send-signal.runtime-DT0TYCy1.js +0 -17
- package/dist/deps-send-slack.runtime-BhaGFfMX.js +0 -17
- package/dist/deps-send-telegram.runtime-B6Cic9NX.js +0 -20
- package/dist/deps-send-whatsapp.runtime-WtEhIq2S.js +0 -43
- package/dist/image-runtime-B1LFYfQ2.js +0 -12
- package/dist/manager-runtime-Da7ME9vS.js +0 -15
- package/dist/pi-model-discovery-runtime-DjM7Z1fx.js +0 -12
- package/dist/runtime-whatsapp-login.runtime-D4BRhQkK.js +0 -13
- package/dist/runtime-whatsapp-outbound.runtime-DJPpS6g-.js +0 -17
- package/dist/slash-commands.runtime-Cu1lTjV9.js +0 -12
- package/dist/slash-dispatch.runtime-DRVJEF4l.js +0 -39
- package/dist/slash-skill-commands.runtime-C373PJjv.js +0 -13
- package/dist/subagent-registry-runtime-D7hWBo1G.js +0 -39
- package/extensions/mfa-auth/node_modules/.bin/qrcode-terminal.CMD +0 -12
- package/extensions/mfa-auth/node_modules/.bin/tsx.CMD +0 -12
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { r as resolveConfigPath } from "./paths-
|
|
1
|
+
import { r as resolveConfigPath } from "./paths-DkxwiA8g.js";
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import
|
|
4
|
+
import syncFs from "node:fs";
|
|
5
5
|
import chalk, { Chalk } from "chalk";
|
|
6
6
|
import { Logger } from "tslog";
|
|
7
7
|
import JSON5 from "json5";
|
|
@@ -49,15 +49,15 @@ function getCommandPathInternal(argv, depth, opts) {
|
|
|
49
49
|
//#endregion
|
|
50
50
|
//#region src/infra/tmp-openclaw-dir.ts
|
|
51
51
|
const POSIX_OPENCLAW_TMP_DIR = "/tmp/openclaw";
|
|
52
|
-
const TMP_DIR_ACCESS_MODE =
|
|
52
|
+
const TMP_DIR_ACCESS_MODE = syncFs.constants.W_OK | syncFs.constants.X_OK;
|
|
53
53
|
function isNodeErrorWithCode(err, code) {
|
|
54
54
|
return typeof err === "object" && err !== null && "code" in err && err.code === code;
|
|
55
55
|
}
|
|
56
56
|
function resolvePreferredOpenClawTmpDir(options = {}) {
|
|
57
|
-
const accessSync = options.accessSync ??
|
|
58
|
-
const chmodSync = options.chmodSync ??
|
|
59
|
-
const lstatSync = options.lstatSync ??
|
|
60
|
-
const mkdirSync = options.mkdirSync ??
|
|
57
|
+
const accessSync = options.accessSync ?? syncFs.accessSync;
|
|
58
|
+
const chmodSync = options.chmodSync ?? syncFs.chmodSync;
|
|
59
|
+
const lstatSync = options.lstatSync ?? syncFs.lstatSync;
|
|
60
|
+
const mkdirSync = options.mkdirSync ?? syncFs.mkdirSync;
|
|
61
61
|
const warn = options.warn ?? ((message) => console.warn(message));
|
|
62
62
|
const getuid = options.getuid ?? (() => {
|
|
63
63
|
try {
|
|
@@ -149,8 +149,8 @@ function resolvePreferredOpenClawTmpDir(options = {}) {
|
|
|
149
149
|
function readLoggingConfig() {
|
|
150
150
|
const configPath = resolveConfigPath();
|
|
151
151
|
try {
|
|
152
|
-
if (!
|
|
153
|
-
const raw =
|
|
152
|
+
if (!syncFs.existsSync(configPath)) return;
|
|
153
|
+
const raw = syncFs.readFileSync(configPath, "utf-8");
|
|
154
154
|
const logging = JSON5.parse(raw)?.logging;
|
|
155
155
|
if (!logging || typeof logging !== "object" || Array.isArray(logging)) return;
|
|
156
156
|
return logging;
|
|
@@ -332,7 +332,7 @@ function buildLogger(settings) {
|
|
|
332
332
|
for (const transport of externalTransports) attachExternalTransport(logger, transport);
|
|
333
333
|
return logger;
|
|
334
334
|
}
|
|
335
|
-
|
|
335
|
+
syncFs.mkdirSync(path.dirname(settings.file), { recursive: true });
|
|
336
336
|
if (isRollingPath(settings.file)) pruneOldRollingLogs(path.dirname(settings.file));
|
|
337
337
|
let currentFileBytes = getCurrentLogFileBytes(settings.file);
|
|
338
338
|
let warnedAboutSizeCap = false;
|
|
@@ -371,14 +371,14 @@ function resolveMaxLogFileBytes(raw) {
|
|
|
371
371
|
}
|
|
372
372
|
function getCurrentLogFileBytes(file) {
|
|
373
373
|
try {
|
|
374
|
-
return
|
|
374
|
+
return syncFs.statSync(file).size;
|
|
375
375
|
} catch {
|
|
376
376
|
return 0;
|
|
377
377
|
}
|
|
378
378
|
}
|
|
379
379
|
function appendLogLine(file, line) {
|
|
380
380
|
try {
|
|
381
|
-
|
|
381
|
+
syncFs.appendFileSync(file, line, { encoding: "utf8" });
|
|
382
382
|
return true;
|
|
383
383
|
} catch {
|
|
384
384
|
return false;
|
|
@@ -430,14 +430,14 @@ function isRollingPath(file) {
|
|
|
430
430
|
}
|
|
431
431
|
function pruneOldRollingLogs(dir) {
|
|
432
432
|
try {
|
|
433
|
-
const entries =
|
|
433
|
+
const entries = syncFs.readdirSync(dir, { withFileTypes: true });
|
|
434
434
|
const cutoff = Date.now() - MAX_LOG_AGE_MS;
|
|
435
435
|
for (const entry of entries) {
|
|
436
436
|
if (!entry.isFile()) continue;
|
|
437
437
|
if (!entry.name.startsWith(`${LOG_PREFIX}-`) || !entry.name.endsWith(LOG_SUFFIX)) continue;
|
|
438
438
|
const fullPath = path.join(dir, entry.name);
|
|
439
439
|
try {
|
|
440
|
-
if (
|
|
440
|
+
if (syncFs.statSync(fullPath).mtimeMs < cutoff) syncFs.rmSync(fullPath, { force: true });
|
|
441
441
|
} catch {}
|
|
442
442
|
}
|
|
443
443
|
} catch {}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ji as detectMime, lt as sanitizeToolResultImages } from "./model-selection-
|
|
1
|
+
import { ji as detectMime, lt as sanitizeToolResultImages } from "./model-selection-CMEj8bpy.js";
|
|
2
2
|
import fs from "node:fs/promises";
|
|
3
3
|
//#region src/agents/tools/common.ts
|
|
4
4
|
var ToolInputError = class extends Error {
|
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
import { s as resolveStorePath } from "./paths-
|
|
2
|
-
import "./paths-
|
|
3
|
-
import { a as defaultRuntime, b as getChildLogger, d as logVerbose, m as shouldLogVerbose, t as createSubsystemLogger } from "./subsystem-
|
|
4
|
-
import { I as buildGroupHistoryKey, N as DEFAULT_MAIN_KEY, P as buildAgentMainSessionKey, z as normalizeAgentId } from "./workspace-
|
|
5
|
-
import { C as sleep, T as toWhatsappJid, h as normalizeE164, m as jidToE164, o as clamp, p as isSelfChatMode, v as resolveJidToE164 } from "./logger-
|
|
6
|
-
import { $t as recordSessionMetaFromInbound, Ai as saveMediaBuffer, Fr as resolveChannelGroupPolicy, Ir as resolveChannelGroupRequireMention, Vr as resolveGroupSessionKey, Zt as loadSessionStore, ao as loadConfig, br as readWebSelfId, dr as resolveWhatsAppAccount, fr as resolveWhatsAppMediaMaxBytes, hr as logWebSelfId, mr as getWebAuthAgeMs, nc as formatCliCommand, pr as WA_WEB_AUTH_DIR, tn as updateLastRoute, vr as pickWebChannel, wr as webAuthExists } from "./model-selection-
|
|
7
|
-
import "./github-copilot-token-
|
|
1
|
+
import { s as resolveStorePath } from "./paths-CehYKFsO.js";
|
|
2
|
+
import "./paths-DkxwiA8g.js";
|
|
3
|
+
import { a as defaultRuntime, b as getChildLogger, d as logVerbose, m as shouldLogVerbose, t as createSubsystemLogger } from "./subsystem-DfXy5gUB.js";
|
|
4
|
+
import { I as buildGroupHistoryKey, N as DEFAULT_MAIN_KEY, P as buildAgentMainSessionKey, z as normalizeAgentId } from "./workspace-DGIcKCCW.js";
|
|
5
|
+
import { C as sleep, T as toWhatsappJid, h as normalizeE164, m as jidToE164, o as clamp, p as isSelfChatMode, v as resolveJidToE164 } from "./logger-CbUVl62f.js";
|
|
6
|
+
import { $t as recordSessionMetaFromInbound, Ai as saveMediaBuffer, Fr as resolveChannelGroupPolicy, Ir as resolveChannelGroupRequireMention, Vr as resolveGroupSessionKey, Zt as loadSessionStore, ao as loadConfig, br as readWebSelfId, dr as resolveWhatsAppAccount, fr as resolveWhatsAppMediaMaxBytes, hr as logWebSelfId, mr as getWebAuthAgeMs, nc as formatCliCommand, pr as WA_WEB_AUTH_DIR, tn as updateLastRoute, vr as pickWebChannel, wr as webAuthExists } from "./model-selection-CMEj8bpy.js";
|
|
7
|
+
import "./github-copilot-token-8N63GdbE.js";
|
|
8
8
|
import "./boolean-C7Ct_klp.js";
|
|
9
|
-
import "./env-
|
|
10
|
-
import "./frontmatter-
|
|
11
|
-
import "./send-
|
|
12
|
-
import { At as resolveOpenProviderRuntimeGroupPolicy, jt as warnMissingProviderGroupPolicyFallbackOnce, kt as resolveDefaultGroupPolicy } from "./send-
|
|
13
|
-
import { A as enqueueSystemEvent, C as formatInboundEnvelope, D as computeBackoff, E as parseActivationCommand, F as finalizeInboundContext, I as hasControlCommand, J as createDedupeCache, L as shouldComputeCommandAuthorized, M as deriveLastRoutePolicy, N as resolveAgentRoute, O as sleepWithAbort, P as resolveInboundLastRouteSessionKey, R as buildMentionRegexes, S as resolveInboundDebounceMs, T as normalizeGroupActivation, X as resolveMessagePrefix, Y as resolveIdentityNamePrefix, _ as resolvePinnedMainDmOwnerFromAllowlist, a as resolveInboundSessionEnvelopeContext, c as createConnectedChannelStatusPatch, d as createReplyPrefixOptions, f as buildHistoryContextFromEntries, g as resolveDmGroupAccessWithLists, h as resolveDmGroupAccessWithCommandGate, j as buildAgentSessionKey, k as formatDurationPrecise, l as issuePairingChallenge, m as readStoreAllowFromForDmPolicy, p as recordPendingHistoryEntryIfEnabled, u as resolveMentionGating, v as shouldAckReactionForWhatsApp, w as getReplyFromConfig, x as createInboundDebouncer, y as dispatchReplyWithBufferedBlockDispatcher, z as normalizeMentionText } from "./pi-embedded-
|
|
14
|
-
import "./tokens-
|
|
15
|
-
import "./deliver-
|
|
16
|
-
import "./diagnostic-
|
|
17
|
-
import { $ as toLocationContext, Q as formatLocationText, rt as upsertChannelPairingRequest } from "./send-
|
|
18
|
-
import "./pi-model-discovery-
|
|
19
|
-
import "./image-
|
|
20
|
-
import { _ as registerUnhandledRejectionHandler } from "./audio-transcription-runner-
|
|
21
|
-
import { i as getAgentScopedMediaLocalRoots } from "./fetch-
|
|
22
|
-
import "./fetch-guard-
|
|
23
|
-
import "./api-key-rotation-
|
|
24
|
-
import "./proxy-fetch-
|
|
25
|
-
import { a as loadWebMedia, d as chunkMarkdownTextWithMode, h as resolveTextChunkLimit, m as resolveChunkMode, s as resolveMarkdownTableMode } from "./ir-
|
|
9
|
+
import "./env-lw2hsIUY.js";
|
|
10
|
+
import "./frontmatter-C_obXuTp.js";
|
|
11
|
+
import "./send-BKO1-P1t.js";
|
|
12
|
+
import { At as resolveOpenProviderRuntimeGroupPolicy, jt as warnMissingProviderGroupPolicyFallbackOnce, kt as resolveDefaultGroupPolicy } from "./send-4rRrSKp9.js";
|
|
13
|
+
import { A as enqueueSystemEvent, C as formatInboundEnvelope, D as computeBackoff, E as parseActivationCommand, F as finalizeInboundContext, I as hasControlCommand, J as createDedupeCache, L as shouldComputeCommandAuthorized, M as deriveLastRoutePolicy, N as resolveAgentRoute, O as sleepWithAbort, P as resolveInboundLastRouteSessionKey, R as buildMentionRegexes, S as resolveInboundDebounceMs, T as normalizeGroupActivation, X as resolveMessagePrefix, Y as resolveIdentityNamePrefix, _ as resolvePinnedMainDmOwnerFromAllowlist, a as resolveInboundSessionEnvelopeContext, c as createConnectedChannelStatusPatch, d as createReplyPrefixOptions, f as buildHistoryContextFromEntries, g as resolveDmGroupAccessWithLists, h as resolveDmGroupAccessWithCommandGate, j as buildAgentSessionKey, k as formatDurationPrecise, l as issuePairingChallenge, m as readStoreAllowFromForDmPolicy, p as recordPendingHistoryEntryIfEnabled, u as resolveMentionGating, v as shouldAckReactionForWhatsApp, w as getReplyFromConfig, x as createInboundDebouncer, y as dispatchReplyWithBufferedBlockDispatcher, z as normalizeMentionText } from "./pi-embedded-CHNPEUAv.js";
|
|
14
|
+
import "./tokens-6ul2IrzG.js";
|
|
15
|
+
import "./deliver-B6eTtXSk.js";
|
|
16
|
+
import "./diagnostic-BZmAxdu9.js";
|
|
17
|
+
import { $ as toLocationContext, Q as formatLocationText, rt as upsertChannelPairingRequest } from "./send-V1MRV7QF.js";
|
|
18
|
+
import "./pi-model-discovery-D-r5y7kV.js";
|
|
19
|
+
import "./image-Bt49ybRv.js";
|
|
20
|
+
import { _ as registerUnhandledRejectionHandler } from "./audio-transcription-runner-CQU4Eg1M.js";
|
|
21
|
+
import { i as getAgentScopedMediaLocalRoots } from "./fetch-CMLoICyN.js";
|
|
22
|
+
import "./fetch-guard-DCj3k042.js";
|
|
23
|
+
import "./api-key-rotation-Dg3JlNDQ.js";
|
|
24
|
+
import "./proxy-fetch-BOh1PLOW.js";
|
|
25
|
+
import { a as loadWebMedia, d as chunkMarkdownTextWithMode, h as resolveTextChunkLimit, m as resolveChunkMode, s as resolveMarkdownTableMode } from "./ir-CVtBjUiL.js";
|
|
26
26
|
import "./render-IRnn-2gt.js";
|
|
27
|
-
import "./target-errors-
|
|
28
|
-
import "./commands-registry-
|
|
29
|
-
import "./skill-commands-
|
|
27
|
+
import "./target-errors-CeBF8Pws.js";
|
|
28
|
+
import "./commands-registry-CyLMCPuP.js";
|
|
29
|
+
import "./skill-commands-B55LOaMB.js";
|
|
30
30
|
import "./fetch-CeWULXBI.js";
|
|
31
|
-
import { n as recordChannelActivity } from "./channel-activity-
|
|
32
|
-
import { t as convertMarkdownTables } from "./tables-
|
|
33
|
-
import "./send-
|
|
34
|
-
import "./outbound-attachment-
|
|
35
|
-
import "./send-
|
|
36
|
-
import "./fetch-
|
|
37
|
-
import { r as setActiveWebListener } from "./active-listener-
|
|
38
|
-
import "./manager-
|
|
39
|
-
import "./query-expansion-
|
|
40
|
-
import { i as markdownToWhatsApp, r as sendReactionWhatsApp, t as sendMessageWhatsApp } from "./outbound-
|
|
41
|
-
import { i as waitForWaConnection, n as formatError, r as getStatusCode, t as createWaSocket } from "./session-
|
|
42
|
-
import { t as loginWeb } from "./login-
|
|
31
|
+
import { n as recordChannelActivity } from "./channel-activity-dT3cYb0e.js";
|
|
32
|
+
import { t as convertMarkdownTables } from "./tables-BAGqh2XD.js";
|
|
33
|
+
import "./send-EDBPXjTT.js";
|
|
34
|
+
import "./outbound-attachment-CVJwpypG.js";
|
|
35
|
+
import "./send-K2mAG7KC.js";
|
|
36
|
+
import "./fetch-C0iyt-Iz.js";
|
|
37
|
+
import { r as setActiveWebListener } from "./active-listener-BLd27Pxd.js";
|
|
38
|
+
import "./manager-DSfEj66R.js";
|
|
39
|
+
import "./query-expansion-BErUY8P2.js";
|
|
40
|
+
import { i as markdownToWhatsApp, r as sendReactionWhatsApp, t as sendMessageWhatsApp } from "./outbound-BxIJyMzV.js";
|
|
41
|
+
import { i as waitForWaConnection, n as formatError, r as getStatusCode, t as createWaSocket } from "./session-CuVCho2m.js";
|
|
42
|
+
import { t as loginWeb } from "./login-D0fUoX-p.js";
|
|
43
43
|
import { randomUUID } from "node:crypto";
|
|
44
44
|
import { DisconnectReason, downloadMediaMessage, extractMessageContent, getContentType, isJidGroup, normalizeMessageContent } from "@whiskeysockets/baileys";
|
|
45
45
|
const DEFAULT_RECONNECT_POLICY = {
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import "./paths-
|
|
2
|
-
import "./paths-
|
|
3
|
-
import "./subsystem-
|
|
4
|
-
import "./workspace-
|
|
5
|
-
import "./logger-
|
|
6
|
-
import { Dr as normalizeWhatsAppTarget, Er as isWhatsAppGroupJid, dr as resolveWhatsAppAccount } from "./model-selection-
|
|
7
|
-
import "./github-copilot-token-
|
|
1
|
+
import "./paths-CehYKFsO.js";
|
|
2
|
+
import "./paths-DkxwiA8g.js";
|
|
3
|
+
import "./subsystem-DfXy5gUB.js";
|
|
4
|
+
import "./workspace-DGIcKCCW.js";
|
|
5
|
+
import "./logger-CbUVl62f.js";
|
|
6
|
+
import { Dr as normalizeWhatsAppTarget, Er as isWhatsAppGroupJid, dr as resolveWhatsAppAccount } from "./model-selection-CMEj8bpy.js";
|
|
7
|
+
import "./github-copilot-token-8N63GdbE.js";
|
|
8
8
|
import "./boolean-C7Ct_klp.js";
|
|
9
|
-
import "./env-
|
|
10
|
-
import "./frontmatter-
|
|
11
|
-
import "./fetch-
|
|
12
|
-
import "./fetch-guard-
|
|
13
|
-
import "./ir-
|
|
9
|
+
import "./env-lw2hsIUY.js";
|
|
10
|
+
import "./frontmatter-C_obXuTp.js";
|
|
11
|
+
import "./fetch-CMLoICyN.js";
|
|
12
|
+
import "./fetch-guard-DCj3k042.js";
|
|
13
|
+
import "./ir-CVtBjUiL.js";
|
|
14
14
|
import "./render-IRnn-2gt.js";
|
|
15
|
-
import { f as readReactionParams, h as readStringParam, i as ToolAuthorizationError, l as jsonResult, n as missingTargetError, o as createActionGate } from "./target-errors-
|
|
16
|
-
import "./tables-
|
|
17
|
-
import { r as sendReactionWhatsApp } from "./outbound-
|
|
15
|
+
import { f as readReactionParams, h as readStringParam, i as ToolAuthorizationError, l as jsonResult, n as missingTargetError, o as createActionGate } from "./target-errors-CeBF8Pws.js";
|
|
16
|
+
import "./tables-BAGqh2XD.js";
|
|
17
|
+
import { r as sendReactionWhatsApp } from "./outbound-BxIJyMzV.js";
|
|
18
18
|
//#region src/whatsapp/resolve-outbound-target.ts
|
|
19
19
|
function resolveWhatsAppOutboundTarget(params) {
|
|
20
20
|
const trimmed = params.to?.trim() ?? "";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { d as resolveRequiredHomeDir } from "./paths-
|
|
2
|
-
import { l as danger, m as shouldLogVerbose } from "./subsystem-
|
|
3
|
-
import { g as pathExists$1, n as logError, t as logDebug, y as resolveUserPath } from "./logger-
|
|
1
|
+
import { d as resolveRequiredHomeDir } from "./paths-DkxwiA8g.js";
|
|
2
|
+
import { l as danger, m as shouldLogVerbose } from "./subsystem-DfXy5gUB.js";
|
|
3
|
+
import { g as pathExists$1, n as logError, t as logDebug, y as resolveUserPath } from "./logger-CbUVl62f.js";
|
|
4
4
|
import fs from "node:fs/promises";
|
|
5
5
|
import os from "node:os";
|
|
6
6
|
import path from "node:path";
|
|
7
|
-
import
|
|
7
|
+
import syncFs from "node:fs";
|
|
8
8
|
import { promisify } from "node:util";
|
|
9
9
|
import { execFile, spawn } from "node:child_process";
|
|
10
10
|
import process$1 from "node:process";
|
|
@@ -566,7 +566,7 @@ function resolveBoundaryPathLexicalSync(params) {
|
|
|
566
566
|
rootCanonicalPath: params.rootCanonicalPath,
|
|
567
567
|
resolveParams: params.params,
|
|
568
568
|
absolutePath: params.absolutePath,
|
|
569
|
-
read: (cursor) =>
|
|
569
|
+
read: (cursor) => syncFs.lstatSync(cursor)
|
|
570
570
|
});
|
|
571
571
|
if (isPromiseLike(maybeStat)) throw new Error("Unexpected async lexical stat");
|
|
572
572
|
const stat = maybeStat;
|
|
@@ -716,15 +716,15 @@ function resolvePathViaExistingAncestorSync(targetPath) {
|
|
|
716
716
|
const normalized = path.resolve(targetPath);
|
|
717
717
|
let cursor = normalized;
|
|
718
718
|
const missingSuffix = [];
|
|
719
|
-
while (!isFilesystemRoot(cursor) && !
|
|
719
|
+
while (!isFilesystemRoot(cursor) && !syncFs.existsSync(cursor)) {
|
|
720
720
|
missingSuffix.unshift(path.basename(cursor));
|
|
721
721
|
const parent = path.dirname(cursor);
|
|
722
722
|
if (parent === cursor) break;
|
|
723
723
|
cursor = parent;
|
|
724
724
|
}
|
|
725
|
-
if (!
|
|
725
|
+
if (!syncFs.existsSync(cursor)) return normalized;
|
|
726
726
|
try {
|
|
727
|
-
const resolvedAncestor = path.resolve(
|
|
727
|
+
const resolvedAncestor = path.resolve(syncFs.realpathSync(cursor));
|
|
728
728
|
if (missingSuffix.length === 0) return resolvedAncestor;
|
|
729
729
|
return path.resolve(resolvedAncestor, ...missingSuffix);
|
|
730
730
|
} catch {
|
|
@@ -749,7 +749,7 @@ function getPathKindSync(absolutePath, preserveFinalSymlink) {
|
|
|
749
749
|
try {
|
|
750
750
|
return {
|
|
751
751
|
exists: true,
|
|
752
|
-
kind: toResolvedKind(preserveFinalSymlink ?
|
|
752
|
+
kind: toResolvedKind(preserveFinalSymlink ? syncFs.lstatSync(absolutePath) : syncFs.statSync(absolutePath))
|
|
753
753
|
};
|
|
754
754
|
} catch (error) {
|
|
755
755
|
if (isNotFoundPathError(error)) return {
|
|
@@ -809,10 +809,10 @@ async function resolveSymlinkHopPath(symlinkPath) {
|
|
|
809
809
|
}
|
|
810
810
|
function resolveSymlinkHopPathSync(symlinkPath) {
|
|
811
811
|
try {
|
|
812
|
-
return path.resolve(
|
|
812
|
+
return path.resolve(syncFs.realpathSync(symlinkPath));
|
|
813
813
|
} catch (error) {
|
|
814
814
|
if (!isNotFoundPathError(error)) throw error;
|
|
815
|
-
const linkTarget =
|
|
815
|
+
const linkTarget = syncFs.readlinkSync(symlinkPath);
|
|
816
816
|
return resolvePathViaExistingAncestorSync(path.resolve(path.dirname(symlinkPath), linkTarget));
|
|
817
817
|
}
|
|
818
818
|
}
|
|
@@ -836,7 +836,7 @@ function sameFileIdentity(left, right) {
|
|
|
836
836
|
return sameFileIdentity$1(left, right);
|
|
837
837
|
}
|
|
838
838
|
function openVerifiedFileSync(params) {
|
|
839
|
-
const ioFs = params.ioFs ??
|
|
839
|
+
const ioFs = params.ioFs ?? syncFs;
|
|
840
840
|
const allowedType = params.allowedType ?? "file";
|
|
841
841
|
const openReadFlags = ioFs.constants.O_RDONLY | (typeof ioFs.constants.O_NOFOLLOW === "number" ? ioFs.constants.O_NOFOLLOW : 0);
|
|
842
842
|
let fd = null;
|
|
@@ -912,7 +912,7 @@ function canUseBoundaryFileOpen(ioFs) {
|
|
|
912
912
|
return typeof ioFs.openSync === "function" && typeof ioFs.closeSync === "function" && typeof ioFs.fstatSync === "function" && typeof ioFs.lstatSync === "function" && typeof ioFs.realpathSync === "function" && typeof ioFs.readFileSync === "function" && typeof ioFs.constants === "object" && ioFs.constants !== null;
|
|
913
913
|
}
|
|
914
914
|
function openBoundaryFileSync(params) {
|
|
915
|
-
const ioFs = params.ioFs ??
|
|
915
|
+
const ioFs = params.ioFs ?? syncFs;
|
|
916
916
|
const resolved = resolveBoundaryFilePathGeneric({
|
|
917
917
|
absolutePath: params.absolutePath,
|
|
918
918
|
resolve: (absolutePath) => resolveBoundaryPathSync({
|
|
@@ -963,7 +963,7 @@ function finalizeBoundaryFileOpen(params) {
|
|
|
963
963
|
});
|
|
964
964
|
}
|
|
965
965
|
async function openBoundaryFile(params) {
|
|
966
|
-
const ioFs = params.ioFs ??
|
|
966
|
+
const ioFs = params.ioFs ?? syncFs;
|
|
967
967
|
const maybeResolved = resolveBoundaryFilePathGeneric({
|
|
968
968
|
absolutePath: params.absolutePath,
|
|
969
969
|
resolve: (absolutePath) => resolveBoundaryPath({
|
|
@@ -1119,7 +1119,7 @@ function resolveNpmArgvForWindows(argv) {
|
|
|
1119
1119
|
if (!cliName) return null;
|
|
1120
1120
|
const nodeDir = path.dirname(process$1.execPath);
|
|
1121
1121
|
const cliPath = path.join(nodeDir, "node_modules", "npm", "bin", cliName);
|
|
1122
|
-
if (!
|
|
1122
|
+
if (!syncFs.existsSync(cliPath)) {
|
|
1123
1123
|
const command = argv[0] ?? "";
|
|
1124
1124
|
return [path.extname(command).toLowerCase() ? command : `${command}.cmd`, ...argv.slice(1)];
|
|
1125
1125
|
}
|
|
@@ -1323,7 +1323,7 @@ async function readPackageName(dir) {
|
|
|
1323
1323
|
}
|
|
1324
1324
|
function readPackageNameSync(dir) {
|
|
1325
1325
|
try {
|
|
1326
|
-
const raw =
|
|
1326
|
+
const raw = syncFs.readFileSync(path.join(dir, "package.json"), "utf-8");
|
|
1327
1327
|
const parsed = JSON.parse(raw);
|
|
1328
1328
|
return typeof parsed.name === "string" ? parsed.name : null;
|
|
1329
1329
|
} catch {
|
|
@@ -1357,7 +1357,7 @@ function candidateDirsFromArgv1(argv1) {
|
|
|
1357
1357
|
const normalized = path.resolve(argv1);
|
|
1358
1358
|
const candidates = [path.dirname(normalized)];
|
|
1359
1359
|
try {
|
|
1360
|
-
const resolved =
|
|
1360
|
+
const resolved = syncFs.realpathSync(normalized);
|
|
1361
1361
|
if (resolved !== normalized) candidates.push(path.dirname(resolved));
|
|
1362
1362
|
} catch {}
|
|
1363
1363
|
const parts = normalized.split(path.sep);
|
|
@@ -1469,14 +1469,14 @@ async function readWorkspaceFileWithGuards(params) {
|
|
|
1469
1469
|
const identity = workspaceFileIdentity(opened.stat, opened.path);
|
|
1470
1470
|
const cached = workspaceFileCache.get(params.filePath);
|
|
1471
1471
|
if (cached && cached.identity === identity) {
|
|
1472
|
-
|
|
1472
|
+
syncFs.closeSync(opened.fd);
|
|
1473
1473
|
return {
|
|
1474
1474
|
ok: true,
|
|
1475
1475
|
content: cached.content
|
|
1476
1476
|
};
|
|
1477
1477
|
}
|
|
1478
1478
|
try {
|
|
1479
|
-
const content =
|
|
1479
|
+
const content = syncFs.readFileSync(opened.fd, "utf-8");
|
|
1480
1480
|
workspaceFileCache.set(params.filePath, {
|
|
1481
1481
|
content,
|
|
1482
1482
|
identity
|
|
@@ -1493,7 +1493,7 @@ async function readWorkspaceFileWithGuards(params) {
|
|
|
1493
1493
|
error
|
|
1494
1494
|
};
|
|
1495
1495
|
} finally {
|
|
1496
|
-
|
|
1496
|
+
syncFs.closeSync(opened.fd);
|
|
1497
1497
|
}
|
|
1498
1498
|
}
|
|
1499
1499
|
function stripFrontMatter(content) {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
插件主要由以下几个部分组成:
|
|
18
18
|
|
|
19
19
|
- **AuthManager (`src/auth-manager.ts`)**: 核心管理器,负责维护用户的验证状态(敏感操作权限、首次对话权限)和管理验证会话(AuthSession)。
|
|
20
|
-
- **
|
|
20
|
+
- **Notification Service (`src/notification-service.ts`)**: 通知服务,负责将认证消息发送到不同的聊天渠道。
|
|
21
21
|
- **拦截钩子 (`index.ts`)**:
|
|
22
22
|
- `before_tool_call`: 拦截工具调用,检查命令是否包含敏感词。
|
|
23
23
|
- `message_received`: 拦截用户消息,检查是否为新用户首次对话。
|
|
@@ -31,7 +31,6 @@ sequenceDiagram
|
|
|
31
31
|
participant Channel as 聊天频道
|
|
32
32
|
participant OpenClaw as OpenClaw核心
|
|
33
33
|
participant Plugin as MFA插件
|
|
34
|
-
participant Browser as 验证页面
|
|
35
34
|
participant Dabby as 权威认证服务
|
|
36
35
|
participant Polling as 轮询机制
|
|
37
36
|
|
|
@@ -42,15 +41,13 @@ sequenceDiagram
|
|
|
42
41
|
alt 需要认证 (首次对话 或 敏感操作 或 重新认证)
|
|
43
42
|
Plugin->>Plugin: 检查本地认证状态
|
|
44
43
|
Plugin->>Dabby: 请求实名认证二维码
|
|
45
|
-
Dabby-->>Plugin:
|
|
44
|
+
Dabby-->>Plugin: 返回二维码URL (qrCodeUrl)
|
|
46
45
|
Plugin->>Plugin: 创建验证会话 (Session)
|
|
47
|
-
Plugin-->>Channel: 发送验证链接
|
|
46
|
+
Plugin-->>Channel: 发送验证链接 (qrCodeUrl)
|
|
48
47
|
Channel-->>User: 显示验证链接消息
|
|
49
48
|
Plugin->>Polling: 启动轮询 (每2秒)
|
|
50
49
|
|
|
51
|
-
User->>
|
|
52
|
-
Browser->>Dabby: 展示二维码
|
|
53
|
-
User->>Dabby: 手机扫码认证
|
|
50
|
+
User->>Dabby: 点击链接扫码认证
|
|
54
51
|
Plugin->>Plugin: 更新用户认证状态 (持久化)
|
|
55
52
|
|
|
56
53
|
Polling->>Plugin: 检测到认证成功
|
|
@@ -65,10 +62,11 @@ sequenceDiagram
|
|
|
65
62
|
|
|
66
63
|
**关键机制说明**:
|
|
67
64
|
|
|
68
|
-
1.
|
|
69
|
-
2.
|
|
70
|
-
3.
|
|
71
|
-
4.
|
|
65
|
+
1. **直接显示认证链接**:插件直接在聊天中发送后端 API 返回的 `qrCodeUrl` 链接,无需启动本地 HTTP 服务器
|
|
66
|
+
2. **聊天侧轮询**:插件在发送认证链接后,启动一个每 2 秒轮询一次的检测机制
|
|
67
|
+
3. **原子通知**:使用 `checkAndConsumeNotification` 确保认证成功消息只发送一次
|
|
68
|
+
4. **场景化消息**:根据不同场景(首次认证、重新认证、二次认证)发送不同的成功消息
|
|
69
|
+
5. **超时保护**:轮询会在 `config.timeout + 10秒` 后自动停止
|
|
72
70
|
|
|
73
71
|
## 通知机制
|
|
74
72
|
|
|
@@ -83,11 +81,11 @@ sequenceDiagram
|
|
|
83
81
|
|
|
84
82
|
### 通知消息类型
|
|
85
83
|
|
|
86
|
-
| 场景
|
|
87
|
-
|
|
88
|
-
| 首次认证 | 用户首次通过认证
|
|
89
|
-
| 重新认证 | 用户通过 `/reauth` 命令重新认证 | `✅ 重新认证成功,请继续对话。`
|
|
90
|
-
| 二次认证 | 用户通过敏感操作认证
|
|
84
|
+
| 场景 | 触发条件 | 消息内容 |
|
|
85
|
+
| -------- | ------------------------------- | ----------------------------------------------------------------- |
|
|
86
|
+
| 首次认证 | 用户首次通过认证 | `✅ 首次认证成功,请继续对话。` |
|
|
87
|
+
| 重新认证 | 用户通过 `/reauth` 命令重新认证 | `✅ 重新认证成功,请继续对话。` |
|
|
88
|
+
| 二次认证 | 用户通过敏感操作认证 | `✅ 二次认证成功,请重新发送之前的命令(或回复'确认')即可执行。` |
|
|
91
89
|
|
|
92
90
|
### 防重复机制
|
|
93
91
|
|
|
@@ -103,11 +101,11 @@ sequenceDiagram
|
|
|
103
101
|
|
|
104
102
|
本插件目前支持以下聊天渠道:
|
|
105
103
|
|
|
106
|
-
| 渠道 | 状态 | 说明
|
|
107
|
-
| :----------------------------------------------------------------- | :---------- |
|
|
108
|
-
| **飞书 (Feishu/Lark)** | ✅ 完全支持 | 通过飞书 API 发送认证链接
|
|
109
|
-
| **Web/Webchat**
|
|
110
|
-
| 其他渠道 (Telegram, Discord, Slack, Signal, iMessage, WhatsApp 等) | ⚠️ 暂不支持 | 待开发
|
|
104
|
+
| 渠道 | 状态 | 说明 |
|
|
105
|
+
| :----------------------------------------------------------------- | :---------- | :-------------------------- |
|
|
106
|
+
| **飞书 (Feishu/Lark)** | ✅ 完全支持 | 通过飞书 API 发送认证链接 |
|
|
107
|
+
| **Web/Webchat** | ✅ 完全支持 | 通过 WebSocket 发送认证链接 |
|
|
108
|
+
| 其他渠道 (Telegram, Discord, Slack, Signal, iMessage, WhatsApp 等) | ⚠️ 暂不支持 | 待开发 |
|
|
111
109
|
|
|
112
110
|
**注意**:
|
|
113
111
|
|
|
@@ -136,8 +134,7 @@ npm install
|
|
|
136
134
|
# --- MFA 认证扩展配置 ---
|
|
137
135
|
|
|
138
136
|
# 权威认证服务账号 (必填)
|
|
139
|
-
|
|
140
|
-
DABBY_CLIENT_SECRET=your_client_secret_here
|
|
137
|
+
MFA_AUTH_API_KEY=your_api_key_here
|
|
141
138
|
|
|
142
139
|
# 敏感操作关键词 (自定义拦截列表)
|
|
143
140
|
# 只有当命令中包含这些关键词时,才会被拦截
|
|
@@ -153,17 +150,11 @@ MFA_VERIFICATION_DURATION=120000 # 敏感操作验证有效期 (2分
|
|
|
153
150
|
|
|
154
151
|
# 存储路径
|
|
155
152
|
MFA_AUTH_STATE_DIR=~/.openclaw/mfa-auth/ # 认证状态持久化目录
|
|
156
|
-
|
|
157
153
|
```
|
|
158
154
|
|
|
159
155
|
**配置详解:**
|
|
160
156
|
|
|
161
|
-
- `
|
|
162
|
-
- `DABBY_CLIENT_SECRET`: 权威认证服务的 Client Secret。
|
|
163
|
-
- `MFA_AUTH_DOMAIN`: **重要!** 如果你的服务器部署在云端,用户无法直接访问内网 IP,请配置此项。
|
|
164
|
-
- 示例:`http://auth.example.com` 或 `https://auth.example.com`
|
|
165
|
-
- 如果包含协议头(http/https),插件将直接使用该 URL 前缀,不再附加端口号。
|
|
166
|
-
- 如果不包含协议头,插件会自动附加 `http://` 和端口号(默认 18801)。
|
|
157
|
+
- `MFA_AUTH_API_KEY`: 权威认证服务的 API Key。
|
|
167
158
|
|
|
168
159
|
**可选配置:**
|
|
169
160
|
|
|
@@ -215,10 +206,12 @@ MFA_AUTH_STATE_DIR=~/.openclaw/mfa-auth/ # 认证状态持久化目录
|
|
|
215
206
|
|
|
216
207
|
**OpenClaw (MFA 插件)**:
|
|
217
208
|
|
|
218
|
-
>
|
|
209
|
+
> 🔐 **首次对话需要进行认证**
|
|
210
|
+
>
|
|
211
|
+
> 为了您的账户安全,首次对话前需要完成身份验证。
|
|
219
212
|
>
|
|
220
|
-
>
|
|
221
|
-
>
|
|
213
|
+
> 📱 请点击以下链接完成扫码认证:
|
|
214
|
+
> https://auth.example.com/qr-code?token=abc123...
|
|
222
215
|
>
|
|
223
216
|
> 验证有效期: 5 分钟
|
|
224
217
|
|
|
@@ -235,8 +228,10 @@ MFA_AUTH_STATE_DIR=~/.openclaw/mfa-auth/ # 认证状态持久化目录
|
|
|
235
228
|
|
|
236
229
|
> ⚠️ **🔐 该操作需要二次认证**
|
|
237
230
|
>
|
|
238
|
-
>
|
|
239
|
-
>
|
|
231
|
+
> 检测到敏感操作: delete一下我电脑桌面的test.txt文件
|
|
232
|
+
>
|
|
233
|
+
> 📱 请点击以下链接完成扫码认证:
|
|
234
|
+
> https://auth.example.com/qr-code?token=def456...
|
|
240
235
|
>
|
|
241
236
|
> 验证有效期: 5 分钟
|
|
242
237
|
>
|
|
@@ -257,10 +252,10 @@ MFA_AUTH_STATE_DIR=~/.openclaw/mfa-auth/ # 认证状态持久化目录
|
|
|
257
252
|
|
|
258
253
|
> 🔐 **重新认证**
|
|
259
254
|
>
|
|
260
|
-
>
|
|
261
|
-
>
|
|
255
|
+
> 📱 请点击以下链接完成扫码认证:
|
|
256
|
+
> https://auth.example.com/qr-code?token=ghi789...
|
|
262
257
|
>
|
|
263
|
-
>
|
|
258
|
+
> 验证有效期: 5 分钟
|
|
264
259
|
|
|
265
260
|
**用户**:(点击链接 -> 扫码认证成功)
|
|
266
261
|
**OpenClaw (MFA 插件轮询检测到认证)**:
|