@agentcomms/whatsapp 0.7.1 → 0.7.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/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { $ as withFileLock, A as CommsError, B as installExitStatus, C as checkStorePath, F as canPrompt, G as paint, H as lookupName, I as channelManifest, J as runCommand, K as renderInstall, L as colorEnabled, M as agentMarker, N as approvalKind, O as CHANNELS, P as approveChangeAtTerminal, Q as truncateDisplay, R as escapeForDisplay, S as storeIdentity, T as expandSource, U as nameAvailable, V as isCommsError, W as nameShapeProblem, X as serverPruneChange, Y as serverInstallChange, _ as chatRefOf, a as listChats, b as requireAccount, c as Presenter, d as draftMessage, et as writeResult, f as Visibility, g as requireSupportedNode, h as WhatsAppIndex, i as CHAT_KINDS, j as EXIT_CODES, k as CHANNEL_SERVERS, l as innerText, m as WhatsAppContext, n as whatsappStatus, o as readChat, p as listKey, q as renderPrune, r as probeStore, s as searchMessages, t as syncAccount, tt as VERSION, v as PLATFORM, w as defaultStorePath, x as requireNamedConfig, y as newWhatsAppAccount, z as gatedChangeAtTerminal } from "./sync-C2WSnOq1.mjs";
2
+ import { $ as withFileLock, A as CommsError, B as installExitStatus, C as checkStorePath, F as canPrompt, G as paint, H as lookupName, I as channelManifest, J as runCommand, K as renderInstall, L as colorEnabled, M as agentMarker, N as approvalKind, O as CHANNELS, P as approveChangeAtTerminal, Q as truncateDisplay, R as escapeForDisplay, S as storeIdentity, T as expandSource, U as nameAvailable, V as isCommsError, W as nameShapeProblem, X as serverPruneChange, Y as serverInstallChange, _ as chatRefOf, a as listChats, b as requireAccount, c as Presenter, d as draftMessage, et as writeResult, f as Visibility, g as requireSupportedNode, h as WhatsAppIndex, i as CHAT_KINDS, j as EXIT_CODES, k as CHANNEL_SERVERS, l as innerText, m as WhatsAppContext, n as whatsappStatus, o as readChat, p as listKey, q as renderPrune, r as probeStore, s as searchMessages, t as syncAccount, tt as VERSION, v as PLATFORM, w as defaultStorePath, x as requireNamedConfig, y as newWhatsAppAccount, z as gatedChangeAtTerminal } from "./sync-DDPszuIn.mjs";
3
3
  import { rm } from "node:fs/promises";
4
4
  import path from "node:path";
5
5
  import { stripVTControlCharacters } from "node:util";
@@ -3495,7 +3495,7 @@ a macOS dialog may be waiting) · 77 permission needed (macOS privacy) · 78 con
3495
3495
  ran = true;
