winclaw 2026.3.32 → 2026.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{banner-DPOw4Y5Z.js → banner-CrUQs7By.js} +1 -1
- package/dist/build-info.json +2 -2
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/{command-registry-0y2xBLj0.js → command-registry-DoH9LuuA.js} +4 -4
- package/dist/{completion-cli-DOjD8RjQ.js → completion-cli-CyCV3ZHh.js} +2 -2
- package/dist/{completion-cli-D_r7Agv7.js → completion-cli-D5AGXrau.js} +1 -1
- package/dist/{doctor-completion-vm65W1rC.js → doctor-completion-B7rNU63W.js} +1 -1
- package/dist/{doctor-completion-UANUtpOr.js → doctor-completion-Drs7WusO.js} +1 -1
- package/dist/entry.js +2 -2
- package/dist/{gateway-cli-BGUFZVFD.js → gateway-cli-CPQ759ko.js} +32 -8
- package/dist/{gateway-cli-fCcYxOiD.js → gateway-cli-JvKJCIvQ.js} +32 -8
- package/dist/index.js +2 -2
- package/dist/{onboard-B2Y_r1_l.js → onboard-DEir-GQ1.js} +1 -1
- package/dist/{onboard-D8Adq_r9.js → onboard-NcAbd8BT.js} +1 -1
- package/dist/{onboarding-CPrdZaF8.js → onboarding-BA6Xzjvi.js} +1 -1
- package/dist/{onboarding-BmR6zht0.js → onboarding-cdo8bLhe.js} +1 -1
- package/dist/{onboarding.finalize-CBSdaN18.js → onboarding.finalize-0mWawAfn.js} +3 -3
- package/dist/{onboarding.finalize-Voe0WOEw.js → onboarding.finalize-Bicw2cW7.js} +4 -4
- package/dist/plugin-sdk/accounts-DjWKwOkO.js +288 -0
- package/dist/plugin-sdk/accounts-Dz2fIa1b.js +35 -0
- package/dist/plugin-sdk/accounts-XkCq-GgE.js +46 -0
- package/dist/plugin-sdk/active-listener-CaEe5rVE.js +50 -0
- package/dist/plugin-sdk/api-key-rotation-7PiUPffv.js +181 -0
- package/dist/plugin-sdk/audio-preflight-BvpK6N8Y.js +69 -0
- package/dist/plugin-sdk/audio-transcription-runner-ckmtzFYH.js +2176 -0
- package/dist/plugin-sdk/audit-membership-runtime-Bv06Vdg2.js +58 -0
- package/dist/plugin-sdk/bluebubbles.js +2 -2
- package/dist/plugin-sdk/channel-activity-vwBB2P3P.js +94 -0
- package/dist/plugin-sdk/channel-web-DcohlXKX.js +2256 -0
- package/dist/plugin-sdk/chrome-CYDRV_JZ.js +2415 -0
- package/dist/plugin-sdk/commands-registry-mceI9AhZ.js +1125 -0
- package/dist/plugin-sdk/compat.js +50 -50
- package/dist/plugin-sdk/config-BcnAlzj7.js +17959 -0
- package/dist/plugin-sdk/deliver-DA6iLkyw.js +1719 -0
- package/dist/plugin-sdk/deliver-runtime-PypF_2PZ.js +32 -0
- package/dist/plugin-sdk/deps-send-discord.runtime-W0j4bFLe.js +23 -0
- package/dist/plugin-sdk/deps-send-imessage.runtime-CbVysbRw.js +22 -0
- package/dist/plugin-sdk/deps-send-signal.runtime-BHEUBN5s.js +21 -0
- package/dist/plugin-sdk/deps-send-slack.runtime-C8UmPFSw.js +19 -0
- package/dist/plugin-sdk/deps-send-telegram.runtime-DpnxH7oK.js +24 -0
- package/dist/plugin-sdk/deps-send-whatsapp.runtime-X3_0evnj.js +57 -0
- package/dist/plugin-sdk/diagnostic-BYpId-ua.js +319 -0
- package/dist/plugin-sdk/discord.js +6 -6
- package/dist/plugin-sdk/errors-BNXdrdgq.js +54 -0
- package/dist/plugin-sdk/feishu.js +2 -2
- package/dist/plugin-sdk/fetch-guard-UENgdBAA.js +156 -0
- package/dist/plugin-sdk/fs-safe-pWsuEZFp.js +352 -0
- package/dist/plugin-sdk/image-DBK1Pm0x.js +2314 -0
- package/dist/plugin-sdk/image-ops-DDNO9FzP.js +584 -0
- package/dist/plugin-sdk/image-runtime-DDg2W35C.js +25 -0
- package/dist/plugin-sdk/ir-rTI2Vu-_.js +1296 -0
- package/dist/plugin-sdk/local-roots-BY1qGHmT.js +186 -0
- package/dist/plugin-sdk/logger-R8IfjvlT.js +1163 -0
- package/dist/plugin-sdk/login-CyPsKJHk.js +57 -0
- package/dist/plugin-sdk/login-qr-Ab4Rdjtw.js +320 -0
- package/dist/plugin-sdk/manager-CDbRqYqO.js +3929 -0
- package/dist/plugin-sdk/manager-runtime-Cv_e0iFU.js +15 -0
- package/dist/plugin-sdk/outbound-BJLmLYpF.js +212 -0
- package/dist/plugin-sdk/outbound-attachment-BVgtsvvA.js +19 -0
- package/dist/plugin-sdk/path-alias-guards-WBsyCbbp.js +43 -0
- package/dist/plugin-sdk/paths-Vi8cYjl0.js +166 -0
- package/dist/plugin-sdk/pi-embedded-helpers-B_AR1znF.js +9630 -0
- package/dist/plugin-sdk/pi-model-discovery-VnmMzMWq.js +134 -0
- package/dist/plugin-sdk/pi-model-discovery-runtime-_Tx2jvO8.js +8 -0
- package/dist/plugin-sdk/pi-tools.before-tool-call.runtime-BrauF-59.js +354 -0
- package/dist/plugin-sdk/plugins-Cd0KK3C4.js +864 -0
- package/dist/plugin-sdk/proxy-fetch-DqjDq6RX.js +38 -0
- package/dist/plugin-sdk/pw-ai-Ct5TZlon.js +1938 -0
- package/dist/plugin-sdk/qmd-manager-DdwC1VzU.js +1448 -0
- package/dist/plugin-sdk/query-expansion-CCRxQ44B.js +1011 -0
- package/dist/plugin-sdk/redact-CjsCSdLm.js +319 -0
- package/dist/plugin-sdk/reply-C9l3uDg5.js +100425 -0
- package/dist/plugin-sdk/resolve-outbound-target-L-Pfnyyj.js +40 -0
- package/dist/plugin-sdk/run-with-concurrency-vOAJTIUl.js +1994 -0
- package/dist/plugin-sdk/runtime-whatsapp-login.runtime-eTygo1nh.js +10 -0
- package/dist/plugin-sdk/runtime-whatsapp-outbound.runtime-6XwAzqXB.js +19 -0
- package/dist/plugin-sdk/send-BQRji2GY.js +2587 -0
- package/dist/plugin-sdk/send-Bo7dSZGk.js +503 -0
- package/dist/plugin-sdk/send-BuxT86_Z.js +3135 -0
- package/dist/plugin-sdk/send-DDmpff5Y.js +540 -0
- package/dist/plugin-sdk/send-uxACTUlM.js +414 -0
- package/dist/plugin-sdk/session-Btqwqejc.js +169 -0
- package/dist/plugin-sdk/skill-commands-DLNPoXns.js +353 -0
- package/dist/plugin-sdk/skills-CooMTEgR.js +1428 -0
- package/dist/plugin-sdk/slack.js +2 -2
- package/dist/plugin-sdk/slash-commands.runtime-DwFlI8Ti.js +13 -0
- package/dist/plugin-sdk/slash-dispatch.runtime-twldzXO6.js +52 -0
- package/dist/plugin-sdk/slash-skill-commands.runtime-D4RHjHw4.js +16 -0
- package/dist/plugin-sdk/ssrf-CVGOya13.js +202 -0
- package/dist/plugin-sdk/store-Bd90psSm.js +81 -0
- package/dist/plugin-sdk/subagent-registry-runtime-CrZLShfQ.js +52 -0
- package/dist/plugin-sdk/tables-B2Ekupoq.js +55 -0
- package/dist/plugin-sdk/target-errors-DFT67P24.js +195 -0
- package/dist/plugin-sdk/telegram.js +2 -2
- package/dist/plugin-sdk/thinking-CHnp0B7X.js +1206 -0
- package/dist/plugin-sdk/tokens-B0EEt7KU.js +52 -0
- package/dist/plugin-sdk/tool-images-CA0CLJms.js +274 -0
- package/dist/plugin-sdk/web-CTiM0ZF5.js +56 -0
- package/dist/plugin-sdk/whatsapp-actions-CHUE2yFs.js +80 -0
- package/dist/{program-akmc3IUx.js → program-DmK4Ex-d.js} +3 -3
- package/dist/{program-context-62Ht6ZW6.js → program-context-M__UNjvB.js} +6 -6
- package/dist/{prompt-select-styled-BBQawmdC.js → prompt-select-styled-BWFM4T6a.js} +1 -1
- package/dist/{prompt-select-styled-CMNC8u4s.js → prompt-select-styled-l4Y-KPuS.js} +1 -1
- package/dist/{register.maintenance-CDEHwOBe.js → register.maintenance-BMIPQ5QO.js} +5 -5
- package/dist/{register.maintenance-DZBfOHdB.js → register.maintenance-DJ0tLvCq.js} +4 -4
- package/dist/{register.onboard-UCJc4fR5.js → register.onboard-Bw9bpiHH.js} +2 -2
- package/dist/{register.onboard-CHIAASy4.js → register.onboard-CKO4La21.js} +2 -2
- package/dist/{register.setup-CCuwz9PJ.js → register.setup-C67Scvfs.js} +2 -2
- package/dist/{register.setup-CvVcRAAU.js → register.setup-DLhJIOnz.js} +2 -2
- package/dist/{register.subclis-dddx3aux.js → register.subclis-DJ2ZLtcN.js} +3 -3
- package/dist/{run-main-BVZb3asP.js → run-main-CtPy_map.js} +4 -4
- package/dist/{update-cli-THxTyOWY.js → update-cli-BHClo1c-.js} +4 -4
- package/dist/{update-cli-DDhr_pYD.js → update-cli-CqwUwO1J.js} +5 -5
- package/package.json +1 -1
|
@@ -269,7 +269,7 @@ function pickTagline(options = {}) {
|
|
|
269
269
|
//#endregion
|
|
270
270
|
//#region src/cli/banner.ts
|
|
271
271
|
let bannerEmitted = false;
|
|
272
|
-
|
|
272
|
+
typeof Intl !== "undefined" && "Segmenter" in Intl && new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
273
273
|
const hasJsonFlag = (argv) => argv.some((arg) => arg === "--json" || arg.startsWith("--json="));
|
|
274
274
|
const hasVersionFlag = (argv) => argv.some((arg) => arg === "--version" || arg === "-V") || hasRootVersionAlias(argv);
|
|
275
275
|
function parseTaglineMode(value) {
|
package/dist/build-info.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
cb8fecfd5a4a343ce61c082c35d67f5ad915d6e32fc2f8b22fa1793571a5c6e2
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-Cbj13DAv.js";
|
|
2
2
|
import { Ct as hasHelpOrVersion, bt as getPrimaryCommand } from "./entry.js";
|
|
3
|
-
import { i as registerSubCliCommands, o as removeCommandByName, s as reparseProgramFromActionArgs } from "./register.subclis-
|
|
3
|
+
import { i as registerSubCliCommands, o as removeCommandByName, s as reparseProgramFromActionArgs } from "./register.subclis-DJ2ZLtcN.js";
|
|
4
4
|
|
|
5
5
|
//#region src/cli/program/command-registry.ts
|
|
6
6
|
var command_registry_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -22,7 +22,7 @@ const coreEntries = [
|
|
|
22
22
|
hasSubcommands: false
|
|
23
23
|
}],
|
|
24
24
|
register: async ({ program }) => {
|
|
25
|
-
(await import("./register.setup-
|
|
25
|
+
(await import("./register.setup-DLhJIOnz.js")).registerSetupCommand(program);
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
{
|
|
@@ -32,7 +32,7 @@ const coreEntries = [
|
|
|
32
32
|
hasSubcommands: false
|
|
33
33
|
}],
|
|
34
34
|
register: async ({ program }) => {
|
|
35
|
-
(await import("./register.onboard-
|
|
35
|
+
(await import("./register.onboard-Bw9bpiHH.js")).registerOnboardCommand(program);
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
{
|
|
@@ -79,7 +79,7 @@ const coreEntries = [
|
|
|
79
79
|
}
|
|
80
80
|
],
|
|
81
81
|
register: async ({ program }) => {
|
|
82
|
-
(await import("./register.maintenance-
|
|
82
|
+
(await import("./register.maintenance-BMIPQ5QO.js")).registerMaintenanceCommands(program);
|
|
83
83
|
}
|
|
84
84
|
},
|
|
85
85
|
{
|
|
@@ -2,8 +2,8 @@ import { t as __exportAll } from "./rolldown-runtime-Cbj13DAv.js";
|
|
|
2
2
|
import { P as theme, ot as resolveStateDir, u as routeLogsToStderr } from "./entry.js";
|
|
3
3
|
import { m as pathExists } from "./utils-hiIKrqOK.js";
|
|
4
4
|
import { t as formatDocsLink } from "./links-Bcv6_maG.js";
|
|
5
|
-
import { n as getSubCliEntries, r as registerSubCliByName } from "./register.subclis-
|
|
6
|
-
import { i as registerCoreCliByName, n as getCoreCliCommandNames } from "./command-registry-
|
|
5
|
+
import { n as getSubCliEntries, r as registerSubCliByName } from "./register.subclis-DJ2ZLtcN.js";
|
|
6
|
+
import { i as registerCoreCliByName, n as getCoreCliCommandNames } from "./command-registry-DoH9LuuA.js";
|
|
7
7
|
import { t as getProgramContext } from "./program-context-gd4x_qEm.js";
|
|
8
8
|
import os from "node:os";
|
|
9
9
|
import path from "node:path";
|
|
@@ -4,7 +4,7 @@ import { p as theme } from "./globals-OYV0_7Zs.js";
|
|
|
4
4
|
import { h as pathExists } from "./utils-D78H0maG.js";
|
|
5
5
|
import { i as routeLogsToStderr } from "./subsystem-CYocb_fP.js";
|
|
6
6
|
import { t as formatDocsLink } from "./links-Tx7CNWHl.js";
|
|
7
|
-
import { a as registerCoreCliByName, c as getSubCliEntries, l as registerSubCliByName, r as getCoreCliCommandNames, t as getProgramContext } from "./program-context-
|
|
7
|
+
import { a as registerCoreCliByName, c as getSubCliEntries, l as registerSubCliByName, r as getCoreCliCommandNames, t as getProgramContext } from "./program-context-M__UNjvB.js";
|
|
8
8
|
import os from "node:os";
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import fs from "node:fs/promises";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { r as resolveCliName } from "./command-format-C2YuTuPp.js";
|
|
2
2
|
import { t as resolveWinClawPackageRoot } from "./winclaw-root-D0OUuGl7.js";
|
|
3
3
|
import { t as note } from "./note-Emtc1zzf.js";
|
|
4
|
-
import { a as resolveCompletionCachePath, i as isCompletionInstalled, o as resolveShellFromEnv, r as installCompletion, s as usesSlowDynamicCompletion, t as completionCacheExists } from "./completion-cli-
|
|
4
|
+
import { a as resolveCompletionCachePath, i as isCompletionInstalled, o as resolveShellFromEnv, r as installCompletion, s as usesSlowDynamicCompletion, t as completionCacheExists } from "./completion-cli-CyCV3ZHh.js";
|
|
5
5
|
import { spawnSync } from "node:child_process";
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as resolveWinClawPackageRoot } from "./winclaw-root-ExuHY0xi.js";
|
|
2
2
|
import { r as resolveCliName } from "./command-format-BU9fEGrc.js";
|
|
3
3
|
import { t as note } from "./note-DPVyaATq.js";
|
|
4
|
-
import { a as resolveCompletionCachePath, i as isCompletionInstalled, o as resolveShellFromEnv, r as installCompletion, s as usesSlowDynamicCompletion, t as completionCacheExists } from "./completion-cli-
|
|
4
|
+
import { a as resolveCompletionCachePath, i as isCompletionInstalled, o as resolveShellFromEnv, r as installCompletion, s as usesSlowDynamicCompletion, t as completionCacheExists } from "./completion-cli-D5AGXrau.js";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { spawnSync } from "node:child_process";
|
|
7
7
|
|
package/dist/entry.js
CHANGED
|
@@ -1831,7 +1831,7 @@ if (!isMainModule({
|
|
|
1831
1831
|
}
|
|
1832
1832
|
function tryHandleRootHelpFastPath(argv) {
|
|
1833
1833
|
if (!isRootHelpInvocation(argv)) return false;
|
|
1834
|
-
import("./program-
|
|
1834
|
+
import("./program-DmK4Ex-d.js").then(({ buildProgram }) => {
|
|
1835
1835
|
buildProgram().outputHelp();
|
|
1836
1836
|
}).catch((error) => {
|
|
1837
1837
|
console.error("[winclaw] Failed to display help:", error instanceof Error ? error.stack ?? error.message : error);
|
|
@@ -1850,7 +1850,7 @@ if (!isMainModule({
|
|
|
1850
1850
|
applyCliProfileEnv({ profile: parsed.profile });
|
|
1851
1851
|
process$1.argv = parsed.argv;
|
|
1852
1852
|
}
|
|
1853
|
-
if (!tryHandleRootVersionFastPath(process$1.argv) && !tryHandleRootHelpFastPath(process$1.argv)) import("./run-main-
|
|
1853
|
+
if (!tryHandleRootVersionFastPath(process$1.argv) && !tryHandleRootHelpFastPath(process$1.argv)) import("./run-main-CtPy_map.js").then(({ runCli }) => runCli(process$1.argv)).catch((error) => {
|
|
1854
1854
|
console.error("[winclaw] Failed to start CLI:", error instanceof Error ? error.stack ?? error.message : error);
|
|
1855
1855
|
process$1.exitCode = 1;
|
|
1856
1856
|
});
|
|
@@ -150,7 +150,7 @@ import { c as DEFAULT_PACKAGE_CHANNEL, m as normalizeUpdateChannel, n as checkUp
|
|
|
150
150
|
import { t as runGatewayUpdate } from "./update-runner-DgLjHR6L.js";
|
|
151
151
|
import { a as resolveCommandSecretsFromActiveRuntimeSnapshot, i as prepareSecretsRuntimeSnapshot, n as clearSecretsRuntimeSnapshot, r as getActiveSecretsRuntimeSnapshot, t as activateSecretsRuntimeSnapshot } from "./runtime-BF8Olfsc.js";
|
|
152
152
|
import "./onboarding.secret-input-BqpyOfgu.js";
|
|
153
|
-
import { t as runOnboardingWizard } from "./onboarding-
|
|
153
|
+
import { t as runOnboardingWizard } from "./onboarding-cdo8bLhe.js";
|
|
154
154
|
import { a as sendApnsAlert, c as parseMessageWithAttachments, d as shouldLogWs, f as summarizeAgentEventForWsLog, i as resolveApnsAuthConfigFromEnv, l as formatForLog, n as normalizeApnsEnvironment, o as sendApnsBackgroundWake, p as setGatewayWsLogStyle, s as normalizeRpcAttachmentsToChatAttachments, t as loadApnsRegistration, u as logWs } from "./push-apns-Ccnjw92j.js";
|
|
155
155
|
import { T as resolveGmailHookRuntimeConfig, _ as buildGogWatchServeArgs, i as ensureTailscaleEndpoint, v as buildGogWatchStartArgs } from "./gmail-setup-utils-DgQq2EEP.js";
|
|
156
156
|
import { n as isNodeCommandAllowed, r as resolveNodeCommandAllowlist } from "./node-command-policy-hSqGZL6Y.js";
|
|
@@ -27675,15 +27675,39 @@ async function runGatewayCommand$1(opts) {
|
|
|
27675
27675
|
const snapshot = await readConfigFileSnapshot().catch(() => null);
|
|
27676
27676
|
const configExists = snapshot?.exists ?? fs.existsSync(CONFIG_PATH);
|
|
27677
27677
|
const configAuditPath = path.join(resolveStateDir(process.env), "logs", "config-audit.jsonl");
|
|
27678
|
-
|
|
27678
|
+
let mode = cfg.gateway?.mode;
|
|
27679
27679
|
if (!opts.allowUnconfigured && mode !== "local") {
|
|
27680
|
-
if (!configExists)
|
|
27681
|
-
|
|
27682
|
-
|
|
27683
|
-
|
|
27680
|
+
if (!configExists) try {
|
|
27681
|
+
const healthRes = await fetch("http://127.0.0.1:3100/health", { signal: AbortSignal.timeout(2e3) }).catch(() => null);
|
|
27682
|
+
if ((healthRes ? await healthRes.json().catch(() => null) : null)?.service === "grc-server") {
|
|
27683
|
+
defaultRuntime.log("Local GRC detected at http://127.0.0.1:3100 — creating auto-config...");
|
|
27684
|
+
const stateDir = resolveStateDir(process.env);
|
|
27685
|
+
fs.mkdirSync(stateDir, { recursive: true });
|
|
27686
|
+
const autoConfig = {
|
|
27687
|
+
gateway: {
|
|
27688
|
+
mode: "local",
|
|
27689
|
+
port: 18789,
|
|
27690
|
+
bind: "loopback",
|
|
27691
|
+
auth: { mode: "token" },
|
|
27692
|
+
controlUi: { dangerouslyDisableDeviceAuth: true }
|
|
27693
|
+
},
|
|
27694
|
+
grc: { url: "http://127.0.0.1:3100" }
|
|
27695
|
+
};
|
|
27696
|
+
fs.writeFileSync(path.join(stateDir, "winclaw.json"), JSON.stringify(autoConfig, null, 2));
|
|
27697
|
+
defaultRuntime.log(`Config auto-created at ${path.join(stateDir, "winclaw.json")}`);
|
|
27698
|
+
Object.assign(cfg, autoConfig);
|
|
27699
|
+
mode = "local";
|
|
27700
|
+
}
|
|
27701
|
+
} catch {}
|
|
27702
|
+
if (mode !== "local") {
|
|
27703
|
+
if (!configExists) defaultRuntime.error(`Missing config. Run \`${formatCliCommand("winclaw setup")}\` or set gateway.mode=local (or pass --allow-unconfigured).`);
|
|
27704
|
+
else {
|
|
27705
|
+
defaultRuntime.error(`Gateway start blocked: set gateway.mode=local (current: ${mode ?? "unset"}) or pass --allow-unconfigured.`);
|
|
27706
|
+
defaultRuntime.error(`Config write audit: ${configAuditPath}`);
|
|
27707
|
+
}
|
|
27708
|
+
defaultRuntime.exit(1);
|
|
27709
|
+
return;
|
|
27684
27710
|
}
|
|
27685
|
-
defaultRuntime.exit(1);
|
|
27686
|
-
return;
|
|
27687
27711
|
}
|
|
27688
27712
|
const miskeys = extractGatewayMiskeys(snapshot?.parsed);
|
|
27689
27713
|
const authOverride = authMode || passwordRaw || tokenRaw || authModeRaw ? {
|
|
@@ -153,7 +153,7 @@ import { c as DEFAULT_PACKAGE_CHANNEL, m as normalizeUpdateChannel, n as checkUp
|
|
|
153
153
|
import { t as runGatewayUpdate } from "./update-runner-BPC9hov9.js";
|
|
154
154
|
import { a as resolveCommandSecretsFromActiveRuntimeSnapshot, i as prepareSecretsRuntimeSnapshot, n as clearSecretsRuntimeSnapshot, r as getActiveSecretsRuntimeSnapshot, t as activateSecretsRuntimeSnapshot } from "./runtime-C8G-Ij45.js";
|
|
155
155
|
import "./onboarding.secret-input-CpvAADXr.js";
|
|
156
|
-
import { t as runOnboardingWizard } from "./onboarding-
|
|
156
|
+
import { t as runOnboardingWizard } from "./onboarding-BA6Xzjvi.js";
|
|
157
157
|
import { a as sendApnsAlert, c as parseMessageWithAttachments, d as shouldLogWs, f as summarizeAgentEventForWsLog, i as resolveApnsAuthConfigFromEnv, l as formatForLog, n as normalizeApnsEnvironment, o as sendApnsBackgroundWake, p as setGatewayWsLogStyle, s as normalizeRpcAttachmentsToChatAttachments, t as loadApnsRegistration, u as logWs } from "./push-apns-asJ7Q3eB.js";
|
|
158
158
|
import { T as resolveGmailHookRuntimeConfig, _ as buildGogWatchServeArgs, i as ensureTailscaleEndpoint, v as buildGogWatchStartArgs } from "./gmail-setup-utils-CGtohkh2.js";
|
|
159
159
|
import { n as isNodeCommandAllowed, r as resolveNodeCommandAllowlist } from "./node-command-policy-CtleaLrB.js";
|
|
@@ -27677,15 +27677,39 @@ async function runGatewayCommand$1(opts) {
|
|
|
27677
27677
|
const snapshot = await readConfigFileSnapshot().catch(() => null);
|
|
27678
27678
|
const configExists = snapshot?.exists ?? fs.existsSync(CONFIG_PATH);
|
|
27679
27679
|
const configAuditPath = path.join(resolveStateDir(process.env), "logs", "config-audit.jsonl");
|
|
27680
|
-
|
|
27680
|
+
let mode = cfg.gateway?.mode;
|
|
27681
27681
|
if (!opts.allowUnconfigured && mode !== "local") {
|
|
27682
|
-
if (!configExists)
|
|
27683
|
-
|
|
27684
|
-
|
|
27685
|
-
|
|
27682
|
+
if (!configExists) try {
|
|
27683
|
+
const healthRes = await fetch("http://127.0.0.1:3100/health", { signal: AbortSignal.timeout(2e3) }).catch(() => null);
|
|
27684
|
+
if ((healthRes ? await healthRes.json().catch(() => null) : null)?.service === "grc-server") {
|
|
27685
|
+
defaultRuntime.log("Local GRC detected at http://127.0.0.1:3100 — creating auto-config...");
|
|
27686
|
+
const stateDir = resolveStateDir(process.env);
|
|
27687
|
+
fs.mkdirSync(stateDir, { recursive: true });
|
|
27688
|
+
const autoConfig = {
|
|
27689
|
+
gateway: {
|
|
27690
|
+
mode: "local",
|
|
27691
|
+
port: 18789,
|
|
27692
|
+
bind: "loopback",
|
|
27693
|
+
auth: { mode: "token" },
|
|
27694
|
+
controlUi: { dangerouslyDisableDeviceAuth: true }
|
|
27695
|
+
},
|
|
27696
|
+
grc: { url: "http://127.0.0.1:3100" }
|
|
27697
|
+
};
|
|
27698
|
+
fs.writeFileSync(path.join(stateDir, "winclaw.json"), JSON.stringify(autoConfig, null, 2));
|
|
27699
|
+
defaultRuntime.log(`Config auto-created at ${path.join(stateDir, "winclaw.json")}`);
|
|
27700
|
+
Object.assign(cfg, autoConfig);
|
|
27701
|
+
mode = "local";
|
|
27702
|
+
}
|
|
27703
|
+
} catch {}
|
|
27704
|
+
if (mode !== "local") {
|
|
27705
|
+
if (!configExists) defaultRuntime.error(`Missing config. Run \`${formatCliCommand("winclaw setup")}\` or set gateway.mode=local (or pass --allow-unconfigured).`);
|
|
27706
|
+
else {
|
|
27707
|
+
defaultRuntime.error(`Gateway start blocked: set gateway.mode=local (current: ${mode ?? "unset"}) or pass --allow-unconfigured.`);
|
|
27708
|
+
defaultRuntime.error(`Config write audit: ${configAuditPath}`);
|
|
27709
|
+
}
|
|
27710
|
+
defaultRuntime.exit(1);
|
|
27711
|
+
return;
|
|
27686
27712
|
}
|
|
27687
|
-
defaultRuntime.exit(1);
|
|
27688
|
-
return;
|
|
27689
27713
|
}
|
|
27690
27714
|
const miskeys = extractGatewayMiskeys(snapshot?.parsed);
|
|
27691
27715
|
const authOverride = authMode || passwordRaw || tokenRaw || authModeRaw ? {
|
package/dist/index.js
CHANGED
|
@@ -119,7 +119,7 @@ import { t as isMainModule } from "./is-main-TPRg8r91.js";
|
|
|
119
119
|
import { t as ensureWinClawCliOnPath } from "./path-env-Buh15leX.js";
|
|
120
120
|
import { t as assertSupportedRuntime } from "./runtime-guard-FM7xygCS.js";
|
|
121
121
|
import "./ports-75LDB15g.js";
|
|
122
|
-
import { i as getCoreCliCommandsWithSubcommands, n as setProgramContext, o as registerProgramCommands, s as getSubCliCommandsWithSubcommands } from "./program-context-
|
|
122
|
+
import { i as getCoreCliCommandsWithSubcommands, n as setProgramContext, o as registerProgramCommands, s as getSubCliCommandsWithSubcommands } from "./program-context-M__UNjvB.js";
|
|
123
123
|
import "./plugin-registry-BeoYaQ7j.js";
|
|
124
124
|
import { n as resolveCliChannelOptions } from "./channel-options-ka5SNkDk.js";
|
|
125
125
|
import process$1 from "node:process";
|
|
@@ -415,7 +415,7 @@ function pickTagline(options = {}) {
|
|
|
415
415
|
//#endregion
|
|
416
416
|
//#region src/cli/banner.ts
|
|
417
417
|
let bannerEmitted = false;
|
|
418
|
-
|
|
418
|
+
typeof Intl !== "undefined" && "Segmenter" in Intl && new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
419
419
|
const hasJsonFlag = (argv) => argv.some((arg) => arg === "--json" || arg.startsWith("--json="));
|
|
420
420
|
const hasVersionFlag = (argv) => argv.some((arg) => arg === "--version" || arg === "-V") || hasRootVersionAlias(argv);
|
|
421
421
|
function parseTaglineMode(value) {
|
|
@@ -8,7 +8,7 @@ import { t as assertSupportedRuntime } from "./runtime-guard-FM7xygCS.js";
|
|
|
8
8
|
import { t as WizardCancelledError } from "./prompts-m1IJwIAx.js";
|
|
9
9
|
import { t as createClackPrompter } from "./clack-prompter-zvdI4LpS.js";
|
|
10
10
|
import { t as DEFAULT_GATEWAY_DAEMON_RUNTIME } from "./daemon-runtime-mYDSc4SR.js";
|
|
11
|
-
import { t as runOnboardingWizard } from "./onboarding-
|
|
11
|
+
import { t as runOnboardingWizard } from "./onboarding-BA6Xzjvi.js";
|
|
12
12
|
import { n as logConfigUpdated } from "./logging-BD5zmT-4.js";
|
|
13
13
|
import { i as normalizeLegacyOnboardAuthChoice, r as isDeprecatedAuthChoice, t as ONBOARD_PROVIDER_AUTH_FLAGS } from "./onboard-provider-auth-flags-CIRgbott.js";
|
|
14
14
|
import { t as applyOnboardingLocalWorkspaceConfig } from "./onboard-config-CiaxSolC.js";
|
|
@@ -7,7 +7,7 @@ import { t as WizardCancelledError } from "./prompts-DomsZukd.js";
|
|
|
7
7
|
import { t as createClackPrompter } from "./clack-prompter-C88sE8nV.js";
|
|
8
8
|
import { t as assertSupportedRuntime } from "./runtime-guard-H-DjZ1G4.js";
|
|
9
9
|
import { t as DEFAULT_GATEWAY_DAEMON_RUNTIME } from "./daemon-runtime-99xh1fGv.js";
|
|
10
|
-
import { t as runOnboardingWizard } from "./onboarding-
|
|
10
|
+
import { t as runOnboardingWizard } from "./onboarding-cdo8bLhe.js";
|
|
11
11
|
import { n as logConfigUpdated } from "./logging-D6YjGDjQ.js";
|
|
12
12
|
import { i as normalizeLegacyOnboardAuthChoice, r as isDeprecatedAuthChoice, t as ONBOARD_PROVIDER_AUTH_FLAGS } from "./onboard-provider-auth-flags--oF1OLyy.js";
|
|
13
13
|
import { t as applyOnboardingLocalWorkspaceConfig } from "./onboard-config-g-XBXKJM.js";
|
|
@@ -327,7 +327,7 @@ async function runOnboardingWizard(opts, runtime = defaultRuntime, prompter) {
|
|
|
327
327
|
mode
|
|
328
328
|
});
|
|
329
329
|
await writeConfigFile(nextConfig);
|
|
330
|
-
const { finalizeOnboardingWizard } = await import("./onboarding.finalize-
|
|
330
|
+
const { finalizeOnboardingWizard } = await import("./onboarding.finalize-0mWawAfn.js");
|
|
331
331
|
const { launchedTui } = await finalizeOnboardingWizard({
|
|
332
332
|
flow,
|
|
333
333
|
opts,
|
|
@@ -326,7 +326,7 @@ async function runOnboardingWizard(opts, runtime = defaultRuntime, prompter) {
|
|
|
326
326
|
mode
|
|
327
327
|
});
|
|
328
328
|
await writeConfigFile(nextConfig);
|
|
329
|
-
const { finalizeOnboardingWizard } = await import("./onboarding.finalize-
|
|
329
|
+
const { finalizeOnboardingWizard } = await import("./onboarding.finalize-Bicw2cW7.js");
|
|
330
330
|
const { launchedTui } = await finalizeOnboardingWizard({
|
|
331
331
|
flow,
|
|
332
332
|
opts,
|
|
@@ -111,9 +111,9 @@ import "./progress-skGe4xuJ.js";
|
|
|
111
111
|
import "./server-lifecycle-Do-Sf9Cq.js";
|
|
112
112
|
import "./stagger-BU0UZwZh.js";
|
|
113
113
|
import "./runtime-guard-FM7xygCS.js";
|
|
114
|
-
import "./program-context-
|
|
114
|
+
import "./program-context-M__UNjvB.js";
|
|
115
115
|
import "./note-DPVyaATq.js";
|
|
116
|
-
import { r as installCompletion } from "./completion-cli-
|
|
116
|
+
import { r as installCompletion } from "./completion-cli-D5AGXrau.js";
|
|
117
117
|
import { n as gatewayInstallErrorHint, t as buildGatewayInstallPlan } from "./daemon-install-helpers-DSwJ2uJ4.js";
|
|
118
118
|
import { n as GATEWAY_DAEMON_RUNTIME_OPTIONS, t as DEFAULT_GATEWAY_DAEMON_RUNTIME } from "./daemon-runtime-mYDSc4SR.js";
|
|
119
119
|
import { r as isSystemdUserServiceAvailable } from "./systemd-BS462KFE.js";
|
|
@@ -122,7 +122,7 @@ import { r as healthCommand } from "./health-K7GwLq6S.js";
|
|
|
122
122
|
import { t as ensureControlUiAssetsBuilt } from "./control-ui-assets-DhUI98bh.js";
|
|
123
123
|
import { t as resolveOnboardingSecretInputString } from "./onboarding.secret-input-CpvAADXr.js";
|
|
124
124
|
import { t as formatHealthCheckFailure } from "./health-format-Ba6tveTS.js";
|
|
125
|
-
import { r as ensureCompletionCacheExists, t as checkShellCompletionStatus } from "./doctor-completion-
|
|
125
|
+
import { r as ensureCompletionCacheExists, t as checkShellCompletionStatus } from "./doctor-completion-Drs7WusO.js";
|
|
126
126
|
import { t as runTui } from "./tui-C3Mn21ul.js";
|
|
127
127
|
import os from "node:os";
|
|
128
128
|
import path from "node:path";
|
|
@@ -109,9 +109,9 @@ import "./cli-utils-BlpNlYVq.js";
|
|
|
109
109
|
import "./help-format-DqamOwoM.js";
|
|
110
110
|
import "./progress-Dtl-ttAH.js";
|
|
111
111
|
import "./note-Emtc1zzf.js";
|
|
112
|
-
import { r as installCompletion } from "./completion-cli-
|
|
113
|
-
import "./register.subclis-
|
|
114
|
-
import "./command-registry-
|
|
112
|
+
import { r as installCompletion } from "./completion-cli-CyCV3ZHh.js";
|
|
113
|
+
import "./register.subclis-DJ2ZLtcN.js";
|
|
114
|
+
import "./command-registry-DoH9LuuA.js";
|
|
115
115
|
import "./program-context-gd4x_qEm.js";
|
|
116
116
|
import { n as gatewayInstallErrorHint, t as buildGatewayInstallPlan } from "./daemon-install-helpers-D1YQ03lO.js";
|
|
117
117
|
import "./runtime-guard-H-DjZ1G4.js";
|
|
@@ -122,7 +122,7 @@ import { r as healthCommand } from "./health-DiqQQYRN.js";
|
|
|
122
122
|
import { t as ensureControlUiAssetsBuilt } from "./control-ui-assets-B0DdamQU.js";
|
|
123
123
|
import { t as resolveOnboardingSecretInputString } from "./onboarding.secret-input-BqpyOfgu.js";
|
|
124
124
|
import { t as formatHealthCheckFailure } from "./health-format-DfUHWWsW.js";
|
|
125
|
-
import { r as ensureCompletionCacheExists, t as checkShellCompletionStatus } from "./doctor-completion-
|
|
125
|
+
import { r as ensureCompletionCacheExists, t as checkShellCompletionStatus } from "./doctor-completion-B7rNU63W.js";
|
|
126
126
|
import { t as runTui } from "./tui-D8p-fGCf.js";
|
|
127
127
|
import os from "node:os";
|
|
128
128
|
import path from "node:path";
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import { at as DEFAULT_ACCOUNT_ID, ot as normalizeAccountId, st as normalizeOptionalAccountId } from "./run-with-concurrency-vOAJTIUl.js";
|
|
2
|
+
import { o as resolveOAuthDir } from "./paths-C2qA2GWL.js";
|
|
3
|
+
import { Pr as formatCliCommand } from "./config-BcnAlzj7.js";
|
|
4
|
+
import { B as success, E as resolveUserPath, G as getChildLogger, I as info, c as defaultRuntime, x as jidToE164 } from "./logger-R8IfjvlT.js";
|
|
5
|
+
import fs from "node:fs";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import fs$1 from "node:fs/promises";
|
|
8
|
+
|
|
9
|
+
//#region src/channels/plugins/account-helpers.ts
|
|
10
|
+
function createAccountListHelpers(channelKey) {
|
|
11
|
+
function resolveConfiguredDefaultAccountId(cfg) {
|
|
12
|
+
const channel = cfg.channels?.[channelKey];
|
|
13
|
+
const preferred = normalizeOptionalAccountId(typeof channel?.defaultAccount === "string" ? channel.defaultAccount : void 0);
|
|
14
|
+
if (!preferred) return;
|
|
15
|
+
if (listAccountIds(cfg).some((id) => normalizeAccountId(id) === preferred)) return preferred;
|
|
16
|
+
}
|
|
17
|
+
function listConfiguredAccountIds(cfg) {
|
|
18
|
+
const accounts = (cfg.channels?.[channelKey])?.accounts;
|
|
19
|
+
if (!accounts || typeof accounts !== "object") return [];
|
|
20
|
+
return Object.keys(accounts).filter(Boolean);
|
|
21
|
+
}
|
|
22
|
+
function listAccountIds(cfg) {
|
|
23
|
+
const ids = listConfiguredAccountIds(cfg);
|
|
24
|
+
if (ids.length === 0) return [DEFAULT_ACCOUNT_ID];
|
|
25
|
+
return ids.toSorted((a, b) => a.localeCompare(b));
|
|
26
|
+
}
|
|
27
|
+
function resolveDefaultAccountId(cfg) {
|
|
28
|
+
const preferred = resolveConfiguredDefaultAccountId(cfg);
|
|
29
|
+
if (preferred) return preferred;
|
|
30
|
+
const ids = listAccountIds(cfg);
|
|
31
|
+
if (ids.includes(DEFAULT_ACCOUNT_ID)) return DEFAULT_ACCOUNT_ID;
|
|
32
|
+
return ids[0] ?? DEFAULT_ACCOUNT_ID;
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
listConfiguredAccountIds,
|
|
36
|
+
listAccountIds,
|
|
37
|
+
resolveDefaultAccountId
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/routing/account-lookup.ts
|
|
43
|
+
function resolveAccountEntry(accounts, accountId) {
|
|
44
|
+
if (!accounts || typeof accounts !== "object") return;
|
|
45
|
+
if (Object.hasOwn(accounts, accountId)) return accounts[accountId];
|
|
46
|
+
const normalized = accountId.toLowerCase();
|
|
47
|
+
const matchKey = Object.keys(accounts).find((key) => key.toLowerCase() === normalized);
|
|
48
|
+
return matchKey ? accounts[matchKey] : void 0;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/web/auth-store.ts
|
|
53
|
+
function resolveDefaultWebAuthDir() {
|
|
54
|
+
return path.join(resolveOAuthDir(), "whatsapp", DEFAULT_ACCOUNT_ID);
|
|
55
|
+
}
|
|
56
|
+
const WA_WEB_AUTH_DIR = resolveDefaultWebAuthDir();
|
|
57
|
+
function resolveWebCredsPath(authDir) {
|
|
58
|
+
return path.join(authDir, "creds.json");
|
|
59
|
+
}
|
|
60
|
+
function resolveWebCredsBackupPath(authDir) {
|
|
61
|
+
return path.join(authDir, "creds.json.bak");
|
|
62
|
+
}
|
|
63
|
+
function hasWebCredsSync(authDir) {
|
|
64
|
+
try {
|
|
65
|
+
const stats = fs.statSync(resolveWebCredsPath(authDir));
|
|
66
|
+
return stats.isFile() && stats.size > 1;
|
|
67
|
+
} catch {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function readCredsJsonRaw(filePath) {
|
|
72
|
+
try {
|
|
73
|
+
if (!fs.existsSync(filePath)) return null;
|
|
74
|
+
const stats = fs.statSync(filePath);
|
|
75
|
+
if (!stats.isFile() || stats.size <= 1) return null;
|
|
76
|
+
return fs.readFileSync(filePath, "utf-8");
|
|
77
|
+
} catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function maybeRestoreCredsFromBackup(authDir) {
|
|
82
|
+
const logger = getChildLogger({ module: "web-session" });
|
|
83
|
+
try {
|
|
84
|
+
const credsPath = resolveWebCredsPath(authDir);
|
|
85
|
+
const backupPath = resolveWebCredsBackupPath(authDir);
|
|
86
|
+
const raw = readCredsJsonRaw(credsPath);
|
|
87
|
+
if (raw) {
|
|
88
|
+
JSON.parse(raw);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const backupRaw = readCredsJsonRaw(backupPath);
|
|
92
|
+
if (!backupRaw) return;
|
|
93
|
+
JSON.parse(backupRaw);
|
|
94
|
+
fs.copyFileSync(backupPath, credsPath);
|
|
95
|
+
try {
|
|
96
|
+
fs.chmodSync(credsPath, 384);
|
|
97
|
+
} catch {}
|
|
98
|
+
logger.warn({ credsPath }, "restored corrupted WhatsApp creds.json from backup");
|
|
99
|
+
} catch {}
|
|
100
|
+
}
|
|
101
|
+
async function webAuthExists(authDir = resolveDefaultWebAuthDir()) {
|
|
102
|
+
const resolvedAuthDir = resolveUserPath(authDir);
|
|
103
|
+
maybeRestoreCredsFromBackup(resolvedAuthDir);
|
|
104
|
+
const credsPath = resolveWebCredsPath(resolvedAuthDir);
|
|
105
|
+
try {
|
|
106
|
+
await fs$1.access(resolvedAuthDir);
|
|
107
|
+
} catch {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
const stats = await fs$1.stat(credsPath);
|
|
112
|
+
if (!stats.isFile() || stats.size <= 1) return false;
|
|
113
|
+
const raw = await fs$1.readFile(credsPath, "utf-8");
|
|
114
|
+
JSON.parse(raw);
|
|
115
|
+
return true;
|
|
116
|
+
} catch {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
async function clearLegacyBaileysAuthState(authDir) {
|
|
121
|
+
const entries = await fs$1.readdir(authDir, { withFileTypes: true });
|
|
122
|
+
const shouldDelete = (name) => {
|
|
123
|
+
if (name === "oauth.json") return false;
|
|
124
|
+
if (name === "creds.json" || name === "creds.json.bak") return true;
|
|
125
|
+
if (!name.endsWith(".json")) return false;
|
|
126
|
+
return /^(app-state-sync|session|sender-key|pre-key)-/.test(name);
|
|
127
|
+
};
|
|
128
|
+
await Promise.all(entries.map(async (entry) => {
|
|
129
|
+
if (!entry.isFile()) return;
|
|
130
|
+
if (!shouldDelete(entry.name)) return;
|
|
131
|
+
await fs$1.rm(path.join(authDir, entry.name), { force: true });
|
|
132
|
+
}));
|
|
133
|
+
}
|
|
134
|
+
async function logoutWeb(params) {
|
|
135
|
+
const runtime = params.runtime ?? defaultRuntime;
|
|
136
|
+
const resolvedAuthDir = resolveUserPath(params.authDir ?? resolveDefaultWebAuthDir());
|
|
137
|
+
if (!await webAuthExists(resolvedAuthDir)) {
|
|
138
|
+
runtime.log(info("No WhatsApp Web session found; nothing to delete."));
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
if (params.isLegacyAuthDir) await clearLegacyBaileysAuthState(resolvedAuthDir);
|
|
142
|
+
else await fs$1.rm(resolvedAuthDir, {
|
|
143
|
+
recursive: true,
|
|
144
|
+
force: true
|
|
145
|
+
});
|
|
146
|
+
runtime.log(success("Cleared WhatsApp Web credentials."));
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
function readWebSelfId(authDir = resolveDefaultWebAuthDir()) {
|
|
150
|
+
try {
|
|
151
|
+
const credsPath = resolveWebCredsPath(resolveUserPath(authDir));
|
|
152
|
+
if (!fs.existsSync(credsPath)) return {
|
|
153
|
+
e164: null,
|
|
154
|
+
jid: null
|
|
155
|
+
};
|
|
156
|
+
const raw = fs.readFileSync(credsPath, "utf-8");
|
|
157
|
+
const jid = JSON.parse(raw)?.me?.id ?? null;
|
|
158
|
+
return {
|
|
159
|
+
e164: jid ? jidToE164(jid, { authDir }) : null,
|
|
160
|
+
jid
|
|
161
|
+
};
|
|
162
|
+
} catch {
|
|
163
|
+
return {
|
|
164
|
+
e164: null,
|
|
165
|
+
jid: null
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Return the age (in milliseconds) of the cached WhatsApp web auth state, or null when missing.
|
|
171
|
+
* Helpful for heartbeats/observability to spot stale credentials.
|
|
172
|
+
*/
|
|
173
|
+
function getWebAuthAgeMs(authDir = resolveDefaultWebAuthDir()) {
|
|
174
|
+
try {
|
|
175
|
+
const stats = fs.statSync(resolveWebCredsPath(resolveUserPath(authDir)));
|
|
176
|
+
return Date.now() - stats.mtimeMs;
|
|
177
|
+
} catch {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function logWebSelfId(authDir = resolveDefaultWebAuthDir(), runtime = defaultRuntime, includeChannelPrefix = false) {
|
|
182
|
+
const { e164, jid } = readWebSelfId(authDir);
|
|
183
|
+
const details = e164 || jid ? `${e164 ?? "unknown"}${jid ? ` (jid ${jid})` : ""}` : "unknown";
|
|
184
|
+
const prefix = includeChannelPrefix ? "Web Channel: " : "";
|
|
185
|
+
runtime.log(info(`${prefix}${details}`));
|
|
186
|
+
}
|
|
187
|
+
async function pickWebChannel(pref, authDir = resolveDefaultWebAuthDir()) {
|
|
188
|
+
const choice = pref === "auto" ? "web" : pref;
|
|
189
|
+
if (!await webAuthExists(authDir)) throw new Error(`No WhatsApp Web session found. Run \`${formatCliCommand("winclaw channels login --channel whatsapp --verbose")}\` to link.`);
|
|
190
|
+
return choice;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
//#endregion
|
|
194
|
+
//#region src/web/accounts.ts
|
|
195
|
+
const { listConfiguredAccountIds, listAccountIds, resolveDefaultAccountId } = createAccountListHelpers("whatsapp");
|
|
196
|
+
const listWhatsAppAccountIds = listAccountIds;
|
|
197
|
+
const resolveDefaultWhatsAppAccountId = resolveDefaultAccountId;
|
|
198
|
+
function listWhatsAppAuthDirs(cfg) {
|
|
199
|
+
const oauthDir = resolveOAuthDir();
|
|
200
|
+
const whatsappDir = path.join(oauthDir, "whatsapp");
|
|
201
|
+
const authDirs = new Set([oauthDir, path.join(whatsappDir, DEFAULT_ACCOUNT_ID)]);
|
|
202
|
+
const accountIds = listConfiguredAccountIds(cfg);
|
|
203
|
+
for (const accountId of accountIds) authDirs.add(resolveWhatsAppAuthDir({
|
|
204
|
+
cfg,
|
|
205
|
+
accountId
|
|
206
|
+
}).authDir);
|
|
207
|
+
try {
|
|
208
|
+
const entries = fs.readdirSync(whatsappDir, { withFileTypes: true });
|
|
209
|
+
for (const entry of entries) {
|
|
210
|
+
if (!entry.isDirectory()) continue;
|
|
211
|
+
authDirs.add(path.join(whatsappDir, entry.name));
|
|
212
|
+
}
|
|
213
|
+
} catch {}
|
|
214
|
+
return Array.from(authDirs);
|
|
215
|
+
}
|
|
216
|
+
function hasAnyWhatsAppAuth(cfg) {
|
|
217
|
+
return listWhatsAppAuthDirs(cfg).some((authDir) => hasWebCredsSync(authDir));
|
|
218
|
+
}
|
|
219
|
+
function resolveAccountConfig(cfg, accountId) {
|
|
220
|
+
return resolveAccountEntry(cfg.channels?.whatsapp?.accounts, accountId);
|
|
221
|
+
}
|
|
222
|
+
function resolveDefaultAuthDir(accountId) {
|
|
223
|
+
return path.join(resolveOAuthDir(), "whatsapp", normalizeAccountId(accountId));
|
|
224
|
+
}
|
|
225
|
+
function resolveLegacyAuthDir() {
|
|
226
|
+
return resolveOAuthDir();
|
|
227
|
+
}
|
|
228
|
+
function legacyAuthExists(authDir) {
|
|
229
|
+
try {
|
|
230
|
+
return fs.existsSync(path.join(authDir, "creds.json"));
|
|
231
|
+
} catch {
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
function resolveWhatsAppAuthDir(params) {
|
|
236
|
+
const accountId = params.accountId.trim() || DEFAULT_ACCOUNT_ID;
|
|
237
|
+
const configured = resolveAccountConfig(params.cfg, accountId)?.authDir?.trim();
|
|
238
|
+
if (configured) return {
|
|
239
|
+
authDir: resolveUserPath(configured),
|
|
240
|
+
isLegacy: false
|
|
241
|
+
};
|
|
242
|
+
const defaultDir = resolveDefaultAuthDir(accountId);
|
|
243
|
+
if (accountId === DEFAULT_ACCOUNT_ID) {
|
|
244
|
+
const legacyDir = resolveLegacyAuthDir();
|
|
245
|
+
if (legacyAuthExists(legacyDir) && !legacyAuthExists(defaultDir)) return {
|
|
246
|
+
authDir: legacyDir,
|
|
247
|
+
isLegacy: true
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
return {
|
|
251
|
+
authDir: defaultDir,
|
|
252
|
+
isLegacy: false
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
function resolveWhatsAppAccount(params) {
|
|
256
|
+
const rootCfg = params.cfg.channels?.whatsapp;
|
|
257
|
+
const accountId = params.accountId?.trim() || resolveDefaultWhatsAppAccountId(params.cfg);
|
|
258
|
+
const accountCfg = resolveAccountConfig(params.cfg, accountId);
|
|
259
|
+
const enabled = accountCfg?.enabled !== false;
|
|
260
|
+
const { authDir, isLegacy } = resolveWhatsAppAuthDir({
|
|
261
|
+
cfg: params.cfg,
|
|
262
|
+
accountId
|
|
263
|
+
});
|
|
264
|
+
return {
|
|
265
|
+
accountId,
|
|
266
|
+
name: accountCfg?.name?.trim() || void 0,
|
|
267
|
+
enabled,
|
|
268
|
+
sendReadReceipts: accountCfg?.sendReadReceipts ?? rootCfg?.sendReadReceipts ?? true,
|
|
269
|
+
messagePrefix: accountCfg?.messagePrefix ?? rootCfg?.messagePrefix ?? params.cfg.messages?.messagePrefix,
|
|
270
|
+
authDir,
|
|
271
|
+
isLegacyAuthDir: isLegacy,
|
|
272
|
+
selfChatMode: accountCfg?.selfChatMode ?? rootCfg?.selfChatMode,
|
|
273
|
+
dmPolicy: accountCfg?.dmPolicy ?? rootCfg?.dmPolicy,
|
|
274
|
+
allowFrom: accountCfg?.allowFrom ?? rootCfg?.allowFrom,
|
|
275
|
+
groupAllowFrom: accountCfg?.groupAllowFrom ?? rootCfg?.groupAllowFrom,
|
|
276
|
+
groupPolicy: accountCfg?.groupPolicy ?? rootCfg?.groupPolicy,
|
|
277
|
+
textChunkLimit: accountCfg?.textChunkLimit ?? rootCfg?.textChunkLimit,
|
|
278
|
+
chunkMode: accountCfg?.chunkMode ?? rootCfg?.chunkMode,
|
|
279
|
+
mediaMaxMb: accountCfg?.mediaMaxMb ?? rootCfg?.mediaMaxMb,
|
|
280
|
+
blockStreaming: accountCfg?.blockStreaming ?? rootCfg?.blockStreaming,
|
|
281
|
+
ackReaction: accountCfg?.ackReaction ?? rootCfg?.ackReaction,
|
|
282
|
+
groups: accountCfg?.groups ?? rootCfg?.groups,
|
|
283
|
+
debounceMs: accountCfg?.debounceMs ?? rootCfg?.debounceMs
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
//#endregion
|
|
288
|
+
export { webAuthExists as _, resolveWhatsAppAuthDir as a, logWebSelfId as c, pickWebChannel as d, readCredsJsonRaw as f, resolveWebCredsPath as g, resolveWebCredsBackupPath as h, resolveWhatsAppAccount as i, logoutWeb as l, resolveDefaultWebAuthDir as m, listWhatsAppAccountIds as n, WA_WEB_AUTH_DIR as o, readWebSelfId as p, resolveDefaultWhatsAppAccountId as r, getWebAuthAgeMs as s, hasAnyWhatsAppAuth as t, maybeRestoreCredsFromBackup as u, resolveAccountEntry as v, createAccountListHelpers as y };
|