cc-peer 1.3.5 → 1.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/README.md +26 -0
- package/dist/adapters/node/alias-worker.cjs +42 -0
- package/dist/adapters/node/alias-worker.d.cts +1 -0
- package/dist/adapters/node/alias-worker.d.mts +1 -0
- package/dist/adapters/node/alias-worker.mjs +41 -0
- package/dist/alias-ipc-Cjs5yivH.cjs +48 -0
- package/dist/alias-ipc-DkaozCo7.mjs +31 -0
- package/dist/alias-pool.cjs +162 -0
- package/dist/alias-pool.d.cts +51 -0
- package/dist/alias-pool.d.mts +51 -0
- package/dist/alias-pool.mjs +160 -0
- package/dist/bin/cc-peer.cjs +10 -30
- package/dist/bin/cc-peer.mjs +2 -1
- package/dist/{cc-peer-CJqStHIL.mjs → cc-peer-CbnScbXe.mjs} +2 -46
- package/dist/cc-peer-DFoi9JJV.d.cts +310 -0
- package/dist/cc-peer-DFoi9JJV.d.mts +310 -0
- package/dist/{cc-peer-CXzxAUE4.cjs → cc-peer-D_3Bw_NE.cjs} +28 -78
- package/dist/cc-peer.cjs +1 -1
- package/dist/cc-peer.d.cts +2 -309
- package/dist/cc-peer.d.mts +2 -309
- package/dist/cc-peer.mjs +1 -1
- package/dist/errors-Dcqq2MIW.mjs +53 -0
- package/dist/errors-Dl_lSq1N.cjs +88 -0
- package/dist/rolldown-runtime-VH7oDXx4.cjs +28 -0
- package/docs/PROTOCOL.md +9 -0
- package/package.json +12 -2
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
//#region src/schemas/define-schema.ts
|
|
2
|
+
/**
|
|
3
|
+
* Attach an `.is()` type guard to a Zod schema so schema, inferred type, and runtime guard derive from one definition (single source of truth). `Schema.parse()` at JSON boundaries; `Schema.is()` for narrowing.
|
|
4
|
+
*/
|
|
5
|
+
function defineSchema(schema) {
|
|
6
|
+
return Object.assign(schema, { is(value) {
|
|
7
|
+
return schema.safeParse(value).success;
|
|
8
|
+
} });
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/errors.ts
|
|
12
|
+
/** Base error for every cc-peer failure; `code` is machine-readable. */
|
|
13
|
+
var CcPeerError = class extends Error {
|
|
14
|
+
code;
|
|
15
|
+
constructor(code, message) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.code = code;
|
|
18
|
+
this.name = "CcPeerError";
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
var NoLiveInboxError = class extends CcPeerError {
|
|
22
|
+
constructor(message) {
|
|
23
|
+
super("NO_LIVE_INBOX", message);
|
|
24
|
+
this.name = "NoLiveInboxError";
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
var UnknownPeerError = class extends CcPeerError {
|
|
28
|
+
constructor(message) {
|
|
29
|
+
super("UNKNOWN_PEER", message);
|
|
30
|
+
this.name = "UnknownPeerError";
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
var MessageTooLargeError = class extends CcPeerError {
|
|
34
|
+
constructor(message) {
|
|
35
|
+
super("MESSAGE_TOO_LARGE", message);
|
|
36
|
+
this.name = "MessageTooLargeError";
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
var NotStartedError = class extends CcPeerError {
|
|
40
|
+
constructor(message) {
|
|
41
|
+
super("NOT_STARTED", message);
|
|
42
|
+
this.name = "NotStartedError";
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
/** A reply-alias worker process exited (or failed to reach the "started" acknowledgement) before it finished registering as a discoverable peer. */
|
|
46
|
+
var AliasStartError = class extends CcPeerError {
|
|
47
|
+
constructor(message) {
|
|
48
|
+
super("ALIAS_START_FAILED", message);
|
|
49
|
+
this.name = "AliasStartError";
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
//#endregion
|
|
53
|
+
Object.defineProperty(exports, "AliasStartError", {
|
|
54
|
+
enumerable: true,
|
|
55
|
+
get: function() {
|
|
56
|
+
return AliasStartError;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
Object.defineProperty(exports, "MessageTooLargeError", {
|
|
60
|
+
enumerable: true,
|
|
61
|
+
get: function() {
|
|
62
|
+
return MessageTooLargeError;
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
Object.defineProperty(exports, "NoLiveInboxError", {
|
|
66
|
+
enumerable: true,
|
|
67
|
+
get: function() {
|
|
68
|
+
return NoLiveInboxError;
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
Object.defineProperty(exports, "NotStartedError", {
|
|
72
|
+
enumerable: true,
|
|
73
|
+
get: function() {
|
|
74
|
+
return NotStartedError;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
Object.defineProperty(exports, "UnknownPeerError", {
|
|
78
|
+
enumerable: true,
|
|
79
|
+
get: function() {
|
|
80
|
+
return UnknownPeerError;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
Object.defineProperty(exports, "defineSchema", {
|
|
84
|
+
enumerable: true,
|
|
85
|
+
get: function() {
|
|
86
|
+
return defineSchema;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
+
key = keys[i];
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
+
get: ((k) => from[k]).bind(null, key),
|
|
13
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
19
|
+
value: mod,
|
|
20
|
+
enumerable: true
|
|
21
|
+
}) : target, mod));
|
|
22
|
+
//#endregion
|
|
23
|
+
Object.defineProperty(exports, "__toESM", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
get: function() {
|
|
26
|
+
return __toESM;
|
|
27
|
+
}
|
|
28
|
+
});
|
package/docs/PROTOCOL.md
CHANGED
|
@@ -76,6 +76,15 @@ The roster builder (`listLivePeerSessions`) reads all `~/.claude/sessions/<pid>.
|
|
|
76
76
|
|
|
77
77
|
Verified chain: a Python peer registered this way appears in `ListAgents` within seconds and receives native `SendMessage` by bare name (`from-name` resolves from the sender's own registry entry).
|
|
78
78
|
|
|
79
|
+
### Session enumeration and reply aliases (for a relay/front building on this SDK)
|
|
80
|
+
|
|
81
|
+
Two capabilities a message relay ("front") needs from this protocol, gated on what it actually supports rather than assumed:
|
|
82
|
+
|
|
83
|
+
- **Session enumeration** — listing every live local Claude Code session, not just ones the relay itself registered — is already fully native. The roster builder above reads every `~/.claude/sessions/<pid>.json` file on disk, regardless of who wrote it; `cc-peer`'s own `CcPeer.roster()` (and the REST facade's `GET /sessions`) is exactly this roster builder, so a relay gets full session discovery for free, with no separate mechanism needed.
|
|
84
|
+
- **Reply aliases** — giving each correspondent that messages a relayed session its own natively-`SendMessage`-reachable name, so the session can reply to it directly by name — is **not** natively supported for more than one name per process. The registry is one file per real OS pid (`registryFilePath`: `<pid>.json`) and each entry carries a single optional `name` field; a process publishing a second name overwrites, rather than adds to, its own entry. This is directly observable in this SDK's own test suite: two `CcPeer` instances sharing one pid (unavoidable — both are the same OS process) leave only the last-registered name visible in the roster, because both wrote to the identical `<pid>.json` file. Native name resolution (`ListAgents`/`SendMessage(name=X)`) walks the registry directory exactly as it is on disk — it has no concept of "this one process answers to several names."
|
|
85
|
+
|
|
86
|
+
The practical consequence: a relay that wants N correspondents to each get their own reply-able name needs N distinct, genuinely live OS processes — one real pid, one registry file, one name, per correspondent — not a lighter-weight in-process mapping. `cc-peer`'s own `AliasPool` (see the root README) implements exactly this: it lazily forks one lightweight child process per correspondent name, each running an ordinary `CcPeer` instance under that name, and relays whatever the relayed session replies with back to the parent process for translation into whatever channel the correspondent actually lives on.
|
|
87
|
+
|
|
79
88
|
## Receipts and status
|
|
80
89
|
|
|
81
90
|
`peer_message_status` is pushed from receiver to sender over a fresh connection to the sender's socket, authenticated with the sender's own peerToken:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cc-peer",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
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",
|
|
@@ -32,6 +32,16 @@
|
|
|
32
32
|
"default": "./dist/cc-peer.cjs"
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
|
+
"./alias-pool": {
|
|
36
|
+
"import": {
|
|
37
|
+
"types": "./dist/alias-pool.d.mts",
|
|
38
|
+
"default": "./dist/alias-pool.mjs"
|
|
39
|
+
},
|
|
40
|
+
"require": {
|
|
41
|
+
"types": "./dist/alias-pool.d.cts",
|
|
42
|
+
"default": "./dist/alias-pool.cjs"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
35
45
|
"./schemas/*.schema.json": "./schemas/*.schema.json",
|
|
36
46
|
"./package.json": "./package.json"
|
|
37
47
|
},
|
|
@@ -59,7 +69,7 @@
|
|
|
59
69
|
"test:integration": "vitest run --project integration",
|
|
60
70
|
"test:e2e": "vitest run --config vitest.e2e.config.ts",
|
|
61
71
|
"test:mutation": "stryker run stryker.config.ts",
|
|
62
|
-
"prepublishOnly": "pnpm lint && pnpm typecheck && pnpm test:coverage && pnpm build && publint && attw --pack",
|
|
72
|
+
"prepublishOnly": "pnpm lint && pnpm typecheck && pnpm test:coverage && pnpm build && publint && attw --pack --profile node16",
|
|
63
73
|
"prepare": "husky",
|
|
64
74
|
"test:coverage": "vitest run --coverage"
|
|
65
75
|
},
|