3496
3496
  exitCode = await runCommand(output(), async () => {
3497
3497
  requireSupportedNode();
3498
- const { startWhatsAppStdioServer } = await import("./stdio-entry-BF9Sjjpl.mjs");
3498
+ const { startWhatsAppStdioServer } = await import("./stdio-entry-IB-6jDdg.mjs");
3499
3499
  await startWhatsAppStdioServer({
3500
3500
  env,
3501
3501
  ...flags.account ? { account: String(flags.account) } : {}
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { tt as VERSION, u as composeDraft } from "./sync-C2WSnOq1.mjs";
2
- import { t as createWhatsAppMcpServer } from "./server-CPNq8D28.mjs";
1
+ import { tt as VERSION, u as composeDraft } from "./sync-DDPszuIn.mjs";
2
+ import { t as createWhatsAppMcpServer } from "./server-BS674Vx-.mjs";
3
3
  //#region src/index.ts
4
4
  /**
5
5
  * The library entry of `@agentcomms/whatsapp`.
@@ -1,4 +1,4 @@
1
- import { D as strictToolArguments, E as UNTRUSTED_NOTICE, Z as toCommsError, a as listChats, d as draftMessage, i as CHAT_KINDS, m as WhatsAppContext, n as whatsappStatus, o as readChat, s as searchMessages, t as syncAccount, tt as VERSION } from "./sync-C2WSnOq1.mjs";
1
+ import { D as strictToolArguments, E as UNTRUSTED_NOTICE, Z as toCommsError, a as listChats, d as draftMessage, i as CHAT_KINDS, m as WhatsAppContext, n as whatsappStatus, o as readChat, s as searchMessages, t as syncAccount, tt as VERSION } from "./sync-DDPszuIn.mjs";
2
2
  import { c as boolean, h as number, x as string } from "./schemas-DiGKNDNq.mjs";
3
3
  import { t as McpServer } from "./mcp-DXXb3Vv3-Co5BzjYe.mjs";
4
4
  //#region src/mcp/server.ts
@@ -1,4 +1,4 @@
1
- import { t as createWhatsAppMcpServer } from "./server-CPNq8D28.mjs";
1
+ import { t as createWhatsAppMcpServer } from "./server-BS674Vx-.mjs";
2
2
  //#region src/mcp/stdio-entry.ts
3
3
  /**
4
4
  * Starting the stdio server. On stdio, stdout is the protocol, so the console is redirected to stderr first — the
@@ -11,9 +11,9 @@ import { constants as constants$1 } from "node:fs";
11
11
  //#endregion
12
12
  //#region src/version.ts
13
13
  /** The package version, read from package.json at build time. */
14
- const VERSION$1 = "0.7.1";
14
+ const VERSION$1 = "0.7.2";
15
15
  //#endregion
16
- //#region ../core/dist/servers-XHOQHOxT.mjs
16
+ //#region ../core/dist/servers-CI6C4CNi.mjs
17
17
  /**
18
18
  * Every failure a user or an agent can act on carries a specific, stable code from this registry, a message, an
19
19
  * optional one-line hint and structured `details`. The code decides the process exit status; agents and skills branch
@@ -3881,7 +3881,56 @@ const PIN_OPTIONS = Object.freeze([
3881
3881
  ]);
3882
3882
  /** Looks for an executable on PATH, the way a shell would. */
3883
3883
  async function whichExecutable(name, env) {
3884
- const paths = (env.PATH ?? "").split(delimiter).filter(Boolean);
3884
+ return executableIn(name, (env.PATH ?? "").split(delimiter), env);
3885
+ }
3886
+ /**
3887
+ * Where a client's own command is usually installed, looked in after PATH: `~/.local/bin`, where Anthropic's native
3888
+ * installer puts `claude`, then `/opt/homebrew/bin` and `/usr/local/bin`, where Homebrew puts `claude` and `codex` on
3889
+ * Apple Silicon and on Intel.
3890
+ *
3891
+ * An install run from inside an MCP server has the PATH written into that server's entry at registration —
3892
+ * `node`'s own directory, `/usr/local/bin`, `/usr/bin`, `/bin` — and nothing of the person's shell. `claude` from
3893
+ * Homebrew on an Apple Silicon Mac, or from the native installer anywhere, is on none of those, so a registration
3894
+ * asked for from chat found no `claude`, registered nothing, and printed the entry instead. That PATH is left as it
3895
+ * is: it is in every entry already registered, and changing it would rewrite them all.
3896
+ *
3897
+ * The home is the environment's own `HOME`, never `os.homedir()`, so a test's temporary home is the only home looked
3898
+ * in. `AGENT_COMMS_CLIENT_CLI_DIRS` replaces the two system directories — a list, separated as PATH is, and empty for
3899
+ * none — which is how the tests keep every lookup inside their own directories: a `claude` or `codex` really
3900
+ * installed on the machine running them would otherwise be found, and run, by a test that meant to have none.
3901
+ *
3902
+ * Only absolute directories are looked in. A relative one would be read against whatever directory the server was
3903
+ * started from, so the command found — and run — would depend on where that was. And none on Windows: a client there
3904
+ * is a `.cmd` shim, which this cannot start without a shell, so a fallback could only find something it cannot run.
3905
+ */
3906
+ function clientCliDirectories(env) {
3907
+ if (process.platform === "win32") return [];
3908
+ const home = env.HOME;
3909
+ const system = env.AGENT_COMMS_CLIENT_CLI_DIRS !== void 0 ? env.AGENT_COMMS_CLIENT_CLI_DIRS.split(delimiter) : ["/opt/homebrew/bin", "/usr/local/bin"];
3910
+ return [...home ? [join(home, ".local", "bin")] : [], ...system].filter((directory) => directory !== "" && isAbsolute(directory));
3911
+ }
3912
+ /**
3913
+ * A client's own command — `claude`, `codex` — on PATH, or else where it is usually installed: see
3914
+ * `clientCliDirectories`. Every place that looks for a client's command looks through here, so the one that plans a
3915
+ * registration and the one that makes it cannot disagree about whether it is there.
3916
+ */
3917
+ async function findClientCli(name, env) {
3918
+ return await whichExecutable(name, env) ?? executableIn(name, clientCliDirectories(env), env);
3919
+ }
3920
+ /** Where `findClientCli` looked, as a sentence ends: "on PATH or in ~/.local/bin, /opt/homebrew/bin or /usr/local/bin". */
3921
+ function clientCliSearch(env) {
3922
+ const directories = clientCliDirectories(env);
3923
+ if (directories.length === 0) return "on PATH";
3924
+ const last = directories.at(-1);
3925
+ const rest = directories.slice(0, -1);
3926
+ return `on PATH or in ${rest.length > 0 ? `${rest.join(", ")} or ${last}` : last}`;
3927
+ }
3928
+ /**
3929
+ * The first of `directories` that holds an executable `name`. PATH is read by the caller, once: a test that counts
3930
+ * how often the installer looks at PATH counts exactly the looks it means.
3931
+ */
3932
+ async function executableIn(name, directories, env) {
3933
+ const paths = directories.filter(Boolean);
3885
3934
  const extensions = process.platform === "win32" ? (env.PATHEXT ?? ".EXE;.CMD;.BAT").split(";") : [""];
3886
3935
  for (const directory of paths) for (const extension of extensions) {
3887
3936
  const candidate = join(directory, name + extension.toLowerCase());
@@ -4342,8 +4391,9 @@ async function backUp(context, client, name, previous, now) {
4342
4391
  }
4343
4392
  /**
4344
4393
  * Where an install with these options goes: the client's own CLI and the file it keeps its servers in, and whether
4345
- * anything will be written there at all — `--print`, `--client json` and a client whose CLI is not on PATH all end
4346
- * with an entry printed rather than registered.
4394
+ * anything will be written there at all — `--print`, `--client json` and a client whose CLI cannot be found all end
4395
+ * with an entry printed rather than registered. The CLI is looked for on PATH and then where it is usually installed:
4396
+ * see `findClientCli`.
4347
4397
  *
4348
4398
  * Exported because a registration is a change a person approves, and what they are shown has to be what then
4349
4399
  * happens. The core server plans an install with this before asking, and the install itself decides with it, so the
@@ -4352,7 +4402,7 @@ async function backUp(context, client, name, previous, now) {
4352
4402
  async function installTarget(context, options) {
4353
4403
  const apply = options.apply ?? true;
4354
4404
  const cliName = options.client === "claude-code" ? "claude" : options.client === "codex" ? "codex" : null;
4355
- const binary = cliName ? await whichExecutable(cliName, context.env) : null;
4405
+ const binary = cliName ? await findClientCli(cliName, context.env) : null;
4356
4406
  const own = knownClientConfigs(context.env).find((file) => file.client === options.client)?.path;
4357
4407
  const configPath = options.client === "claude-code" ? void 0 : own;
4358
4408
  return {
@@ -4607,7 +4657,7 @@ async function mcpInstall(context, product, options, planned) {
4607
4657
  }
4608
4658
  method = "cli";
4609
4659
  applied = true;
4610
- } else if (cliName && apply) notApplied = `${cliName} was not found on PATH, so nothing was registered`;
4660
+ } else if (cliName && apply) notApplied = `${cliName} was not found ${clientCliSearch(context.env)}, so nothing was registered`;
4611
4661
  else if (configPath && writes) {
4612
4662
  await mergeIntoJsonConfig(configPath, options.client, name, entry);
4613
4663
  method = "file";
@@ -5474,7 +5524,7 @@ function wholeNumber(raw, rule) {
5474
5524
  return value;
5475
5525
  }
5476
5526
  /** The package version, read from package.json at build time. */
5477
- const VERSION = "0.7.1";
5527
+ const VERSION = "0.7.2";
5478
5528
  /**
5479
5529
  * Registering, pruning and listing the MCP servers of every channel, from the core.
5480
5530
  *
@@ -5729,7 +5779,7 @@ function serverPruneChange(core, env, request, own) {
5729
5779
  };
5730
5780
  const { packageName, version } = ownProduct(request.channel, own) ?? {
5731
5781
  packageName: channelServer(request.channel).packageName,
5732
- version: "0.7.1"
5782
+ version: "0.7.2"
5733
5783
  };
5734
5784
  const product = {
5735
5785
  packageName,
@@ -5768,7 +5818,7 @@ function serverPruneChange(core, env, request, own) {
5768
5818
  };
5769
5819
  }
5770
5820
  //#endregion
5771
- //#region ../core/dist/tool-arguments-CXQsEUqg.mjs
5821
+ //#region ../core/dist/tool-arguments-DBqML6N8.mjs
5772
5822
  const APPLIED = Symbol.for("agentcomms.strictToolArguments");
5773
5823
  const TARGET = "draft-2020-12";
5774
5824
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentcomms/whatsapp",
3
- "version": "0.7.1",
3
+ "version": "0.7.2",
4
4
  "description": "WhatsApp for coding agents, read-only: list, read and search the chats WhatsApp for Mac keeps on this Mac, and draft replies as links the person sends. No network client; it never sends.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -38,7 +38,7 @@
38
38
  "@modelcontextprotocol/server": "^2.0.0",
39
39
  "commander": "^15.0.0",
40
40
  "zod": "^4.6.5",
41
- "@agentcomms/core": "0.7.1"
41
+ "@agentcomms/core": "0.7.2"
42
42
  },
43
43
  "agentcomms": {
44
44
  "contract": 1,
@@ -87,5 +87,5 @@
87
87
  "typecheck": "tsc -p tsconfig.json",
88
88
  "test": "node --experimental-strip-types --disable-warning=ExperimentalWarning --test --test-timeout=600000 \"test/**/*.test.ts\""
89
89
  },
90
- "gitHead": "4c6701c2ee05843704d3619c22a8262248e4e1aa"
90
+ "gitHead": "b0e3060e9ce327f2fd9b040c69bde81721c37e3e"
91
91
  }