@wirecat/whatsapp-cli 0.0.0-stage → 0.1.0
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/LICENSE +204 -0
- package/README.md +282 -2
- package/dist/adapter/adapter.d.ts +9 -0
- package/dist/adapter/adapter.d.ts.map +1 -0
- package/dist/adapter/adapter.js +326 -0
- package/dist/adapter/adapter.js.map +1 -0
- package/dist/adapter/checks.d.ts +7 -0
- package/dist/adapter/checks.d.ts.map +1 -0
- package/dist/adapter/checks.js +3 -0
- package/dist/adapter/checks.js.map +1 -0
- package/dist/adapter/errors.d.ts +18 -0
- package/dist/adapter/errors.d.ts.map +1 -0
- package/dist/adapter/errors.js +40 -0
- package/dist/adapter/errors.js.map +1 -0
- package/dist/adapter/format-markdown.d.ts +8 -0
- package/dist/adapter/format-markdown.d.ts.map +1 -0
- package/dist/adapter/format-markdown.js +80 -0
- package/dist/adapter/format-markdown.js.map +1 -0
- package/dist/adapter/groups.d.ts +21 -0
- package/dist/adapter/groups.d.ts.map +1 -0
- package/dist/adapter/groups.js +210 -0
- package/dist/adapter/groups.js.map +1 -0
- package/dist/adapter/map.d.ts +9 -0
- package/dist/adapter/map.d.ts.map +1 -0
- package/dist/adapter/map.js +72 -0
- package/dist/adapter/map.js.map +1 -0
- package/dist/adapter/polls.d.ts +21 -0
- package/dist/adapter/polls.d.ts.map +1 -0
- package/dist/adapter/polls.js +103 -0
- package/dist/adapter/polls.js.map +1 -0
- package/dist/app.d.ts +6 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +16 -0
- package/dist/app.js.map +1 -0
- package/dist/bin/wa.d.ts +3 -0
- package/dist/bin/wa.d.ts.map +1 -0
- package/dist/bin/wa.js +27 -0
- package/dist/bin/wa.js.map +1 -0
- package/dist/commands/answer.d.ts +7 -0
- package/dist/commands/answer.d.ts.map +1 -0
- package/dist/commands/answer.js +11 -0
- package/dist/commands/answer.js.map +1 -0
- package/dist/commands/session.d.ts +37 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +202 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/setup.d.ts +3 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +192 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/update.d.ts +2 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +36 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/diagnose.d.ts +77 -0
- package/dist/diagnose.d.ts.map +1 -0
- package/dist/diagnose.js +84 -0
- package/dist/diagnose.js.map +1 -0
- package/dist/engine/contract.d.ts +617 -0
- package/dist/engine/contract.d.ts.map +1 -0
- package/dist/engine/contract.js +186 -0
- package/dist/engine/contract.js.map +1 -0
- package/dist/engine/events.d.ts +9 -0
- package/dist/engine/events.d.ts.map +1 -0
- package/dist/engine/events.js +23 -0
- package/dist/engine/events.js.map +1 -0
- package/dist/engine/go-engine.d.ts +23 -0
- package/dist/engine/go-engine.d.ts.map +1 -0
- package/dist/engine/go-engine.js +238 -0
- package/dist/engine/go-engine.js.map +1 -0
- package/dist/engine/groups.d.ts +159 -0
- package/dist/engine/groups.d.ts.map +1 -0
- package/dist/engine/groups.js +64 -0
- package/dist/engine/groups.js.map +1 -0
- package/dist/engine-binary.d.ts +5 -0
- package/dist/engine-binary.d.ts.map +1 -0
- package/dist/engine-binary.js +18 -0
- package/dist/engine-binary.js.map +1 -0
- package/dist/install/postinstall.d.ts +8 -0
- package/dist/install/postinstall.d.ts.map +1 -0
- package/dist/install/postinstall.js +62 -0
- package/dist/install/postinstall.js.map +1 -0
- package/dist/messenger.d.ts +64 -0
- package/dist/messenger.d.ts.map +1 -0
- package/dist/messenger.js +171 -0
- package/dist/messenger.js.map +1 -0
- package/dist/paths.d.ts +5 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +7 -0
- package/dist/paths.js.map +1 -0
- package/dist/program.d.ts +8 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +114 -0
- package/dist/program.js.map +1 -0
- package/dist/reasons.d.ts +4 -0
- package/dist/reasons.d.ts.map +1 -0
- package/dist/reasons.js +13 -0
- package/dist/reasons.js.map +1 -0
- package/dist/update.d.ts +8 -0
- package/dist/update.d.ts.map +1 -0
- package/dist/update.js +26 -0
- package/dist/update.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/install/postinstall.mjs +3 -0
- package/install/windows.ps1 +161 -0
- package/package.json +89 -4
- package/skills/whatsapp-cli/SKILL.md +290 -0
package/dist/paths.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { resolvePaths } from "@wirecat/cli-base";
|
|
3
|
+
import { WA } from "./app.js";
|
|
4
|
+
export const pathsFor = (env = process.env) => resolvePaths({ appName: WA.appName, prefix: WA.envPrefix, env });
|
|
5
|
+
/** The engine's device store: the linked device's keys, a credential as good as a password. One device per file. */
|
|
6
|
+
export const privateStore = (profile, env = process.env) => join(pathsFor(env).state, "profiles", profile, "private.db");
|
|
7
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAc,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAC5D,OAAO,EAAE,EAAE,EAAE,MAAM,UAAU,CAAA;AAE7B,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,GAAG,GAAsB,OAAO,CAAC,GAAG,EAAS,EAAE,CACtE,YAAY,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,CAAA;AAElE,oHAAoH;AACpH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAe,EAAE,GAAG,GAAsB,OAAO,CAAC,GAAG,EAAU,EAAE,CAC5F,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,CAAC,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import { type Environment } from "./messenger.js";
|
|
3
|
+
/** A revoked or missing login fails the same on every retry. */
|
|
4
|
+
export declare const NO_RESTART_ON: number[];
|
|
5
|
+
export declare const createProgram: () => Command;
|
|
6
|
+
/** Never throws: every outcome is an exit code, and a failure is said once, on stderr. */
|
|
7
|
+
export declare const run: (argv: string[], environment?: Environment) => Promise<number>;
|
|
8
|
+
//# sourceMappingURL=program.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../src/program.ts"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKxC,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,gBAAgB,CAAA;AAGlE,gEAAgE;AAChE,eAAO,MAAM,aAAa,UAAwC,CAAA;AAkElE,eAAO,MAAM,aAAa,QAAO,OAA6B,CAAA;AAE9D,0FAA0F;AAC1F,eAAO,MAAM,GAAG,SAAgB,MAAM,EAAE,gBAAe,WAAW,KAAQ,OAAO,CAAC,MAAM,CAcvF,CAAA"}
|
package/dist/program.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { appendFileSync } from "node:fs";
|
|
2
|
+
import { exitCodeFor, processStreams } from "@wirecat/cli-base";
|
|
3
|
+
import { accountCommand, attachmentsCommand, chatsCommand, commandsCommand, completeCommand, configCommand, contactsCommand, conversationsCommand, createProgram as create, doctorCommand, floodCommand, imagesCommand, inboxCommand, mcpCommand, mentionsCommand, messagesCommand, modelsCommand, pollsCommand, reactionsCommand, recipientsCommand, reviewCommand, run as runCli, runsCommand, searchCommand, searchesCommand, sendsCommand, serveCommand, serverCommand, skillCommand, statsCommand, storeCommand, tagsCommand, tasksCommand, watchCommand, } from "@wirecat/cli-core/cli";
|
|
4
|
+
import { CONFIG, WA } from "./app.js";
|
|
5
|
+
import { sessionCommand } from "./commands/session.js";
|
|
6
|
+
import { setupCommand } from "./commands/setup.js";
|
|
7
|
+
import { upgradeCommand } from "./commands/update.js";
|
|
8
|
+
import { SKILL, WHATSAPP } from "./messenger.js";
|
|
9
|
+
import { updateNotice } from "./update.js";
|
|
10
|
+
/** A revoked or missing login fails the same on every retry. */
|
|
11
|
+
export const NO_RESTART_ON = [exitCodeFor("authentication_error")];
|
|
12
|
+
const definition = {
|
|
13
|
+
app: WA,
|
|
14
|
+
configuration: CONFIG,
|
|
15
|
+
configure: (program) => {
|
|
16
|
+
program.addHelpText("after", "\nGetting started after installation:\n" +
|
|
17
|
+
" wa personal setup Guided first run as profile personal; about 5 minutes\n" +
|
|
18
|
+
" wa personal setup --agent codex Link and install your agent's skill\n" +
|
|
19
|
+
" wa setup --help Linking choices, examples and Windows instructions\n" +
|
|
20
|
+
"Every account command names its profile first: `wa personal chats list`.\n" +
|
|
21
|
+
"\nFor agents:\n" +
|
|
22
|
+
" wa skill show Read the bundled instructions before using WhatsApp\n" +
|
|
23
|
+
" wa commands --json Discover commands, arguments and flags\n");
|
|
24
|
+
program.commands
|
|
25
|
+
.find((command) => command.name() === "skill")
|
|
26
|
+
?.addHelpText("after", "\nBefore the first link, an agent can read `wa skill show`; no device is needed.\n" +
|
|
27
|
+
"Run `wa personal setup --agent codex` for guided linking and skill installation.\n" +
|
|
28
|
+
"To install instructions separately: `wa skill install --for all`.\n");
|
|
29
|
+
},
|
|
30
|
+
commands: () => loggingArgv([
|
|
31
|
+
sessionCommand(),
|
|
32
|
+
setupCommand(),
|
|
33
|
+
accountCommand(WHATSAPP),
|
|
34
|
+
chatsCommand(WHATSAPP),
|
|
35
|
+
contactsCommand(WHATSAPP),
|
|
36
|
+
messagesCommand(WHATSAPP),
|
|
37
|
+
reactionsCommand(WHATSAPP),
|
|
38
|
+
pollsCommand(WHATSAPP),
|
|
39
|
+
modelsCommand(WHATSAPP),
|
|
40
|
+
inboxCommand(WHATSAPP),
|
|
41
|
+
reviewCommand(WHATSAPP),
|
|
42
|
+
watchCommand(WHATSAPP),
|
|
43
|
+
serveCommand(WHATSAPP),
|
|
44
|
+
serverCommand(WHATSAPP, { unit: { noRestartOn: NO_RESTART_ON } }),
|
|
45
|
+
storeCommand(WHATSAPP),
|
|
46
|
+
conversationsCommand(WHATSAPP),
|
|
47
|
+
attachmentsCommand(WHATSAPP),
|
|
48
|
+
tagsCommand(WHATSAPP),
|
|
49
|
+
mentionsCommand(WHATSAPP),
|
|
50
|
+
imagesCommand(WHATSAPP),
|
|
51
|
+
statsCommand(WHATSAPP),
|
|
52
|
+
tasksCommand(WHATSAPP),
|
|
53
|
+
searchCommand(WHATSAPP),
|
|
54
|
+
searchesCommand(WHATSAPP),
|
|
55
|
+
floodCommand(WHATSAPP),
|
|
56
|
+
recipientsCommand(WHATSAPP),
|
|
57
|
+
sendsCommand(WHATSAPP),
|
|
58
|
+
runsCommand(WA),
|
|
59
|
+
configCommand(WA, CONFIG),
|
|
60
|
+
doctorCommand(WHATSAPP),
|
|
61
|
+
commandsCommand(WA),
|
|
62
|
+
completeCommand(WHATSAPP, CONFIG),
|
|
63
|
+
upgradeCommand(),
|
|
64
|
+
mcpCommand(WHATSAPP),
|
|
65
|
+
skillCommand(WA, SKILL),
|
|
66
|
+
]),
|
|
67
|
+
};
|
|
68
|
+
export const createProgram = () => create(definition);
|
|
69
|
+
/** Never throws: every outcome is an exit code, and a failure is said once, on stderr. */
|
|
70
|
+
export const run = async (argv, environment = {}) => {
|
|
71
|
+
const notice = updateNotice(argv, {
|
|
72
|
+
...(environment.tty === undefined ? {} : { tty: environment.tty }),
|
|
73
|
+
...(environment.update ? { environment: environment.update } : {}),
|
|
74
|
+
...(environment.env ? { env: environment.env } : {}),
|
|
75
|
+
});
|
|
76
|
+
const code = await runCli(argv, definition, environment);
|
|
77
|
+
const line = await notice;
|
|
78
|
+
const argvLog = process.env.WA_TEST_ARGV_LOG;
|
|
79
|
+
// --version ends before any action, so the preAction hook never sees it.
|
|
80
|
+
if (argvLog && code === 0 && argv.some((word) => word === "--version" || word === "-V"))
|
|
81
|
+
appendFileSync(argvLog, `${JSON.stringify({ command: "", options: ["--version"] })}\n`);
|
|
82
|
+
if (line && code === 0)
|
|
83
|
+
(environment.streams ?? processStreams).diagnostic(line);
|
|
84
|
+
return code;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Under vitest only: which command a test drove and the option names it gave, never a value
|
|
88
|
+
* (`pnpm test:matrix`). The hook sits on each top-level command because the root program is built
|
|
89
|
+
* inside cli-core; commander runs an ancestor's preAction hook for every subcommand.
|
|
90
|
+
*/
|
|
91
|
+
function loggingArgv(commands) {
|
|
92
|
+
const file = process.env.WA_TEST_ARGV_LOG;
|
|
93
|
+
if (file)
|
|
94
|
+
for (const command of commands)
|
|
95
|
+
command.hook("preAction", (_self, action) => logParsed(file, action));
|
|
96
|
+
return commands;
|
|
97
|
+
}
|
|
98
|
+
const logParsed = (file, action) => {
|
|
99
|
+
const words = [];
|
|
100
|
+
const options = [];
|
|
101
|
+
for (let at = action; at; at = at.parent) {
|
|
102
|
+
if (at.parent)
|
|
103
|
+
words.unshift(at.name());
|
|
104
|
+
for (const option of at.options) {
|
|
105
|
+
const key = option.attributeName();
|
|
106
|
+
if (at.getOptionValueSource(key) !== "cli" || !option.long)
|
|
107
|
+
continue;
|
|
108
|
+
if (option.negate === (at.getOptionValue(key) === false))
|
|
109
|
+
options.push(option.long);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
appendFileSync(file, `${JSON.stringify({ command: words.join(" "), options })}\n`);
|
|
113
|
+
};
|
|
114
|
+
//# sourceMappingURL=program.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"program.js","sourceRoot":"","sources":["../src/program.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reasons.d.ts","sourceRoot":"","sources":["../src/reasons.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,6BAA6B,CAAA;AAE7E,wFAAwF;AACxF,eAAO,MAAM,OAAO,EAAE,WAAW,EAahC,CAAA"}
|
package/dist/reasons.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { defineReasons } from "@wirecat/cli-base/standards";
|
|
2
|
+
/** Every reason wa raises beyond cli-core's, so an agent branches on it (WC-OUT-15). */
|
|
3
|
+
export const REASONS = defineReasons([
|
|
4
|
+
["device.in-use", "provider_unavailable", "another wa process holds this WhatsApp login"],
|
|
5
|
+
["device.replaced", "provider_unavailable", "another connection took over this WhatsApp login"],
|
|
6
|
+
["device.logged-out", "authentication_error", "WhatsApp logged this device out"],
|
|
7
|
+
["client.outdated", "provider_unavailable", "WhatsApp no longer accepts this version of wa"],
|
|
8
|
+
["account.banned", "permission_error", "WhatsApp has banned or restricted this account"],
|
|
9
|
+
["account.rate-limited", "rate_limited", "WhatsApp asked this account to slow down"],
|
|
10
|
+
["engine.stopped", "provider_unavailable", "the WhatsApp engine stopped unexpectedly"],
|
|
11
|
+
["engine.stopped-mid-write", "outcome_unknown", "the WhatsApp engine stopped before WhatsApp confirmed a change"],
|
|
12
|
+
].map(([reason, code, message]) => ({ reason, code, message, details: [] })));
|
|
13
|
+
//# sourceMappingURL=reasons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reasons.js","sourceRoot":"","sources":["../src/reasons.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAoB,MAAM,6BAA6B,CAAA;AAE7E,wFAAwF;AACxF,MAAM,CAAC,MAAM,OAAO,GAAkB,aAAa,CAE/C;IACE,CAAC,eAAe,EAAE,sBAAsB,EAAE,8CAA8C,CAAC;IACzF,CAAC,iBAAiB,EAAE,sBAAsB,EAAE,kDAAkD,CAAC;IAC/F,CAAC,mBAAmB,EAAE,sBAAsB,EAAE,iCAAiC,CAAC;IAChF,CAAC,iBAAiB,EAAE,sBAAsB,EAAE,+CAA+C,CAAC;IAC5F,CAAC,gBAAgB,EAAE,kBAAkB,EAAE,gDAAgD,CAAC;IACxF,CAAC,sBAAsB,EAAE,cAAc,EAAE,0CAA0C,CAAC;IACpF,CAAC,gBAAgB,EAAE,sBAAsB,EAAE,0CAA0C,CAAC;IACtF,CAAC,0BAA0B,EAAE,iBAAiB,EAAE,gEAAgE,CAAC;CAEpH,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,CAC7E,CAAA"}
|
package/dist/update.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type UpdateEnvironment } from "@wirecat/cli-core/update";
|
|
2
|
+
export type { UpdateEnvironment };
|
|
3
|
+
export declare const PACKAGE = "@wirecat/whatsapp-cli";
|
|
4
|
+
export declare const installer: ({ scriptPath }?: UpdateEnvironment) => import("@wirecat/cli-base/update").Installer, latest: (environment?: UpdateEnvironment) => Promise<string | undefined>, runUpdate: (argv: string[], environment?: UpdateEnvironment) => number, updateNotice: (argv: readonly string[], { tty, environment, env }?: import("@wirecat/cli-core/update").NoticeOptions) => Promise<string | undefined>;
|
|
5
|
+
/** This install's own entry point — after an update, the new code at the same path. */
|
|
6
|
+
export declare const waScript: () => string;
|
|
7
|
+
export declare const restartServer: (profile: string, env: NodeJS.ProcessEnv, environment?: UpdateEnvironment) => number;
|
|
8
|
+
//# sourceMappingURL=update.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../src/update.ts"],"names":[],"mappings":"AAGA,OAAO,EAAa,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAK5E,YAAY,EAAE,iBAAiB,EAAE,CAAA;AAEjC,eAAO,MAAM,OAAO,0BAA0B,CAAA;AAE9C,eAAO,MAAQ,SAAS,wFAAE,MAAM,oEAAE,SAAS,+DAAE,YAAY,wIAQvD,CAAA;AAEF,uFAAuF;AACvF,eAAO,MAAM,QAAQ,QAAO,MAAgE,CAAA;AAE5F,eAAO,MAAM,aAAa,YAAa,MAAM,OAAO,MAAM,CAAC,UAAU,gBAAe,iBAAiB,KAAQ,MAK5G,CAAA"}
|
package/dist/update.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { appUpdate } from "@wirecat/cli-core/update";
|
|
5
|
+
import { resolveSettings } from "./app.js";
|
|
6
|
+
import { pathsFor } from "./paths.js";
|
|
7
|
+
import { VERSION } from "./version.js";
|
|
8
|
+
export const PACKAGE = "@wirecat/whatsapp-cli";
|
|
9
|
+
export const { installer, latest, runUpdate, updateNotice } = appUpdate({
|
|
10
|
+
packageName: PACKAGE,
|
|
11
|
+
command: "wa",
|
|
12
|
+
version: VERSION,
|
|
13
|
+
entry: import.meta.url,
|
|
14
|
+
statePath: (env) => join(pathsFor(env).state, "update-check.json"),
|
|
15
|
+
enabled: (env) => resolveSettings({}, { env, needsProfile: false }).updateCheck,
|
|
16
|
+
offVariables: ["WA_NO_UPDATE_CHECK"],
|
|
17
|
+
});
|
|
18
|
+
/** This install's own entry point — after an update, the new code at the same path. */
|
|
19
|
+
export const waScript = () => fileURLToPath(new URL("./bin/wa.js", import.meta.url));
|
|
20
|
+
export const restartServer = (profile, env, environment = {}) => {
|
|
21
|
+
const argv = [waScript(), profile, "server", "restart"];
|
|
22
|
+
return environment.spawn
|
|
23
|
+
? environment.spawn([process.execPath, ...argv])
|
|
24
|
+
: (spawnSync(process.execPath, argv, { env, shell: false, stdio: ["ignore", 2, 2] }).status ?? 1);
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../src/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,SAAS,EAA0B,MAAM,0BAA0B,CAAA;AAC5E,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAItC,MAAM,CAAC,MAAM,OAAO,GAAG,uBAAuB,CAAA;AAE9C,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,SAAS,CAAC;IACtE,WAAW,EAAE,OAAO;IACpB,OAAO,EAAE,IAAI;IACb,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,OAAO,IAAI,CAAC,GAAG;IACtB,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,mBAAmB,CAAC;IAClE,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,eAAe,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC,WAAW;IAC/E,YAAY,EAAE,CAAC,oBAAoB,CAAC;CACrC,CAAC,CAAA;AAEF,uFAAuF;AACvF,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAW,EAAE,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,aAAa,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAE5F,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,OAAe,EAAE,GAAsB,EAAE,WAAW,GAAsB,EAAE,EAAU,EAAE;IACpH,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAA;IACvD,OAAO,WAAW,CAAC,KAAK;QACtB,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAA;AACrG,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,UAAU,CAAA"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAA"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
param(
|
|
2
|
+
[ValidateSet('wa')][string] $Tool = 'wa',
|
|
3
|
+
[ValidateSet('all', 'codex', 'cursor', 'claude', 'gemini', 'none')][string] $Agent = 'all',
|
|
4
|
+
[string] $Prefix,
|
|
5
|
+
[string] $PackageSpec,
|
|
6
|
+
[string] $NodeDirectory,
|
|
7
|
+
[switch] $RepairOnly,
|
|
8
|
+
[switch] $Json
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
$ErrorActionPreference = 'Stop'
|
|
12
|
+
if ($env:OS -ne 'Windows_NT') { throw 'This installer is for Windows.' }
|
|
13
|
+
|
|
14
|
+
function Note([string] $Message) {
|
|
15
|
+
if ($Json) { [Console]::Error.WriteLine($Message) } else { Write-Host $Message }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function NormalPath([string] $Value) {
|
|
19
|
+
$expanded = [Environment]::ExpandEnvironmentVariables($Value.Trim().Trim('"'))
|
|
20
|
+
return $expanded.TrimEnd('\', '/').ToLowerInvariant()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function ContainsPath([string] $Value, [string] $Directory) {
|
|
24
|
+
$wanted = NormalPath $Directory
|
|
25
|
+
foreach ($entry in ($Value -split ';')) {
|
|
26
|
+
if ($entry.Trim() -and (NormalPath $entry) -eq $wanted) { return $true }
|
|
27
|
+
}
|
|
28
|
+
return $false
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function AddUserPaths([string[]] $Directories) {
|
|
32
|
+
$key = [Microsoft.Win32.Registry]::CurrentUser.CreateSubKey('Environment')
|
|
33
|
+
try {
|
|
34
|
+
$old = [string] $key.GetValue('Path', '', [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames)
|
|
35
|
+
$kind = [Microsoft.Win32.RegistryValueKind]::ExpandString
|
|
36
|
+
if ($key.GetValueNames() -contains 'Path') { $kind = $key.GetValueKind('Path') }
|
|
37
|
+
$machine = [Environment]::GetEnvironmentVariable('Path', 'Machine')
|
|
38
|
+
$updated = $old
|
|
39
|
+
$added = @()
|
|
40
|
+
foreach ($directory in $Directories) {
|
|
41
|
+
if (-not (ContainsPath "$machine;$updated" $directory)) {
|
|
42
|
+
$updated = if ($updated) { "$directory;$updated" } else { $directory }
|
|
43
|
+
$added += $directory
|
|
44
|
+
}
|
|
45
|
+
$remaining = ($env:Path -split ';') | Where-Object { (NormalPath $_) -ne (NormalPath $directory) }
|
|
46
|
+
$env:Path = "$directory;" + ($remaining -join ';')
|
|
47
|
+
}
|
|
48
|
+
if ($updated.Length -gt 32767) { throw 'User PATH is too long to add the CLI safely.' }
|
|
49
|
+
if ($updated -ne $old) { $key.SetValue('Path', $updated, $kind) }
|
|
50
|
+
} finally { $key.Dispose() }
|
|
51
|
+
if ($added.Count) {
|
|
52
|
+
if (-not ('WireCat.EnvironmentChange' -as [type])) {
|
|
53
|
+
Add-Type -TypeDefinition @'
|
|
54
|
+
using System;
|
|
55
|
+
using System.Runtime.InteropServices;
|
|
56
|
+
namespace WireCat {
|
|
57
|
+
public class EnvironmentChange {
|
|
58
|
+
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
59
|
+
public static extern IntPtr SendMessageTimeout(IntPtr window, uint message,
|
|
60
|
+
UIntPtr wParam, string lParam, uint flags, uint timeout, out UIntPtr result);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
'@
|
|
64
|
+
}
|
|
65
|
+
$result = [UIntPtr]::Zero
|
|
66
|
+
$null = [WireCat.EnvironmentChange]::SendMessageTimeout([IntPtr] 0xffff, 0x1a,
|
|
67
|
+
[UIntPtr]::Zero, 'Environment', 2, 2000, [ref] $result)
|
|
68
|
+
}
|
|
69
|
+
return $added
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function RemoveGeneratedPowerShellShim([string] $Directory) {
|
|
73
|
+
$script = Join-Path $Directory "$Tool.ps1"
|
|
74
|
+
if (Test-Path -LiteralPath $script) {
|
|
75
|
+
$content = (Get-Content -LiteralPath $script -Raw).Replace('\', '/')
|
|
76
|
+
if (-not $content.Contains("node_modules/@wirecat/whatsapp-cli/dist/bin/$Tool.js")) {
|
|
77
|
+
throw "An unrelated $Tool.ps1 exists in the npm prefix; it was left untouched."
|
|
78
|
+
}
|
|
79
|
+
# npm's .cmd launcher works even when PowerShell refuses unsigned .ps1 scripts.
|
|
80
|
+
Remove-Item -LiteralPath $script
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
$node = (Get-Command node -CommandType Application -ErrorAction Stop | Select-Object -First 1).Source
|
|
85
|
+
if (-not $NodeDirectory) { $NodeDirectory = Split-Path $node -Parent }
|
|
86
|
+
if (-not $Prefix) {
|
|
87
|
+
$npm = (Get-Command npm.cmd -CommandType Application -ErrorAction Stop | Select-Object -First 1).Source
|
|
88
|
+
$Prefix = (& $npm prefix -g | Out-String).Trim()
|
|
89
|
+
if ($LASTEXITCODE -ne 0) { throw 'Could not determine the npm installation folder.' }
|
|
90
|
+
}
|
|
91
|
+
$Prefix = [IO.Path]::GetFullPath($Prefix)
|
|
92
|
+
if ($Prefix.Contains(';') -or $NodeDirectory.Contains(';')) { throw 'Installation folders cannot contain a semicolon.' }
|
|
93
|
+
|
|
94
|
+
if (-not $RepairOnly) {
|
|
95
|
+
$nodeVersion = (& $node --version | Out-String).Trim()
|
|
96
|
+
if ($LASTEXITCODE -ne 0 -or $nodeVersion -notmatch '^v(\d+)\.(\d+)\.') { throw 'Could not read the Node.js version.' }
|
|
97
|
+
$major = [int] $Matches[1]
|
|
98
|
+
$minor = [int] $Matches[2]
|
|
99
|
+
if (-not ($major -ge 24 -or ($major -eq 22 -and $minor -ge 16))) {
|
|
100
|
+
throw 'Node.js 22.16+ or 24+ is required. Install a supported Node.js release first.'
|
|
101
|
+
}
|
|
102
|
+
$npm = (Get-Command npm.cmd -CommandType Application -ErrorAction Stop | Select-Object -First 1).Source
|
|
103
|
+
$package = "@wirecat/whatsapp-cli"
|
|
104
|
+
if (-not $PackageSpec) { $PackageSpec = $package }
|
|
105
|
+
Note "1/3 Installing $package..."
|
|
106
|
+
$savedPreference = $ErrorActionPreference
|
|
107
|
+
$agentVariable = $Tool.ToUpperInvariant() + '_INSTALL_AGENT'
|
|
108
|
+
$savedAgent = [Environment]::GetEnvironmentVariable($agentVariable, 'Process')
|
|
109
|
+
try {
|
|
110
|
+
# PowerShell 5.1 turns redirected native warnings into errors; npm's exit code decides success.
|
|
111
|
+
$ErrorActionPreference = 'Continue'
|
|
112
|
+
[Environment]::SetEnvironmentVariable($agentVariable, $Agent, 'Process')
|
|
113
|
+
$log = & $npm install --global --prefix $Prefix "--allow-scripts=$package" --foreground-scripts $PackageSpec 2>&1
|
|
114
|
+
$installExit = $LASTEXITCODE
|
|
115
|
+
} finally {
|
|
116
|
+
$ErrorActionPreference = $savedPreference
|
|
117
|
+
[Environment]::SetEnvironmentVariable($agentVariable, $savedAgent, 'Process')
|
|
118
|
+
}
|
|
119
|
+
foreach ($line in $log) { Note ([string] $line) }
|
|
120
|
+
if ($installExit -ne 0) { throw 'npm installation failed; PATH was not changed.' }
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
$shim = Join-Path $Prefix "$Tool.cmd"
|
|
124
|
+
if (-not (Test-Path -LiteralPath $shim)) { throw "The installation did not create $Tool.cmd." }
|
|
125
|
+
$added = @(AddUserPaths @($NodeDirectory, $Prefix))
|
|
126
|
+
RemoveGeneratedPowerShellShim $Prefix
|
|
127
|
+
|
|
128
|
+
if ($RepairOnly) {
|
|
129
|
+
if ($Json) { @{ tool = $Tool; prefix = $Prefix; pathAdded = $added } | ConvertTo-Json -Compress }
|
|
130
|
+
exit 0
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
Note '2/3 PATH is ready in this terminal and saved for future terminals.'
|
|
134
|
+
$version = (& $shim --version | Out-String).Trim()
|
|
135
|
+
if ($LASTEXITCODE -ne 0) { throw 'The installed CLI could not start.' }
|
|
136
|
+
$written = @()
|
|
137
|
+
if ($Agent -ne 'none') {
|
|
138
|
+
Note "3/3 Installing agent instructions ($Agent)..."
|
|
139
|
+
$target = if ($Agent -eq 'all') { 'all' } elseif ($Agent -eq 'claude') { 'claude' } else { 'agents' }
|
|
140
|
+
$skillJson = & $shim skill install --for $target --json
|
|
141
|
+
if ($LASTEXITCODE -ne 0) { throw 'Agent skill installation failed.' }
|
|
142
|
+
$skill = ($skillJson -join "`n") | ConvertFrom-Json
|
|
143
|
+
$written = @($skill.written)
|
|
144
|
+
if (-not $written.Count) { throw 'Agent skill installation wrote no instructions.' }
|
|
145
|
+
foreach ($file in $written) {
|
|
146
|
+
if (-not (Test-Path -LiteralPath $file)) { throw 'An installed agent skill could not be found.' }
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
$resolved = Get-Command $Tool -CommandType Application -ErrorAction Stop | Select-Object -First 1
|
|
151
|
+
if ([IO.Path]::GetFullPath($resolved.Source) -ne [IO.Path]::GetFullPath($shim)) {
|
|
152
|
+
throw "Another $Tool command shadows this installation on PATH."
|
|
153
|
+
}
|
|
154
|
+
$directVersion = (& $Tool --version | Out-String).Trim()
|
|
155
|
+
if ($LASTEXITCODE -ne 0 -or $directVersion -ne $version) { throw "Bare $Tool did not start the installed version." }
|
|
156
|
+
Note "$Tool $version is ready. Agent: read '$Tool skill show' before login; the skill is already installed."
|
|
157
|
+
Note 'Account login is the next step; the owner enters codes or scans the QR locally.'
|
|
158
|
+
if ($Json) {
|
|
159
|
+
@{ tool = $Tool; version = $version; prefix = $Prefix; pathAdded = $added;
|
|
160
|
+
agent = $Agent; written = $written; instructions = "$Tool skill show" } | ConvertTo-Json -Compress
|
|
161
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,91 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wirecat/whatsapp-cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A personal WhatsApp account from the terminal, as a linked device — built for agents and scripts",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"author": "Viacheslav Ptsarev",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/WireCatLabs/whatsapp-cli.git"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": "^22.16.0 || >=24"
|
|
14
|
+
},
|
|
15
|
+
"packageManager": "pnpm@11.20.0",
|
|
16
|
+
"bin": {
|
|
17
|
+
"wa": "dist/bin/wa.js"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"skills",
|
|
22
|
+
"install",
|
|
23
|
+
"README.md",
|
|
24
|
+
"LICENSE"
|
|
25
|
+
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsc --build --force",
|
|
28
|
+
"typecheck": "tsc --build --force --emitDeclarationOnly && tsc -p tsconfig.test.json && tsc -p tsconfig.scripts.json",
|
|
29
|
+
"lint": "biome check .",
|
|
30
|
+
"lint:fix": "biome check --write .",
|
|
31
|
+
"test": "vitest run",
|
|
32
|
+
"test:watch": "vitest",
|
|
33
|
+
"test:coverage": "vitest run --coverage",
|
|
34
|
+
"test:matrix": "vitest run >/dev/null && pnpm build >/dev/null && cli-dev test-matrix --program dist/program.js --untested scripts/test-matrix-untested.ts --name wa --check",
|
|
35
|
+
"test:slow": "vitest run --reporter=json --outputFile=coverage/tests.json >/dev/null; cli-dev slow-tests",
|
|
36
|
+
"engine:test": "cd engine && unformatted=$(\"$(go env GOROOT)/bin/gofmt\" -l .) && { test -z \"$unformatted\" || { echo \"not gofmt-formatted: $unformatted\" >&2; exit 1; }; } && go vet ./... && go test ./...",
|
|
37
|
+
"generate": "pnpm build && node --experimental-strip-types scripts/commands.ts",
|
|
38
|
+
"smoke:bun": "bun run scripts/smoke.ts",
|
|
39
|
+
"release:check": "pnpm build && node --experimental-strip-types scripts/release-check.ts",
|
|
40
|
+
"docs:check": "cli-dev docs-check --rules scripts/release/checks.ts --pages && cspell --no-progress --no-summary README.md 'docs/*.md' && rumdl check --config config/wirecat/rumdl.toml README.md docs/*.md",
|
|
41
|
+
"parity:check": "pnpm build && node dist/bin/wa.js commands --json | cli-core-parity wa && node dist/bin/wa.js commands --json | cli-core-parity wa --pages README.md docs/*.md",
|
|
42
|
+
"version:check": "cli-dev version && node scripts/engine-packages.mjs check",
|
|
43
|
+
"version:sync": "cli-dev version --sync && node scripts/engine-packages.mjs sync",
|
|
44
|
+
"prepare": "lefthook install || true",
|
|
45
|
+
"secrets:scan": "gitleaks git --no-banner --redact .",
|
|
46
|
+
"prepack": "rm -rf dist tsconfig.tsbuildinfo && pnpm build",
|
|
47
|
+
"postinstall": "node install/postinstall.mjs",
|
|
48
|
+
"check:agent-docs": "pnpm build && node --experimental-strip-types scripts/check-agent-docs.ts",
|
|
49
|
+
"standards:check": "node config/wirecat/check.mjs",
|
|
50
|
+
"docs:lint": "markdownlint-cli2",
|
|
51
|
+
"docs:spell": "cspell lint --config cspell.json --no-progress README.md",
|
|
52
|
+
"ci:quick": "pnpm typecheck && pnpm build && pnpm lint:commands",
|
|
53
|
+
"contracts:check": "cli-contract contracts/plan.json",
|
|
54
|
+
"security:no-leak": "cli-testing security no-leak . contracts/no-leak.json",
|
|
55
|
+
"lint:commands": "cli-dev lint --cli dist/bin/wa.js",
|
|
56
|
+
"engine:build": "cd engine && go build -trimpath -ldflags=\"-s -w\" -o bin/wa-engine ./cmd/wa-engine",
|
|
57
|
+
"engine:packages": "node scripts/engine-packages.mjs build"
|
|
58
|
+
},
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"@wirecat/cli-base": "0.43.1",
|
|
61
|
+
"@wirecat/cli-core": "0.326.0",
|
|
62
|
+
"commander": "15.0.0",
|
|
63
|
+
"valibot": "1.5.0"
|
|
64
|
+
},
|
|
65
|
+
"optionalDependencies": {
|
|
66
|
+
"@wirecat/whatsapp-engine-darwin-arm64": "0.1.0",
|
|
67
|
+
"@wirecat/whatsapp-engine-darwin-x64": "0.1.0",
|
|
68
|
+
"@wirecat/whatsapp-engine-linux-arm64": "0.1.0",
|
|
69
|
+
"@wirecat/whatsapp-engine-linux-x64": "0.1.0",
|
|
70
|
+
"@wirecat/whatsapp-engine-win32-arm64": "0.1.0",
|
|
71
|
+
"@wirecat/whatsapp-engine-win32-x64": "0.1.0"
|
|
72
|
+
},
|
|
73
|
+
"devDependencies": {
|
|
74
|
+
"@biomejs/biome": "2.5.15",
|
|
75
|
+
"@cspell/dict-en-gb": "5.0.34",
|
|
76
|
+
"@cspell/dict-es-es": "3.0.9",
|
|
77
|
+
"@cspell/dict-ru_ru": "2.3.3",
|
|
78
|
+
"@types/node": "^22.20.4",
|
|
79
|
+
"@vitest/coverage-v8": "^5.0.3",
|
|
80
|
+
"@wirecat/cli-testing": "0.5.2",
|
|
81
|
+
"cspell": "10.3.6",
|
|
82
|
+
"lefthook": "2.1.16",
|
|
83
|
+
"markdownlint-cli2": "0.23.3",
|
|
84
|
+
"rumdl": "^0.2.79",
|
|
85
|
+
"typescript": "^7.0.2",
|
|
86
|
+
"vitest": "^5.0.3"
|
|
87
|
+
},
|
|
88
|
+
"publishConfig": {
|
|
89
|
+
"access": "public"
|
|
90
|
+
}
|
|
91
|
+
}
|