@cotal-ai/connector-claude-code 0.8.3 → 0.9.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/dist/extension.d.ts.map +1 -1
- package/dist/extension.js +8 -0
- package/dist/extension.js.map +1 -1
- package/dist/mcp.cjs +53 -22
- package/package.json +3 -3
package/dist/extension.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"AAIA,OAAO,EAA2D,KAAK,SAAS,EAAoC,MAAM,gBAAgB,CAAC;AAoB3I;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"AAIA,OAAO,EAA2D,KAAK,SAAS,EAAoC,MAAM,gBAAgB,CAAC;AAoB3I;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,SAmH7B,CAAC"}
|
package/dist/extension.js
CHANGED
|
@@ -31,6 +31,7 @@ export const claudeConnector = {
|
|
|
31
31
|
transcriptChannel, // the shared `tr-<name>` convention (connector-core), exposed via the contract
|
|
32
32
|
pluginRoot: PLUGIN_ROOT,
|
|
33
33
|
requires: ["claude"],
|
|
34
|
+
supportsResume: true, // renders `--resume <id> --fork-session` (fork-from, never hijack) — see buildLaunch
|
|
34
35
|
buildLaunch(opts) {
|
|
35
36
|
// Operator MCP servers shared with this agent (default none — see the --mcp-config block).
|
|
36
37
|
const shared = opts.mcpServers ?? {};
|
|
@@ -124,6 +125,13 @@ export const claudeConnector = {
|
|
|
124
125
|
// The `--model` flag wins over the agent file, and applies even with no agent file.
|
|
125
126
|
if (model)
|
|
126
127
|
args.push("--model", model);
|
|
128
|
+
// Fork an existing session INTO the mesh (opts.resume, an opaque host-local id). `--fork-session`
|
|
129
|
+
// is pushed in the SAME branch — resume here is fork-only, never a hijack: claude mints a NEW
|
|
130
|
+
// session id from that transcript and leaves the original untouched. The id is a single argv
|
|
131
|
+
// token (no shell), so a hostile-looking id can't inject. The persona `--append-system-prompt`
|
|
132
|
+
// above still applies, so the forked context runs under the current mesh persona.
|
|
133
|
+
if (opts.resume)
|
|
134
|
+
args.push("--resume", opts.resume, "--fork-session");
|
|
127
135
|
return {
|
|
128
136
|
command: "claude",
|
|
129
137
|
args,
|
package/dist/extension.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp.cjs
CHANGED
|
@@ -47983,6 +47983,7 @@ var CotalEndpoint = class extends import_node_events.EventEmitter {
|
|
|
47983
47983
|
ttlMs;
|
|
47984
47984
|
doRegister;
|
|
47985
47985
|
doWatch;
|
|
47986
|
+
doWatchChannels;
|
|
47986
47987
|
doConsume;
|
|
47987
47988
|
ackWaitMs;
|
|
47988
47989
|
inactiveThresholdMs;
|
|
@@ -48098,6 +48099,7 @@ var CotalEndpoint = class extends import_node_events.EventEmitter {
|
|
|
48098
48099
|
this.ttlMs = opts.ttlMs ?? 6e3;
|
|
48099
48100
|
this.doRegister = opts.registerPresence ?? true;
|
|
48100
48101
|
this.doWatch = opts.watchPresence ?? true;
|
|
48102
|
+
this.doWatchChannels = opts.watchChannels ?? true;
|
|
48101
48103
|
this.doConsume = opts.consume ?? true;
|
|
48102
48104
|
this.channelModes = opts.channelModes && Object.keys(opts.channelModes).length ? opts.channelModes : void 0;
|
|
48103
48105
|
this.ackWaitMs = opts.ackWaitMs ?? 6e4;
|
|
@@ -48137,9 +48139,10 @@ var CotalEndpoint = class extends import_node_events.EventEmitter {
|
|
|
48137
48139
|
await this.startPresenceWatch();
|
|
48138
48140
|
this.sweepTimer = setInterval(() => this.sweep(), Math.max(500, Math.floor(this.ttlMs / 3)));
|
|
48139
48141
|
}
|
|
48140
|
-
|
|
48142
|
+
const watchChannels = this.doWatch && this.doWatchChannels;
|
|
48143
|
+
if (watchChannels || this.doConsume) {
|
|
48141
48144
|
this.channelKv = await openChannelRegistry(this.nc, this.space, { create: !this.creds });
|
|
48142
|
-
if (
|
|
48145
|
+
if (watchChannels)
|
|
48143
48146
|
await this.startChannelWatch();
|
|
48144
48147
|
}
|
|
48145
48148
|
if (this.doRegister) {
|
|
@@ -48430,8 +48433,10 @@ var CotalEndpoint = class extends import_node_events.EventEmitter {
|
|
|
48430
48433
|
* PEER's reply lane (`ctl.delivery.<victim>.reply.<n>`) and turn the responder into a confused
|
|
48431
48434
|
* deputy — the broker does NOT permission-check the requester's embedded reply subject. With it, a
|
|
48432
48435
|
* reply is published only when `m.reply` is under the AUTHENTICATED request subject
|
|
48433
|
-
* (`${m.subject}.reply.…`), binding the reply to the broker-policed sender token.
|
|
48434
|
-
* tiers
|
|
48436
|
+
* (`${m.subject}.reply.…`), binding the reply to the broker-policed sender token. The manager's three
|
|
48437
|
+
* lifecycle tiers ALSO require it as of closure (i): they reply on bounded `ctl.<tier>.<caller>.reply.…`
|
|
48438
|
+
* (the manager cred holds the wildcard `ctl.<tier>.*.reply.>` pub — exactly the confused-deputy
|
|
48439
|
+
* condition above), so do NOT drop `boundReply` on them. */
|
|
48435
48440
|
serveControl(service, handler, opts = {}) {
|
|
48436
48441
|
if (!this.nc)
|
|
48437
48442
|
throw new Error("endpoint not started");
|
|
@@ -48466,12 +48471,25 @@ var CotalEndpoint = class extends import_node_events.EventEmitter {
|
|
|
48466
48471
|
})().catch((e) => this.emit("error", e));
|
|
48467
48472
|
return sub;
|
|
48468
48473
|
}
|
|
48469
|
-
/** Send a control request to a service and await its reply (client side).
|
|
48474
|
+
/** Send a control request to a service and await its reply (client side). Like {@link requestDelivery},
|
|
48475
|
+
* the reply rides a BOUNDED subject UNDER the request subject (`ctl.<service>.<id>.reply.<uuid>`), not
|
|
48476
|
+
* the per-id `_INBOX` — closure (i): this frees the manager's permission set from needing a position-1
|
|
48477
|
+
* inbox wildcard, so its publish surface can be an exact self-scoped allow-list (no message forging).
|
|
48478
|
+
* `noMux` lets us name the reply subject while keeping NoResponders detection. The random suffix is
|
|
48479
|
+
* defense-in-depth (a predictable suffix would let a peer target an in-flight named reply sub). The
|
|
48480
|
+
* reply sits under the sender's OWN request subject, so the responder's `boundReply` guard accepts it.
|
|
48481
|
+
*
|
|
48482
|
+
* CUTOVER (not backward-compatible): an agent cred minted BEFORE closure (i) lacks the
|
|
48483
|
+
* `ctl.<tier>.<id>.reply.>` sub grant — it can still publish the request but cannot subscribe the
|
|
48484
|
+
* reply, so its control calls (spawn/despawn/purge/definePersona, self-stop) hang. The per-user-auth
|
|
48485
|
+
* atomic cutover re-mints every agent; if this change ships ahead of that, agents must be RESPAWNED. */
|
|
48470
48486
|
async requestControl(service, req, timeoutMs = 5e3) {
|
|
48471
48487
|
if (!this.nc)
|
|
48472
48488
|
throw new Error(this.notLiveMsg());
|
|
48489
|
+
const reqSubject = controlServiceSubject(this.space, service, this.card.id);
|
|
48490
|
+
const reply = `${reqSubject}.reply.${(0, import_node_crypto.randomUUID)()}`;
|
|
48473
48491
|
const body = { ...req, from: req.from ?? this.ref() };
|
|
48474
|
-
const m = await this.nc.request(
|
|
48492
|
+
const m = await this.nc.request(reqSubject, JSON.stringify(body), { timeout: timeoutMs, noMux: true, reply });
|
|
48475
48493
|
return m.json();
|
|
48476
48494
|
}
|
|
48477
48495
|
/** Send a durable-membership request to the SERVER-SIDE delivery daemon (`ctl.delivery`) and await its
|
|
@@ -48926,23 +48944,29 @@ var CotalEndpoint = class extends import_node_events.EventEmitter {
|
|
|
48926
48944
|
return void 0;
|
|
48927
48945
|
}
|
|
48928
48946
|
}
|
|
48929
|
-
/** Ensure + bind the manager singleton-lease bucket.
|
|
48930
|
-
*
|
|
48931
|
-
*
|
|
48932
|
-
*
|
|
48933
|
-
*
|
|
48934
|
-
*
|
|
48935
|
-
*
|
|
48947
|
+
/** Ensure + bind the manager singleton-lease bucket. Mirrors the presence-bucket pattern (connectAndBind):
|
|
48948
|
+
* AUTH mode OPENs the bucket pre-created at `cotal up` (the scoped `supervisor` cred holds no
|
|
48949
|
+
* STREAM.CREATE — and `open` binds direct=false, so the CAS-conflict `kv.get` inside `acquire` rides
|
|
48950
|
+
* STREAM.MSG.GET, the verb the supervisor grants, never DIRECT.GET). OPEN mode (no creds) create-firsts:
|
|
48951
|
+
* `Kvm.open` binds LAZILY — it does NOT verify the stream exists or throw when it's missing (a fresh
|
|
48952
|
+
* bucket then fails 'stream not found' on the first write), so `create` is the ensure-exists call (it
|
|
48953
|
+
* makes the bucket or, when another endpoint already did, throws and we bind the existing one). Either
|
|
48954
|
+
* way the per-KEY CAS create stays the only single-flight gate, so a lost bucket-create race never reads
|
|
48955
|
+
* as "lease held". */
|
|
48936
48956
|
async managerLeaseRegistry() {
|
|
48937
48957
|
if (!this.nc)
|
|
48938
48958
|
throw new Error("endpoint not started");
|
|
48939
48959
|
if (this.managerLeaseKv)
|
|
48940
48960
|
return this.managerLeaseKv;
|
|
48941
48961
|
const kvm = new import_kv7.Kvm(this.nc);
|
|
48942
|
-
|
|
48943
|
-
this.managerLeaseKv = await kvm.create(managerBucket(this.space), { ttl: MANAGER_LEASE_TTL_MS });
|
|
48944
|
-
} catch {
|
|
48962
|
+
if (this.creds) {
|
|
48945
48963
|
this.managerLeaseKv = await kvm.open(managerBucket(this.space));
|
|
48964
|
+
} else {
|
|
48965
|
+
try {
|
|
48966
|
+
this.managerLeaseKv = await kvm.create(managerBucket(this.space), { ttl: MANAGER_LEASE_TTL_MS });
|
|
48967
|
+
} catch {
|
|
48968
|
+
this.managerLeaseKv = await kvm.open(managerBucket(this.space));
|
|
48969
|
+
}
|
|
48946
48970
|
}
|
|
48947
48971
|
return this.managerLeaseKv;
|
|
48948
48972
|
}
|
|
@@ -50069,6 +50093,8 @@ var CotalEndpoint = class extends import_node_events.EventEmitter {
|
|
|
50069
50093
|
this.applyPresence(e.key, p);
|
|
50070
50094
|
}
|
|
50071
50095
|
applyPresence(id, raw) {
|
|
50096
|
+
if (raw.card?.id !== id)
|
|
50097
|
+
return;
|
|
50072
50098
|
const prev = this.roster.get(id);
|
|
50073
50099
|
const stale = Date.now() - raw.ts > this.ttlMs;
|
|
50074
50100
|
const p = stale || raw.status === "offline" ? this.toOffline(raw) : raw;
|
|
@@ -50634,7 +50660,9 @@ var MeshAgent = class extends import_node_events2.EventEmitter {
|
|
|
50634
50660
|
* the harness (default the manager's `cotal`/Claude), `opts.model` overrides the
|
|
50635
50661
|
* persona file's `model:`, and `opts.cwd` roots the new peer at a different folder/repo
|
|
50636
50662
|
* than the manager's workspace — the same knobs the operator's `cotal start` carries, so
|
|
50637
|
-
* the agent and operator spawn doors share one control-op contract.
|
|
50663
|
+
* the agent and operator spawn doors share one control-op contract. (Session `resume` is
|
|
50664
|
+
* intentionally NOT forwarded here: forking a host-local `~/.claude` transcript is an
|
|
50665
|
+
* operator-local intent, kept off the peer-facing spawn door — see #159.) */
|
|
50638
50666
|
async spawn(name, role, opts) {
|
|
50639
50667
|
this.assertConnected();
|
|
50640
50668
|
return this.ep.requestControl(CONTROL_PRIVILEGED, {
|
|
@@ -50896,8 +50924,6 @@ function controlFailure(action, e) {
|
|
|
50896
50924
|
function statusGlyph(s) {
|
|
50897
50925
|
return s === "working" ? "\u25CF" : s === "waiting" ? "\u25D0" : s === "idle" ? "\u25CB" : "\xB7";
|
|
50898
50926
|
}
|
|
50899
|
-
var FACE_TAG_RE = /\[\[\s*face\s*:\s*[\w-]+\s*\]\]\s?/gi;
|
|
50900
|
-
var stripFaceTags = (text) => text.replace(FACE_TAG_RE, "");
|
|
50901
50927
|
var ATTENTION_DESC = {
|
|
50902
50928
|
open: "open \u2014 you receive everything; untagged channel chatter wakes you when idle",
|
|
50903
50929
|
dnd: "dnd \u2014 channel chatter no longer wakes you (it still arrives in your next turn); DMs, anycast, and @mentions still wake you",
|
|
@@ -51042,7 +51068,7 @@ ${all.map(fmtItem).join("\n")}`);
|
|
|
51042
51068
|
},
|
|
51043
51069
|
async run(agent, _config, { text: msg, channel, mentions }) {
|
|
51044
51070
|
try {
|
|
51045
|
-
const m = await agent.send(
|
|
51071
|
+
const m = await agent.send(msg, channel, mentions);
|
|
51046
51072
|
return ok(`Sent to #${m.channel}${m.mentions?.length ? ` (mentioned @${m.mentions.join(", @")})` : ""}.`);
|
|
51047
51073
|
} catch (e) {
|
|
51048
51074
|
return err(`Couldn't send: ${e.message}`);
|
|
@@ -51059,7 +51085,7 @@ ${all.map(fmtItem).join("\n")}`);
|
|
|
51059
51085
|
},
|
|
51060
51086
|
async run(agent, _config, { to, text: msg }) {
|
|
51061
51087
|
try {
|
|
51062
|
-
const { peer } = await agent.dm(to,
|
|
51088
|
+
const { peer } = await agent.dm(to, msg);
|
|
51063
51089
|
return ok(`DM sent to ${peer.card.name}.`);
|
|
51064
51090
|
} catch (e) {
|
|
51065
51091
|
if (e instanceof AmbiguousPeerError) {
|
|
@@ -51081,7 +51107,7 @@ ${who2}`);
|
|
|
51081
51107
|
},
|
|
51082
51108
|
async run(agent, _config, { role, text: msg }) {
|
|
51083
51109
|
try {
|
|
51084
|
-
await agent.anycast(role,
|
|
51110
|
+
await agent.anycast(role, msg);
|
|
51085
51111
|
return ok(`Sent to one @${role}.`);
|
|
51086
51112
|
} catch (e) {
|
|
51087
51113
|
return err(`Couldn't send: ${e.message}`);
|
|
@@ -51223,6 +51249,11 @@ ${info}${caught}`);
|
|
|
51223
51249
|
agent: external_exports.string().optional().describe("Optional harness the new peer runs on \u2014 the agent/connector type (claude, opencode, hermes), NOT the persona to spawn (that's `name`). Defaults to the manager's default (Claude)."),
|
|
51224
51250
|
model: external_exports.string().optional().describe("Optional model override (e.g. opus, sonnet) \u2014 wins over the persona file's model:."),
|
|
51225
51251
|
cwd: external_exports.string().optional().describe("Optional working directory to root the new peer at (e.g. a different repo). A relative path resolves against the manager's workspace; omitted \u2192 it shares the manager's workspace.")
|
|
51252
|
+
// NOTE: session `resume` is deliberately NOT exposed here. Forking a host-local `~/.claude`
|
|
51253
|
+
// transcript is an operator-local intent; letting a spawn-capable mesh PEER name a host
|
|
51254
|
+
// session id would expand `spawn` into host-transcript disclosure with no broker-enforced
|
|
51255
|
+
// boundary. Resume lives only on the operator CLI (`cotal spawn --resume` / `cotal start
|
|
51256
|
+
// --resume`); a peer-facing, capability-gated resume is deferred (see #159).
|
|
51226
51257
|
},
|
|
51227
51258
|
async run(agent, _config, { name, role, agent: agentType, model, cwd }) {
|
|
51228
51259
|
try {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cotal-ai/connector-claude-code",
|
|
3
3
|
"description": "Cotal connector for Claude Code: an installed plugin that joins a session to the mesh.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.9.0",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
22
|
-
"@cotal-ai/connector-core": "0.
|
|
22
|
+
"@cotal-ai/connector-core": "0.9.0"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
|
25
25
|
"@cotal-ai/core": ">=0.1.0"
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"esbuild": "^0.28.0",
|
|
29
29
|
"tsx": "^4.22.4",
|
|
30
|
-
"@cotal-ai/core": "0.
|
|
30
|
+
"@cotal-ai/core": "0.9.0"
|
|
31
31
|
},
|
|
32
32
|
"files": [
|
|
33
33
|
"dist",
|