cc-peer 1.6.2 → 1.6.4

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # cc-peer
2
2
 
3
- [![GitHub](https://img.shields.io/badge/GitHub-181717?logo=github&logoColor=white)](https://github.com/ExaDev/cc-peer) [![npm](https://img.shields.io/npm/v/cc-peer)](https://www.npmjs.com/package/cc-peer) [![CI](https://img.shields.io/github/actions/workflow/status/ExaDev/cc-peer/ci.yml?branch=main)](https://github.com/ExaDev/cc-peer/actions)
3
+ [![GitHub](https://img.shields.io/badge/GitHub-181717?logo=github&logoColor=white)](https://github.com/ExaDev/cc-peer) [![npm](https://img.shields.io/badge/npm-CB3837?logo=npm&logoColor=white)](https://www.npmjs.com/package/cc-peer) [![Release](https://img.shields.io/github/v/release/ExaDev/cc-peer)](https://github.com/ExaDev/cc-peer/releases/latest) [![CI](https://img.shields.io/github/actions/workflow/status/ExaDev/cc-peer/ci.yml?branch=main)](https://github.com/ExaDev/cc-peer/actions)
4
4
 
5
5
  Talk to the Claude Code instances running on your machine, from any Node application: send messages, register as a named peer other sessions can discover and message, receive replies and delivery receipts, and subscribe to idle notifications. Ships a REST facade you can run with `npx cc-peer`.
6
6
 
@@ -57,6 +57,8 @@ await peer.stop();
57
57
 
58
58
  Every release is also mirrored to the GitHub Packages registry as `@exadev/cc-peer` (GitHub Packages requires owner-scoped names), and single-executable binaries ship as release assets for every platform/architecture pair Node's own SEA feature supports (see Limitations for the one exception).
59
59
 
60
+ `npx cc-peer --help` prints the options: `--port` and `--token` choose the listening port and bearer token, `--no-token` disables authentication, `--name` sets the peer name, and `--home` overrides the home directory holding `.claude`. An unknown option exits non-zero without starting anything.
61
+
60
62
  The REST facade (`npx cc-peer`) serves `GET /sessions`, `POST /messages`, `POST /idle-subscriptions`, `GET /events` (SSE), and a self-describing `GET /openapi.json` on loopback with a bearer token.
61
63
 
62
64
  ### Session discovery and reply aliases
@@ -1,5 +1,5 @@
1
1
  const require_rolldown_runtime = require("../../rolldown-runtime-VH7oDXx4.cjs");
2
- const require_cc_peer = require("../../cc-peer-DNB8oHNm.cjs");
2
+ const require_cc_peer = require("../../cc-peer-CUt7BwyE.cjs");
3
3
  const require_errors = require("../../errors-BAbklcGw.cjs");
4
4
  const require_alias_ipc = require("../../alias-ipc-BPc2wfmz.cjs");
5
5
  let node_process = require("node:process");
@@ -1,4 +1,4 @@
1
- import { n as CcPeer } from "../../cc-peer-zz8MzHY8.mjs";
1
+ import { n as CcPeer } from "../../cc-peer-8l2Nyivq.mjs";
2
2
  import { r as CcPeerError } from "../../errors-KYBco8pU.mjs";
3
3
  import { t as AliasCommandSchema } from "../../alias-ipc-BSh7Q4LL.mjs";
4
4
  import process from "node:process";
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  const require_rolldown_runtime = require("../rolldown-runtime-VH7oDXx4.cjs");
3
- const require_cc_peer = require("../cc-peer-DNB8oHNm.cjs");
3
+ const require_cc_peer = require("../cc-peer-CUt7BwyE.cjs");
4
4
  const require_errors = require("../errors-BAbklcGw.cjs");
5
5
  let node_crypto = require("node:crypto");
6
6
  let zod = require("zod");
@@ -340,29 +340,82 @@ function openApiDocument() {
340
340
  }
341
341
  //#endregion
342
342
  //#region src/bin/main.ts
343
+ const USAGE = `Usage: cc-peer [options]
344
+
345
+ Starts the cc-peer REST facade on loopback and registers a peer for this process.
346
+
347
+ Options:
348
+ --port <number> Port to listen on (default: an ephemeral port)
349
+ --token <string> Bearer token to require (default: a generated token)
350
+ --no-token Disable bearer-token authentication
351
+ --name <string> Peer name shown to Claude Code sessions
352
+ --home <path> Home directory containing .claude (default: the current user's)
353
+ -h, --help Print this help and exit
354
+ `;
355
+ const MAX_PORT = 65535;
356
+ const VALUE_FLAGS = /* @__PURE__ */ new Set([
357
+ "--port",
358
+ "--token",
359
+ "--name",
360
+ "--home"
361
+ ]);
362
+ /**
363
+ * Parses command-line arguments (without the node and script entries) without any side effects.
364
+ * `-h` and `--help` win over everything else; an unknown argument, a value flag with no value, or a
365
+ * `--port` that is not an integer from 0 to 65535 yields an error command.
366
+ */
343
367
  function parseArgs(argv) {
368
+ if (argv.includes("--help") || argv.includes("-h")) return { kind: "help" };
344
369
  const args = { noToken: false };
345
370
  for (let i = 0; i < argv.length; i += 1) {
346
371
  const arg = argv[i];
347
- const next = argv[i + 1];
348
- if (arg === "--port" && next !== void 0) {
349
- args.port = Number.parseInt(next, 10);
350
- i += 1;
351
- } else if (arg === "--token" && next !== void 0) {
352
- args.token = next;
353
- i += 1;
354
- } else if (arg === "--name" && next !== void 0) {
355
- args.name = next;
356
- i += 1;
357
- } else if (arg === "--home" && next !== void 0) {
358
- args.home = next;
359
- i += 1;
360
- } else if (arg === "--no-token") args.noToken = true;
372
+ if (arg === void 0) continue;
373
+ if (arg === "--no-token") {
374
+ args.noToken = true;
375
+ continue;
376
+ }
377
+ if (!VALUE_FLAGS.has(arg)) return {
378
+ kind: "error",
379
+ message: `unknown argument: ${arg}`
380
+ };
381
+ const value = argv[i + 1];
382
+ if (value === void 0) return {
383
+ kind: "error",
384
+ message: `${arg} requires a value`
385
+ };
386
+ i += 1;
387
+ if (arg === "--port") {
388
+ const port = Number(value);
389
+ if (!/^\d+$/.test(value) || port > MAX_PORT) return {
390
+ kind: "error",
391
+ message: `invalid --port: ${value}`
392
+ };
393
+ args.port = port;
394
+ } else if (arg === "--token") args.token = value;
395
+ else if (arg === "--name") args.name = value;
396
+ else args.home = value;
361
397
  }
362
- return args;
398
+ return {
399
+ kind: "run",
400
+ args
401
+ };
363
402
  }
364
- async function main() {
365
- const args = parseArgs(node_process.default.argv.slice(2));
403
+ /**
404
+ * Runs the CLI. Arguments are parsed before any peer is created or socket bound, so `--help` and
405
+ * argument errors have no side effects beyond output; an argument error sets a non-zero exit code.
406
+ */
407
+ async function main(argv = node_process.default.argv.slice(2)) {
408
+ const command = parseArgs(argv);
409
+ if (command.kind === "help") {
410
+ node_process.default.stdout.write(USAGE);
411
+ return;
412
+ }
413
+ if (command.kind === "error") {
414
+ node_process.default.stderr.write(`[cc-peer] ${command.message}\nRun 'cc-peer --help' for usage.\n`);
415
+ node_process.default.exitCode = 2;
416
+ return;
417
+ }
418
+ const { args } = command;
366
419
  const peer = await require_cc_peer.CcPeer.create({
367
420
  ...args.name !== void 0 ? { name: args.name } : {},
368
421
  ...args.home !== void 0 ? { homeDir: args.home } : {},
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { i as RegistryEntrySchema, n as CcPeer, r as PrioritySchema } from "../cc-peer-zz8MzHY8.mjs";
2
+ import { i as RegistryEntrySchema, n as CcPeer, r as PrioritySchema } from "../cc-peer-8l2Nyivq.mjs";
3
3
  import { l as defineSchema } from "../errors-KYBco8pU.mjs";
4
4
  import { randomBytes } from "node:crypto";
5
5
  import { z } from "zod";
@@ -338,29 +338,82 @@ function openApiDocument() {
338
338
  }
339
339
  //#endregion
340
340
  //#region src/bin/main.ts
341
+ const USAGE = `Usage: cc-peer [options]
342
+
343
+ Starts the cc-peer REST facade on loopback and registers a peer for this process.
344
+
345
+ Options:
346
+ --port <number> Port to listen on (default: an ephemeral port)
347
+ --token <string> Bearer token to require (default: a generated token)
348
+ --no-token Disable bearer-token authentication
349
+ --name <string> Peer name shown to Claude Code sessions
350
+ --home <path> Home directory containing .claude (default: the current user's)
351
+ -h, --help Print this help and exit
352
+ `;
353
+ const MAX_PORT = 65535;
354
+ const VALUE_FLAGS = /* @__PURE__ */ new Set([
355
+ "--port",
356
+ "--token",
357
+ "--name",
358
+ "--home"
359
+ ]);
360
+ /**
361
+ * Parses command-line arguments (without the node and script entries) without any side effects.
362
+ * `-h` and `--help` win over everything else; an unknown argument, a value flag with no value, or a
363
+ * `--port` that is not an integer from 0 to 65535 yields an error command.
364
+ */
341
365
  function parseArgs(argv) {
366
+ if (argv.includes("--help") || argv.includes("-h")) return { kind: "help" };
342
367
  const args = { noToken: false };
343
368
  for (let i = 0; i < argv.length; i += 1) {
344
369
  const arg = argv[i];
345
- const next = argv[i + 1];
346
- if (arg === "--port" && next !== void 0) {
347
- args.port = Number.parseInt(next, 10);
348
- i += 1;
349
- } else if (arg === "--token" && next !== void 0) {
350
- args.token = next;
351
- i += 1;
352
- } else if (arg === "--name" && next !== void 0) {
353
- args.name = next;
354
- i += 1;
355
- } else if (arg === "--home" && next !== void 0) {
356
- args.home = next;
357
- i += 1;
358
- } else if (arg === "--no-token") args.noToken = true;
370
+ if (arg === void 0) continue;
371
+ if (arg === "--no-token") {
372
+ args.noToken = true;
373
+ continue;
374
+ }
375
+ if (!VALUE_FLAGS.has(arg)) return {
376
+ kind: "error",
377
+ message: `unknown argument: ${arg}`
378
+ };
379
+ const value = argv[i + 1];
380
+ if (value === void 0) return {
381
+ kind: "error",
382
+ message: `${arg} requires a value`
383
+ };
384
+ i += 1;
385
+ if (arg === "--port") {
386
+ const port = Number(value);
387
+ if (!/^\d+$/.test(value) || port > MAX_PORT) return {
388
+ kind: "error",
389
+ message: `invalid --port: ${value}`
390
+ };
391
+ args.port = port;
392
+ } else if (arg === "--token") args.token = value;
393
+ else if (arg === "--name") args.name = value;
394
+ else args.home = value;
359
395
  }
360
- return args;
396
+ return {
397
+ kind: "run",
398
+ args
399
+ };
361
400
  }
362
- async function main() {
363
- const args = parseArgs(process.argv.slice(2));
401
+ /**
402
+ * Runs the CLI. Arguments are parsed before any peer is created or socket bound, so `--help` and
403
+ * argument errors have no side effects beyond output; an argument error sets a non-zero exit code.
404
+ */
405
+ async function main(argv = process.argv.slice(2)) {
406
+ const command = parseArgs(argv);
407
+ if (command.kind === "help") {
408
+ process.stdout.write(USAGE);
409
+ return;
410
+ }
411
+ if (command.kind === "error") {
412
+ process.stderr.write(`[cc-peer] ${command.message}\nRun 'cc-peer --help' for usage.\n`);
413
+ process.exitCode = 2;
414
+ return;
415
+ }
416
+ const { args } = command;
364
417
  const peer = await CcPeer.create({
365
418
  ...args.name !== void 0 ? { name: args.name } : {},
366
419
  ...args.home !== void 0 ? { homeDir: args.home } : {},
@@ -8,7 +8,7 @@ import { z } from "zod";
8
8
  import { homedir } from "node:os";
9
9
  import { spawn } from "node:child_process";
10
10
  //#region package.json
11
- var version = "1.6.2";
11
+ var version = "1.6.4";
12
12
  //#endregion
13
13
  //#region src/adapters/node/uds-transport.ts
14
14
  /** macOS linger before close, matching the reference client's ~150ms. */
@@ -8,7 +8,7 @@ let zod = require("zod");
8
8
  let node_os = require("node:os");
9
9
  let node_child_process = require("node:child_process");
10
10
  //#region package.json
11
- var version = "1.6.2";
11
+ var version = "1.6.4";
12
12
  //#endregion
13
13
  //#region src/adapters/node/uds-transport.ts
14
14
  /** macOS linger before close, matching the reference client's ~150ms. */
package/dist/cc-peer.cjs CHANGED
@@ -1,4 +1,4 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_cc_peer = require("./cc-peer-DNB8oHNm.cjs");
2
+ const require_cc_peer = require("./cc-peer-CUt7BwyE.cjs");
3
3
  exports.CC_PEER_VERSION = require_cc_peer.CC_PEER_VERSION;
4
4
  exports.CcPeer = require_cc_peer.CcPeer;
package/dist/cc-peer.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { n as CcPeer, t as CC_PEER_VERSION } from "./cc-peer-zz8MzHY8.mjs";
1
+ import { n as CcPeer, t as CC_PEER_VERSION } from "./cc-peer-8l2Nyivq.mjs";
2
2
  export { CC_PEER_VERSION, CcPeer };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-peer",
3
- "version": "1.6.2",
3
+ "version": "1.6.4",
4
4
  "description": "Communicate with local Claude Code instances over their native cross-session peer messaging: send and receive messages, register as a named discoverable peer, receipts, idle subscriptions, and a REST facade via `npx cc-peer`.",
5
5
  "type": "module",
6
6
  "license": "MIT",