claudemesh-cli 0.6.8 → 0.6.9
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/index.js +314 -93
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -47376,13 +47376,14 @@ var TOOLS = [
|
|
|
47376
47376
|
},
|
|
47377
47377
|
{
|
|
47378
47378
|
name: "schedule_reminder",
|
|
47379
|
-
description: "Schedule a
|
|
47379
|
+
description: "Schedule a one-shot or recurring message. Without `to`, it fires back to yourself (a self-reminder). With `to`, it delivers to a peer, @group, or * broadcast. For one-shot, provide `deliver_at` or `in_seconds`. For recurring, provide `cron` (standard 5-field expression). The broker persists schedules to the database — they survive restarts. Receivers see `subtype: reminder` in the push envelope.",
|
|
47380
47380
|
inputSchema: {
|
|
47381
47381
|
type: "object",
|
|
47382
47382
|
properties: {
|
|
47383
47383
|
message: { type: "string", description: "Message or reminder text" },
|
|
47384
|
-
deliver_at: { type: "number", description: "Unix timestamp (ms) when to deliver" },
|
|
47385
|
-
in_seconds: { type: "number", description: "Alternative to deliver_at: fire after N seconds" },
|
|
47384
|
+
deliver_at: { type: "number", description: "Unix timestamp (ms) when to deliver (one-shot)" },
|
|
47385
|
+
in_seconds: { type: "number", description: "Alternative to deliver_at: fire after N seconds (one-shot)" },
|
|
47386
|
+
cron: { type: "string", description: "Cron expression for recurring reminders (e.g. '0 */2 * * *' for every 2 hours, '30 9 * * 1-5' for 9:30 weekdays)" },
|
|
47386
47387
|
to: {
|
|
47387
47388
|
type: "string",
|
|
47388
47389
|
description: "Recipient: display name, pubkey hex, @group, or * (omit for self-reminder)"
|
|
@@ -47565,6 +47566,9 @@ class BrokerClient {
|
|
|
47565
47566
|
sessionId: `${process.pid}-${Date.now()}`,
|
|
47566
47567
|
pid: process.pid,
|
|
47567
47568
|
cwd: process.cwd(),
|
|
47569
|
+
peerType: "ai",
|
|
47570
|
+
channel: "claude-code",
|
|
47571
|
+
model: process.env.CLAUDE_MODEL || undefined,
|
|
47568
47572
|
timestamp,
|
|
47569
47573
|
signature
|
|
47570
47574
|
}));
|
|
@@ -47773,7 +47777,7 @@ class BrokerClient {
|
|
|
47773
47777
|
return;
|
|
47774
47778
|
this.ws.send(JSON.stringify({ type: "forget", memoryId }));
|
|
47775
47779
|
}
|
|
47776
|
-
async scheduleMessage(to, message, deliverAt, isReminder = false) {
|
|
47780
|
+
async scheduleMessage(to, message, deliverAt, isReminder = false, cron) {
|
|
47777
47781
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47778
47782
|
return null;
|
|
47779
47783
|
return new Promise((resolve) => {
|
|
@@ -47788,6 +47792,7 @@ class BrokerClient {
|
|
|
47788
47792
|
message,
|
|
47789
47793
|
deliverAt,
|
|
47790
47794
|
...isReminder ? { subtype: "reminder" } : {},
|
|
47795
|
+
...cron ? { cron, recurring: true } : {},
|
|
47791
47796
|
_reqId: reqId
|
|
47792
47797
|
}));
|
|
47793
47798
|
});
|
|
@@ -48234,7 +48239,9 @@ class BrokerClient {
|
|
|
48234
48239
|
receivedAt: new Date().toISOString(),
|
|
48235
48240
|
plaintext,
|
|
48236
48241
|
kind,
|
|
48237
|
-
...msg.subtype ? { subtype: msg.subtype } : {}
|
|
48242
|
+
...msg.subtype ? { subtype: msg.subtype } : {},
|
|
48243
|
+
...msg.event ? { event: String(msg.event) } : {},
|
|
48244
|
+
...msg.eventData ? { eventData: msg.eventData } : {}
|
|
48238
48245
|
};
|
|
48239
48246
|
this.pushBuffer.push(push);
|
|
48240
48247
|
if (this.pushBuffer.length > 500)
|
|
@@ -48402,7 +48409,8 @@ class BrokerClient {
|
|
|
48402
48409
|
if (msg.type === "scheduled_ack") {
|
|
48403
48410
|
this.resolveFromMap(this.scheduledAckResolvers, msgReqId, {
|
|
48404
48411
|
scheduledId: String(msg.scheduledId ?? ""),
|
|
48405
|
-
deliverAt: Number(msg.deliverAt ?? 0)
|
|
48412
|
+
deliverAt: Number(msg.deliverAt ?? 0),
|
|
48413
|
+
...msg.cron ? { cron: String(msg.cron) } : {}
|
|
48406
48414
|
});
|
|
48407
48415
|
return;
|
|
48408
48416
|
}
|
|
@@ -48805,7 +48813,16 @@ No peers connected.`);
|
|
|
48805
48813
|
const peerLines = peers.map((p) => {
|
|
48806
48814
|
const summary = p.summary ? ` — "${p.summary}"` : "";
|
|
48807
48815
|
const groupsStr = p.groups?.length ? ` [${p.groups.map((g) => `@${g.name}${g.role ? ":" + g.role : ""}`).join(", ")}]` : "";
|
|
48808
|
-
|
|
48816
|
+
const meta2 = [];
|
|
48817
|
+
if (p.peerType)
|
|
48818
|
+
meta2.push(`type:${p.peerType}`);
|
|
48819
|
+
if (p.channel)
|
|
48820
|
+
meta2.push(`channel:${p.channel}`);
|
|
48821
|
+
if (p.model)
|
|
48822
|
+
meta2.push(`model:${p.model}`);
|
|
48823
|
+
const metaStr = meta2.length ? ` {${meta2.join(", ")}}` : "";
|
|
48824
|
+
const cwdStr = p.cwd ? ` cwd:${p.cwd}` : "";
|
|
48825
|
+
return `- **${p.displayName}** [${p.status}]${groupsStr}${metaStr} (${p.pubkey.slice(0, 12)}…)${cwdStr}${summary}`;
|
|
48809
48826
|
});
|
|
48810
48827
|
sections.push(`${header}
|
|
48811
48828
|
${peerLines.join(`
|
|
@@ -48958,13 +48975,16 @@ ${lines.join(`
|
|
|
48958
48975
|
const sArgs = args ?? {};
|
|
48959
48976
|
if (!sArgs.message)
|
|
48960
48977
|
return text("schedule_reminder: `message` required", true);
|
|
48978
|
+
const isCron = !!sArgs.cron;
|
|
48961
48979
|
let deliverAt;
|
|
48962
|
-
if (
|
|
48980
|
+
if (isCron) {
|
|
48981
|
+
deliverAt = 0;
|
|
48982
|
+
} else if (sArgs.deliver_at) {
|
|
48963
48983
|
deliverAt = Number(sArgs.deliver_at);
|
|
48964
48984
|
} else if (sArgs.in_seconds) {
|
|
48965
48985
|
deliverAt = Date.now() + Number(sArgs.in_seconds) * 1000;
|
|
48966
48986
|
} else {
|
|
48967
|
-
return text("schedule_reminder: provide `deliver_at` (ms timestamp) or `
|
|
48987
|
+
return text("schedule_reminder: provide `deliver_at` (ms timestamp), `in_seconds`, or `cron` expression", true);
|
|
48968
48988
|
}
|
|
48969
48989
|
const isSelf = !sArgs.to;
|
|
48970
48990
|
let targetSpec;
|
|
@@ -48984,9 +49004,13 @@ ${lines.join(`
|
|
|
48984
49004
|
targetSpec = to;
|
|
48985
49005
|
}
|
|
48986
49006
|
}
|
|
48987
|
-
const result = await client.scheduleMessage(targetSpec, sArgs.message, deliverAt, true);
|
|
49007
|
+
const result = await client.scheduleMessage(targetSpec, sArgs.message, deliverAt, true, sArgs.cron);
|
|
48988
49008
|
if (!result)
|
|
48989
49009
|
return text("schedule_reminder: broker did not acknowledge — check connection", true);
|
|
49010
|
+
if (isCron) {
|
|
49011
|
+
const nextFire = new Date(result.deliverAt).toISOString();
|
|
49012
|
+
return text(isSelf ? `Recurring self-reminder scheduled (${result.scheduledId.slice(0, 8)}): "${sArgs.message.slice(0, 60)}" — cron: ${sArgs.cron}, next fire: ${nextFire}` : `Recurring reminder to "${sArgs.to}" scheduled (${result.scheduledId.slice(0, 8)}) — cron: ${sArgs.cron}, next fire: ${nextFire}`);
|
|
49013
|
+
}
|
|
48990
49014
|
const when = new Date(result.deliverAt).toISOString();
|
|
48991
49015
|
return text(isSelf ? `Self-reminder scheduled (${result.scheduledId.slice(0, 8)}): "${sArgs.message.slice(0, 60)}" at ${when}` : `Reminder to "${sArgs.to}" scheduled (${result.scheduledId.slice(0, 8)}) for ${when}`);
|
|
48992
49016
|
}
|
|
@@ -49502,6 +49526,39 @@ ${rows.join(`
|
|
|
49502
49526
|
client2.onPush(async (msg) => {
|
|
49503
49527
|
if (messageMode === "off")
|
|
49504
49528
|
return;
|
|
49529
|
+
if (msg.subtype === "system" && msg.event) {
|
|
49530
|
+
const eventName = msg.event;
|
|
49531
|
+
const data = msg.eventData ?? {};
|
|
49532
|
+
let content2;
|
|
49533
|
+
if (eventName === "peer_joined") {
|
|
49534
|
+
content2 = `[system] Peer "${data.name ?? "unknown"}" joined the mesh`;
|
|
49535
|
+
} else if (eventName === "peer_left") {
|
|
49536
|
+
content2 = `[system] Peer "${data.name ?? "unknown"}" left the mesh`;
|
|
49537
|
+
} else {
|
|
49538
|
+
content2 = `[system] ${eventName}: ${JSON.stringify(data)}`;
|
|
49539
|
+
}
|
|
49540
|
+
try {
|
|
49541
|
+
await server.notification({
|
|
49542
|
+
method: "notifications/claude/channel",
|
|
49543
|
+
params: {
|
|
49544
|
+
content: content2,
|
|
49545
|
+
meta: {
|
|
49546
|
+
kind: "system",
|
|
49547
|
+
event: eventName,
|
|
49548
|
+
mesh_slug: client2.meshSlug,
|
|
49549
|
+
mesh_id: client2.meshId,
|
|
49550
|
+
...Object.keys(data).length > 0 ? { eventData: data } : {}
|
|
49551
|
+
}
|
|
49552
|
+
}
|
|
49553
|
+
});
|
|
49554
|
+
process.stderr.write(`[claudemesh] system: ${content2}
|
|
49555
|
+
`);
|
|
49556
|
+
} catch (pushErr) {
|
|
49557
|
+
process.stderr.write(`[claudemesh] system push FAILED: ${pushErr}
|
|
49558
|
+
`);
|
|
49559
|
+
}
|
|
49560
|
+
return;
|
|
49561
|
+
}
|
|
49505
49562
|
const fromPubkey = msg.senderPubkey || "";
|
|
49506
49563
|
const fromName = fromPubkey ? await resolvePeerName(client2, fromPubkey) : "unknown";
|
|
49507
49564
|
if (messageMode === "inbox") {
|
|
@@ -49725,47 +49782,51 @@ function writeClaudeSettings(obj) {
|
|
|
49725
49782
|
`, "utf-8");
|
|
49726
49783
|
}
|
|
49727
49784
|
var CLAUDEMESH_TOOLS = [
|
|
49728
|
-
"
|
|
49729
|
-
"mcp__claudemesh__list_peers",
|
|
49785
|
+
"mcp__claudemesh__cancel_scheduled",
|
|
49730
49786
|
"mcp__claudemesh__check_messages",
|
|
49731
|
-
"
|
|
49732
|
-
"
|
|
49733
|
-
"
|
|
49734
|
-
"
|
|
49735
|
-
"
|
|
49736
|
-
"
|
|
49737
|
-
"mcp__claudemesh__list_state",
|
|
49738
|
-
"mcp__claudemesh__remember",
|
|
49739
|
-
"mcp__claudemesh__recall",
|
|
49787
|
+
"mcp__claudemesh__claim_task",
|
|
49788
|
+
"mcp__claudemesh__complete_task",
|
|
49789
|
+
"mcp__claudemesh__create_stream",
|
|
49790
|
+
"mcp__claudemesh__create_task",
|
|
49791
|
+
"mcp__claudemesh__delete_file",
|
|
49792
|
+
"mcp__claudemesh__file_status",
|
|
49740
49793
|
"mcp__claudemesh__forget",
|
|
49741
|
-
"
|
|
49794
|
+
"mcp__claudemesh__get_context",
|
|
49742
49795
|
"mcp__claudemesh__get_file",
|
|
49743
|
-
"
|
|
49744
|
-
"
|
|
49745
|
-
"mcp__claudemesh__delete_file",
|
|
49746
|
-
"mcp__claudemesh__vector_store",
|
|
49747
|
-
"mcp__claudemesh__vector_search",
|
|
49748
|
-
"mcp__claudemesh__vector_delete",
|
|
49749
|
-
"mcp__claudemesh__list_collections",
|
|
49750
|
-
"mcp__claudemesh__graph_query",
|
|
49796
|
+
"mcp__claudemesh__get_state",
|
|
49797
|
+
"mcp__claudemesh__grant_file_access",
|
|
49751
49798
|
"mcp__claudemesh__graph_execute",
|
|
49752
|
-
"
|
|
49753
|
-
"
|
|
49754
|
-
"
|
|
49755
|
-
"
|
|
49756
|
-
"mcp__claudemesh__get_context",
|
|
49799
|
+
"mcp__claudemesh__graph_query",
|
|
49800
|
+
"mcp__claudemesh__join_group",
|
|
49801
|
+
"mcp__claudemesh__leave_group",
|
|
49802
|
+
"mcp__claudemesh__list_collections",
|
|
49757
49803
|
"mcp__claudemesh__list_contexts",
|
|
49758
|
-
"
|
|
49759
|
-
"
|
|
49760
|
-
"
|
|
49761
|
-
"
|
|
49762
|
-
"mcp__claudemesh__create_stream",
|
|
49763
|
-
"mcp__claudemesh__publish",
|
|
49764
|
-
"mcp__claudemesh__subscribe",
|
|
49804
|
+
"mcp__claudemesh__list_files",
|
|
49805
|
+
"mcp__claudemesh__list_peers",
|
|
49806
|
+
"mcp__claudemesh__list_scheduled",
|
|
49807
|
+
"mcp__claudemesh__list_state",
|
|
49765
49808
|
"mcp__claudemesh__list_streams",
|
|
49809
|
+
"mcp__claudemesh__list_tasks",
|
|
49766
49810
|
"mcp__claudemesh__mesh_execute",
|
|
49811
|
+
"mcp__claudemesh__mesh_info",
|
|
49767
49812
|
"mcp__claudemesh__mesh_query",
|
|
49768
|
-
"mcp__claudemesh__mesh_schema"
|
|
49813
|
+
"mcp__claudemesh__mesh_schema",
|
|
49814
|
+
"mcp__claudemesh__message_status",
|
|
49815
|
+
"mcp__claudemesh__ping_mesh",
|
|
49816
|
+
"mcp__claudemesh__publish",
|
|
49817
|
+
"mcp__claudemesh__recall",
|
|
49818
|
+
"mcp__claudemesh__remember",
|
|
49819
|
+
"mcp__claudemesh__schedule_reminder",
|
|
49820
|
+
"mcp__claudemesh__send_message",
|
|
49821
|
+
"mcp__claudemesh__set_state",
|
|
49822
|
+
"mcp__claudemesh__set_status",
|
|
49823
|
+
"mcp__claudemesh__set_summary",
|
|
49824
|
+
"mcp__claudemesh__share_context",
|
|
49825
|
+
"mcp__claudemesh__share_file",
|
|
49826
|
+
"mcp__claudemesh__subscribe",
|
|
49827
|
+
"mcp__claudemesh__vector_delete",
|
|
49828
|
+
"mcp__claudemesh__vector_search",
|
|
49829
|
+
"mcp__claudemesh__vector_store"
|
|
49769
49830
|
];
|
|
49770
49831
|
function installAllowedTools() {
|
|
49771
49832
|
const settings = readClaudeSettings();
|
|
@@ -50559,7 +50620,7 @@ init_config();
|
|
|
50559
50620
|
// package.json
|
|
50560
50621
|
var package_default = {
|
|
50561
50622
|
name: "claudemesh-cli",
|
|
50562
|
-
version: "0.6.
|
|
50623
|
+
version: "0.6.9",
|
|
50563
50624
|
description: "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.",
|
|
50564
50625
|
keywords: [
|
|
50565
50626
|
"claude-code",
|
|
@@ -51025,8 +51086,19 @@ async function runPeers(flags) {
|
|
|
51025
51086
|
const groups = p.groups.length ? " [" + p.groups.map((g) => `@${g.name}${g.role ? `:${g.role}` : ""}`).join(", ") + "]" : "";
|
|
51026
51087
|
const statusIcon = p.status === "working" ? yellow("●") : green("●");
|
|
51027
51088
|
const name = bold2(p.displayName);
|
|
51089
|
+
const meta2 = [];
|
|
51090
|
+
if (p.peerType)
|
|
51091
|
+
meta2.push(p.peerType);
|
|
51092
|
+
if (p.channel)
|
|
51093
|
+
meta2.push(p.channel);
|
|
51094
|
+
if (p.model)
|
|
51095
|
+
meta2.push(p.model);
|
|
51096
|
+
const metaStr = meta2.length ? dim(` (${meta2.join(", ")})`) : "";
|
|
51097
|
+
const cwdStr = p.cwd ? dim(` cwd: ${p.cwd}`) : "";
|
|
51028
51098
|
const summary = p.summary ? dim(` ${p.summary}`) : "";
|
|
51029
|
-
console.log(` ${statusIcon} ${name}${groups}${summary}`);
|
|
51099
|
+
console.log(` ${statusIcon} ${name}${groups}${metaStr}${summary}`);
|
|
51100
|
+
if (cwdStr)
|
|
51101
|
+
console.log(` ${cwdStr}`);
|
|
51030
51102
|
}
|
|
51031
51103
|
console.log("");
|
|
51032
51104
|
});
|
|
@@ -51313,13 +51385,15 @@ async function runRemind(flags, positional) {
|
|
|
51313
51385
|
if (!message) {
|
|
51314
51386
|
console.error("Usage: claudemesh remind <message> --in <duration>");
|
|
51315
51387
|
console.error(" claudemesh remind <message> --at <time>");
|
|
51388
|
+
console.error(' claudemesh remind <message> --cron "0 */2 * * *"');
|
|
51316
51389
|
console.error(" claudemesh remind list");
|
|
51317
51390
|
console.error(" claudemesh remind cancel <id>");
|
|
51318
51391
|
process.exit(1);
|
|
51319
51392
|
}
|
|
51320
|
-
const
|
|
51321
|
-
|
|
51322
|
-
|
|
51393
|
+
const isCron = !!flags.cron;
|
|
51394
|
+
const deliverAt = isCron ? 0 : parseDeliverAt(flags);
|
|
51395
|
+
if (!isCron && deliverAt === null) {
|
|
51396
|
+
console.error('Specify when: --in <duration> (e.g. "2h", "30m"), --at <time> (e.g. "15:00"), or --cron <expression>');
|
|
51323
51397
|
process.exit(1);
|
|
51324
51398
|
}
|
|
51325
51399
|
await withMesh({ meshSlug: flags.mesh ?? null }, async (client2) => {
|
|
@@ -51339,7 +51413,7 @@ async function runRemind(flags, positional) {
|
|
|
51339
51413
|
} else {
|
|
51340
51414
|
targetSpec = client2.getSessionPubkey() ?? "*";
|
|
51341
51415
|
}
|
|
51342
|
-
const result = await client2.scheduleMessage(targetSpec, message, deliverAt);
|
|
51416
|
+
const result = await client2.scheduleMessage(targetSpec, message, deliverAt ?? 0, false, flags.cron);
|
|
51343
51417
|
if (!result) {
|
|
51344
51418
|
console.error("✗ Broker did not acknowledge — check connection");
|
|
51345
51419
|
process.exit(1);
|
|
@@ -51348,34 +51422,170 @@ async function runRemind(flags, positional) {
|
|
|
51348
51422
|
console.log(JSON.stringify(result));
|
|
51349
51423
|
return;
|
|
51350
51424
|
}
|
|
51351
|
-
const when = new Date(result.deliverAt).toLocaleString();
|
|
51352
51425
|
const toLabel = !flags.to || flags.to === "self" ? "yourself" : flags.to;
|
|
51353
|
-
|
|
51426
|
+
if (isCron) {
|
|
51427
|
+
const nextFire = new Date(result.deliverAt).toLocaleString();
|
|
51428
|
+
console.log(`✓ Recurring reminder set (${result.scheduledId.slice(0, 8)}): "${message}" → ${toLabel} — cron: ${flags.cron}, next fire: ${nextFire}`);
|
|
51429
|
+
} else {
|
|
51430
|
+
const when = new Date(result.deliverAt).toLocaleString();
|
|
51431
|
+
console.log(`✓ Reminder set (${result.scheduledId.slice(0, 8)}): "${message}" → ${toLabel} at ${when}`);
|
|
51432
|
+
}
|
|
51354
51433
|
});
|
|
51355
51434
|
}
|
|
51435
|
+
// src/templates/dev-team.json
|
|
51436
|
+
var dev_team_default = {
|
|
51437
|
+
name: "dev-team",
|
|
51438
|
+
description: "Software development team with frontend, backend, and devops groups",
|
|
51439
|
+
groups: [
|
|
51440
|
+
{ name: "frontend", roles: ["lead", "member"] },
|
|
51441
|
+
{ name: "backend", roles: ["lead", "member"] },
|
|
51442
|
+
{ name: "devops", roles: ["lead", "member"] },
|
|
51443
|
+
{ name: "qa", roles: ["lead", "member"] }
|
|
51444
|
+
],
|
|
51445
|
+
stateKeys: {
|
|
51446
|
+
sprint: "current",
|
|
51447
|
+
"deploy-frozen": "false",
|
|
51448
|
+
"pr-queue": "[]"
|
|
51449
|
+
},
|
|
51450
|
+
suggestedRoles: ["lead", "member", "reviewer"],
|
|
51451
|
+
systemPromptHint: "You are part of a dev team. Coordinate with @frontend, @backend, @devops groups. Check state keys for sprint status and deploy freezes before making changes."
|
|
51452
|
+
};
|
|
51453
|
+
// src/templates/research.json
|
|
51454
|
+
var research_default = {
|
|
51455
|
+
name: "research",
|
|
51456
|
+
description: "Research and analysis team focused on deep investigation and knowledge sharing",
|
|
51457
|
+
groups: [
|
|
51458
|
+
{ name: "analysis", roles: ["lead", "analyst"] },
|
|
51459
|
+
{ name: "writing", roles: ["lead", "writer", "reviewer"] },
|
|
51460
|
+
{ name: "data", roles: ["engineer", "analyst"] }
|
|
51461
|
+
],
|
|
51462
|
+
stateKeys: {
|
|
51463
|
+
"research-topic": "",
|
|
51464
|
+
phase: "exploration",
|
|
51465
|
+
"findings-count": "0"
|
|
51466
|
+
},
|
|
51467
|
+
suggestedRoles: ["lead", "analyst", "writer", "reviewer"],
|
|
51468
|
+
systemPromptHint: "You are part of a research team. Share findings via remember(), use recall() before starting new analysis. Coordinate phases through state keys."
|
|
51469
|
+
};
|
|
51470
|
+
// src/templates/ops-incident.json
|
|
51471
|
+
var ops_incident_default = {
|
|
51472
|
+
name: "ops-incident",
|
|
51473
|
+
description: "Incident response team with oncall, comms, and engineering groups",
|
|
51474
|
+
groups: [
|
|
51475
|
+
{ name: "oncall", roles: ["primary", "secondary"] },
|
|
51476
|
+
{ name: "comms", roles: ["lead", "scribe"] },
|
|
51477
|
+
{ name: "engineering", roles: ["lead", "responder"] }
|
|
51478
|
+
],
|
|
51479
|
+
stateKeys: {
|
|
51480
|
+
"incident-status": "investigating",
|
|
51481
|
+
severity: "unknown",
|
|
51482
|
+
commander: "",
|
|
51483
|
+
timeline: "[]"
|
|
51484
|
+
},
|
|
51485
|
+
suggestedRoles: ["commander", "primary-oncall", "scribe", "responder"],
|
|
51486
|
+
systemPromptHint: "INCIDENT MODE. Priority: now for all messages. Update incident-status state. Commander coordinates. Scribe maintains timeline. Engineering fixes."
|
|
51487
|
+
};
|
|
51488
|
+
// src/templates/simulation.json
|
|
51489
|
+
var simulation_default = {
|
|
51490
|
+
name: "simulation",
|
|
51491
|
+
description: "Load testing simulation with configurable time multiplier and user personas",
|
|
51492
|
+
groups: [
|
|
51493
|
+
{ name: "personas", roles: ["admin", "user", "customer"] },
|
|
51494
|
+
{ name: "observers", roles: ["monitor", "analyst"] },
|
|
51495
|
+
{ name: "control", roles: ["orchestrator"] }
|
|
51496
|
+
],
|
|
51497
|
+
stateKeys: {
|
|
51498
|
+
"clock-speed": "x1",
|
|
51499
|
+
"sim-status": "paused",
|
|
51500
|
+
"tick-count": "0",
|
|
51501
|
+
scenario: ""
|
|
51502
|
+
},
|
|
51503
|
+
suggestedRoles: ["orchestrator", "persona", "monitor"],
|
|
51504
|
+
systemPromptHint: "SIMULATION MODE. Follow the clock-speed state for time multiplier. Act according to your persona role and the simulated time. Report actions to @observers."
|
|
51505
|
+
};
|
|
51506
|
+
// src/templates/personal.json
|
|
51507
|
+
var personal_default = {
|
|
51508
|
+
name: "personal",
|
|
51509
|
+
description: "Private mesh for a single user — all sessions auto-join",
|
|
51510
|
+
groups: [],
|
|
51511
|
+
stateKeys: {
|
|
51512
|
+
focus: "",
|
|
51513
|
+
todos: "[]"
|
|
51514
|
+
},
|
|
51515
|
+
suggestedRoles: [],
|
|
51516
|
+
systemPromptHint: "Personal workspace. All your Claude Code sessions share this mesh. Use state keys to track focus and todos across sessions."
|
|
51517
|
+
};
|
|
51518
|
+
|
|
51519
|
+
// src/templates/index.ts
|
|
51520
|
+
var TEMPLATES = {
|
|
51521
|
+
"dev-team": dev_team_default,
|
|
51522
|
+
research: research_default,
|
|
51523
|
+
"ops-incident": ops_incident_default,
|
|
51524
|
+
simulation: simulation_default,
|
|
51525
|
+
personal: personal_default
|
|
51526
|
+
};
|
|
51527
|
+
function listTemplates() {
|
|
51528
|
+
return Object.values(TEMPLATES);
|
|
51529
|
+
}
|
|
51530
|
+
function getTemplate(name) {
|
|
51531
|
+
return TEMPLATES[name];
|
|
51532
|
+
}
|
|
51533
|
+
|
|
51534
|
+
// src/commands/create.ts
|
|
51535
|
+
function runCreate(args) {
|
|
51536
|
+
if (args["list-templates"]) {
|
|
51537
|
+
console.log(`Available mesh templates:
|
|
51538
|
+
`);
|
|
51539
|
+
for (const t of listTemplates()) {
|
|
51540
|
+
console.log(` ${t.name}`);
|
|
51541
|
+
console.log(` ${t.description}`);
|
|
51542
|
+
console.log(` Groups: ${t.groups.map((g) => g.name).join(", ") || "(none)"}`);
|
|
51543
|
+
console.log(` State keys: ${Object.keys(t.stateKeys).join(", ") || "(none)"}`);
|
|
51544
|
+
console.log();
|
|
51545
|
+
}
|
|
51546
|
+
return;
|
|
51547
|
+
}
|
|
51548
|
+
const templateName = args.template;
|
|
51549
|
+
if (templateName) {
|
|
51550
|
+
const template = getTemplate(templateName);
|
|
51551
|
+
if (!template) {
|
|
51552
|
+
console.error(`Unknown template "${templateName}". Use --list-templates to see available options.`);
|
|
51553
|
+
process.exit(1);
|
|
51554
|
+
}
|
|
51555
|
+
console.log(`Template "${template.name}" loaded:`);
|
|
51556
|
+
console.log(` Groups: ${template.groups.map((g) => `@${g.name}`).join(", ")}`);
|
|
51557
|
+
console.log(` State keys: ${Object.keys(template.stateKeys).join(", ")}`);
|
|
51558
|
+
console.log(` Hint: ${template.systemPromptHint.slice(0, 80)}...`);
|
|
51559
|
+
console.log();
|
|
51560
|
+
console.log("Template applied. Use `claudemesh launch` with --groups to join the predefined groups.");
|
|
51561
|
+
return;
|
|
51562
|
+
}
|
|
51563
|
+
console.log("Usage: claudemesh create --template <name>");
|
|
51564
|
+
console.log(" claudemesh create --list-templates");
|
|
51565
|
+
}
|
|
51356
51566
|
|
|
51357
51567
|
// src/index.ts
|
|
51358
51568
|
var launch = defineCommand({
|
|
51359
51569
|
meta: {
|
|
51360
51570
|
name: "launch",
|
|
51361
|
-
description: "
|
|
51571
|
+
description: "Spawn a Claude Code session with mesh connectivity and MCP tools"
|
|
51362
51572
|
},
|
|
51363
51573
|
args: {
|
|
51364
51574
|
name: {
|
|
51365
51575
|
type: "string",
|
|
51366
|
-
description: "Display name
|
|
51576
|
+
description: "Display name visible to other peers"
|
|
51367
51577
|
},
|
|
51368
51578
|
role: {
|
|
51369
51579
|
type: "string",
|
|
51370
|
-
description: "
|
|
51580
|
+
description: "Free-form role tag: `dev`, `lead`, `analyst`, etc"
|
|
51371
51581
|
},
|
|
51372
51582
|
groups: {
|
|
51373
51583
|
type: "string",
|
|
51374
|
-
description: 'Groups to join
|
|
51584
|
+
description: 'Groups to join as `group:role,...` — e.g. `"eng/frontend:lead,qa:member"`'
|
|
51375
51585
|
},
|
|
51376
51586
|
mesh: {
|
|
51377
51587
|
type: "string",
|
|
51378
|
-
description: "
|
|
51588
|
+
description: "Mesh slug (interactive picker if omitted and >1 joined)"
|
|
51379
51589
|
},
|
|
51380
51590
|
join: {
|
|
51381
51591
|
type: "string",
|
|
@@ -51383,21 +51593,21 @@ var launch = defineCommand({
|
|
|
51383
51593
|
},
|
|
51384
51594
|
"message-mode": {
|
|
51385
51595
|
type: "string",
|
|
51386
|
-
description: "push (default) | inbox | off —
|
|
51596
|
+
description: '`"push"` (default) | `"inbox"` | `"off"` — how peer messages arrive'
|
|
51387
51597
|
},
|
|
51388
51598
|
"system-prompt": {
|
|
51389
51599
|
type: "string",
|
|
51390
|
-
description: "
|
|
51600
|
+
description: "Custom system prompt for this Claude session"
|
|
51391
51601
|
},
|
|
51392
51602
|
yes: {
|
|
51393
51603
|
type: "boolean",
|
|
51394
51604
|
alias: "y",
|
|
51395
|
-
description: "Skip
|
|
51605
|
+
description: "Skip the --dangerously-skip-permissions confirmation",
|
|
51396
51606
|
default: false
|
|
51397
51607
|
},
|
|
51398
51608
|
quiet: {
|
|
51399
51609
|
type: "boolean",
|
|
51400
|
-
description: "
|
|
51610
|
+
description: "Suppress banner and interactive prompts",
|
|
51401
51611
|
default: false
|
|
51402
51612
|
}
|
|
51403
51613
|
},
|
|
@@ -51408,7 +51618,7 @@ var launch = defineCommand({
|
|
|
51408
51618
|
var install = defineCommand({
|
|
51409
51619
|
meta: {
|
|
51410
51620
|
name: "install",
|
|
51411
|
-
description: "Register MCP server
|
|
51621
|
+
description: "Register MCP server and status hooks with Claude Code"
|
|
51412
51622
|
},
|
|
51413
51623
|
args: {
|
|
51414
51624
|
"no-hooks": {
|
|
@@ -51424,12 +51634,12 @@ var install = defineCommand({
|
|
|
51424
51634
|
var join7 = defineCommand({
|
|
51425
51635
|
meta: {
|
|
51426
51636
|
name: "join",
|
|
51427
|
-
description: "Join a mesh via invite URL"
|
|
51637
|
+
description: "Join a mesh via invite URL or token"
|
|
51428
51638
|
},
|
|
51429
51639
|
args: {
|
|
51430
51640
|
url: {
|
|
51431
51641
|
type: "positional",
|
|
51432
|
-
description: "Invite URL (https://claudemesh.com/join
|
|
51642
|
+
description: "Invite URL (`https://claudemesh.com/join/...`) or token",
|
|
51433
51643
|
required: true
|
|
51434
51644
|
}
|
|
51435
51645
|
},
|
|
@@ -51440,12 +51650,12 @@ var join7 = defineCommand({
|
|
|
51440
51650
|
var leave = defineCommand({
|
|
51441
51651
|
meta: {
|
|
51442
51652
|
name: "leave",
|
|
51443
|
-
description: "Leave a joined mesh"
|
|
51653
|
+
description: "Leave a joined mesh and remove its local keypair"
|
|
51444
51654
|
},
|
|
51445
51655
|
args: {
|
|
51446
51656
|
slug: {
|
|
51447
51657
|
type: "positional",
|
|
51448
|
-
description: "Mesh slug to leave",
|
|
51658
|
+
description: "Mesh slug to leave (see `claudemesh list`)",
|
|
51449
51659
|
required: true
|
|
51450
51660
|
}
|
|
51451
51661
|
},
|
|
@@ -51461,23 +51671,33 @@ var main = defineCommand({
|
|
|
51461
51671
|
},
|
|
51462
51672
|
subCommands: {
|
|
51463
51673
|
launch,
|
|
51674
|
+
create: defineCommand({
|
|
51675
|
+
meta: { name: "create", description: "Create a new mesh from a template" },
|
|
51676
|
+
args: {
|
|
51677
|
+
template: { type: "string", description: "Template name: `dev-team`, `research`, `ops-incident`, `simulation`, `personal`" },
|
|
51678
|
+
"list-templates": { type: "boolean", description: "List available templates and exit", default: false }
|
|
51679
|
+
},
|
|
51680
|
+
run({ args }) {
|
|
51681
|
+
runCreate(args);
|
|
51682
|
+
}
|
|
51683
|
+
}),
|
|
51464
51684
|
install,
|
|
51465
51685
|
uninstall: defineCommand({
|
|
51466
|
-
meta: { name: "uninstall", description: "Remove MCP server and hooks" },
|
|
51686
|
+
meta: { name: "uninstall", description: "Remove MCP server and hooks from Claude Code config" },
|
|
51467
51687
|
run() {
|
|
51468
51688
|
runUninstall();
|
|
51469
51689
|
}
|
|
51470
51690
|
}),
|
|
51471
51691
|
join: join7,
|
|
51472
51692
|
list: defineCommand({
|
|
51473
|
-
meta: { name: "list", description: "Show joined meshes and identities" },
|
|
51693
|
+
meta: { name: "list", description: "Show joined meshes, slugs, and local identities" },
|
|
51474
51694
|
run() {
|
|
51475
51695
|
runList();
|
|
51476
51696
|
}
|
|
51477
51697
|
}),
|
|
51478
51698
|
leave,
|
|
51479
51699
|
peers: defineCommand({
|
|
51480
|
-
meta: { name: "peers", description: "List
|
|
51700
|
+
meta: { name: "peers", description: "List online peers with status, summary, and groups" },
|
|
51481
51701
|
args: {
|
|
51482
51702
|
mesh: { type: "string", description: "Mesh slug (auto-selected if only one joined)" },
|
|
51483
51703
|
json: { type: "boolean", description: "Output as JSON", default: false }
|
|
@@ -51487,34 +51707,34 @@ var main = defineCommand({
|
|
|
51487
51707
|
}
|
|
51488
51708
|
}),
|
|
51489
51709
|
send: defineCommand({
|
|
51490
|
-
meta: { name: "send", description: "Send a message to a peer, group, or
|
|
51710
|
+
meta: { name: "send", description: "Send a message to a peer, group, or all peers" },
|
|
51491
51711
|
args: {
|
|
51492
|
-
to: { type: "positional", description: "Recipient: display name,
|
|
51712
|
+
to: { type: "positional", description: "Recipient: display name, `@group`, `*` (broadcast), or pubkey hex", required: true },
|
|
51493
51713
|
message: { type: "positional", description: "Message text", required: true },
|
|
51494
51714
|
mesh: { type: "string", description: "Mesh slug (auto-selected if only one joined)" },
|
|
51495
|
-
priority: { type: "string", description: "now | next (default) | low" }
|
|
51715
|
+
priority: { type: "string", description: '`"now"` | `"next"` (default) | `"low"`' }
|
|
51496
51716
|
},
|
|
51497
51717
|
async run({ args }) {
|
|
51498
51718
|
await runSend(args, args.to, args.message);
|
|
51499
51719
|
}
|
|
51500
51720
|
}),
|
|
51501
51721
|
inbox: defineCommand({
|
|
51502
|
-
meta: { name: "inbox", description: "
|
|
51722
|
+
meta: { name: "inbox", description: "Drain pending inbound messages" },
|
|
51503
51723
|
args: {
|
|
51504
51724
|
mesh: { type: "string", description: "Mesh slug (auto-selected if only one joined)" },
|
|
51505
51725
|
json: { type: "boolean", description: "Output as JSON", default: false },
|
|
51506
|
-
wait: { type: "string", description: "Seconds to wait for broker delivery (default: 1)" }
|
|
51726
|
+
wait: { type: "string", description: "Seconds to wait for broker delivery (default: `1`)" }
|
|
51507
51727
|
},
|
|
51508
51728
|
async run({ args }) {
|
|
51509
51729
|
await runInbox({ ...args, wait: args.wait ? parseInt(args.wait, 10) : undefined });
|
|
51510
51730
|
}
|
|
51511
51731
|
}),
|
|
51512
51732
|
state: defineCommand({
|
|
51513
|
-
meta: { name: "state", description: "
|
|
51733
|
+
meta: { name: "state", description: "Get, set, or list shared key-value state in the mesh" },
|
|
51514
51734
|
args: {
|
|
51515
|
-
action: { type: "positional", description: "get | set | list", required: true },
|
|
51516
|
-
key: { type: "positional", description: "State key (required for get
|
|
51517
|
-
value: { type: "positional", description: "Value to
|
|
51735
|
+
action: { type: "positional", description: "`get <key>` | `set <key> <value>` | `list`", required: true },
|
|
51736
|
+
key: { type: "positional", description: "State key (required for `get` and `set`)" },
|
|
51737
|
+
value: { type: "positional", description: "Value to store (required for `set`)" },
|
|
51518
51738
|
mesh: { type: "string", description: "Mesh slug (auto-selected if only one joined)" },
|
|
51519
51739
|
json: { type: "boolean", description: "Output as JSON", default: false }
|
|
51520
51740
|
},
|
|
@@ -51550,11 +51770,11 @@ var main = defineCommand({
|
|
|
51550
51770
|
}
|
|
51551
51771
|
}),
|
|
51552
51772
|
remember: defineCommand({
|
|
51553
|
-
meta: { name: "remember", description: "Store a memory
|
|
51773
|
+
meta: { name: "remember", description: "Store a persistent memory visible to all peers" },
|
|
51554
51774
|
args: {
|
|
51555
|
-
content: { type: "positional", description: "Text to
|
|
51775
|
+
content: { type: "positional", description: "Text to store", required: true },
|
|
51556
51776
|
mesh: { type: "string", description: "Mesh slug (auto-selected if only one joined)" },
|
|
51557
|
-
tags: { type: "string", description: "Comma-separated tags
|
|
51777
|
+
tags: { type: "string", description: "Comma-separated tags, e.g. `task,context`" },
|
|
51558
51778
|
json: { type: "boolean", description: "Output as JSON", default: false }
|
|
51559
51779
|
},
|
|
51560
51780
|
async run({ args }) {
|
|
@@ -51562,9 +51782,9 @@ var main = defineCommand({
|
|
|
51562
51782
|
}
|
|
51563
51783
|
}),
|
|
51564
51784
|
recall: defineCommand({
|
|
51565
|
-
meta: { name: "recall", description: "Search mesh
|
|
51785
|
+
meta: { name: "recall", description: "Search mesh memories by keyword or phrase" },
|
|
51566
51786
|
args: {
|
|
51567
|
-
query: { type: "positional", description: "
|
|
51787
|
+
query: { type: "positional", description: "Full-text search query", required: true },
|
|
51568
51788
|
mesh: { type: "string", description: "Mesh slug (auto-selected if only one joined)" },
|
|
51569
51789
|
json: { type: "boolean", description: "Output as JSON", default: false }
|
|
51570
51790
|
},
|
|
@@ -51573,13 +51793,14 @@ var main = defineCommand({
|
|
|
51573
51793
|
}
|
|
51574
51794
|
}),
|
|
51575
51795
|
remind: defineCommand({
|
|
51576
|
-
meta: { name: "remind", description: "Schedule a
|
|
51796
|
+
meta: { name: "remind", description: "Schedule a delayed message. Also: `remind list`, `remind cancel <id>`" },
|
|
51577
51797
|
args: {
|
|
51578
|
-
message: { type: "positional", description: "Message text
|
|
51579
|
-
extra: { type: "positional", description: "
|
|
51580
|
-
in: { type: "string", description: 'Deliver after duration: "2h"
|
|
51581
|
-
at: { type: "string", description: 'Deliver at time: "15:00" or ISO timestamp' },
|
|
51582
|
-
|
|
51798
|
+
message: { type: "positional", description: "Message text — or `list` / `cancel <id>` to manage reminders", required: false },
|
|
51799
|
+
extra: { type: "positional", description: "Reminder ID for `cancel`", required: false },
|
|
51800
|
+
in: { type: "string", description: 'Deliver after duration: `"2h"`, `"30m"`, `"90s"`' },
|
|
51801
|
+
at: { type: "string", description: 'Deliver at time: `"15:00"` or ISO timestamp' },
|
|
51802
|
+
cron: { type: "string", description: 'Recurring cron expression: `"0 */2 * * *"` (every 2h), `"30 9 * * 1-5"` (9:30 weekdays)' },
|
|
51803
|
+
to: { type: "string", description: "Recipient (default: self). Name, `@group`, `*`, or pubkey" },
|
|
51583
51804
|
mesh: { type: "string", description: "Mesh slug (auto-selected if only one joined)" },
|
|
51584
51805
|
json: { type: "boolean", description: "Output as JSON", default: false }
|
|
51585
51806
|
},
|
|
@@ -51589,31 +51810,31 @@ var main = defineCommand({
|
|
|
51589
51810
|
}
|
|
51590
51811
|
}),
|
|
51591
51812
|
status: defineCommand({
|
|
51592
|
-
meta: { name: "status", description: "Check broker
|
|
51813
|
+
meta: { name: "status", description: "Check broker connectivity for each joined mesh" },
|
|
51593
51814
|
async run() {
|
|
51594
51815
|
await runStatus();
|
|
51595
51816
|
}
|
|
51596
51817
|
}),
|
|
51597
51818
|
doctor: defineCommand({
|
|
51598
|
-
meta: { name: "doctor", description: "Diagnose install, config, keypairs, and PATH" },
|
|
51819
|
+
meta: { name: "doctor", description: "Diagnose install, config, keypairs, and PATH issues" },
|
|
51599
51820
|
async run() {
|
|
51600
51821
|
await runDoctor();
|
|
51601
51822
|
}
|
|
51602
51823
|
}),
|
|
51603
51824
|
mcp: defineCommand({
|
|
51604
|
-
meta: { name: "mcp", description: "Start MCP server
|
|
51825
|
+
meta: { name: "mcp", description: "Start MCP server on stdio (called by Claude Code, not users)" },
|
|
51605
51826
|
async run() {
|
|
51606
51827
|
await startMcpServer();
|
|
51607
51828
|
}
|
|
51608
51829
|
}),
|
|
51609
51830
|
"seed-test-mesh": defineCommand({
|
|
51610
|
-
meta: { name: "seed-test-mesh", description: "Dev
|
|
51831
|
+
meta: { name: "seed-test-mesh", description: "Dev: inject a mesh into local config, skip invite flow" },
|
|
51611
51832
|
run({ rawArgs }) {
|
|
51612
51833
|
runSeedTestMesh(rawArgs);
|
|
51613
51834
|
}
|
|
51614
51835
|
}),
|
|
51615
51836
|
hook: defineCommand({
|
|
51616
|
-
meta: { name: "hook", description: "Internal
|
|
51837
|
+
meta: { name: "hook", description: "Internal: handle Claude Code hook events" },
|
|
51617
51838
|
async run({ rawArgs }) {
|
|
51618
51839
|
await runHook(rawArgs);
|
|
51619
51840
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudemesh-cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.9",
|
|
4
4
|
"description": "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|
|
@@ -48,10 +48,10 @@
|
|
|
48
48
|
"prettier": "3.6.2",
|
|
49
49
|
"typescript": "5.9.3",
|
|
50
50
|
"vitest": "4.0.14",
|
|
51
|
-
"@turbostarter/prettier-config": "0.1.0",
|
|
52
51
|
"@turbostarter/eslint-config": "0.1.0",
|
|
53
|
-
"@turbostarter/
|
|
54
|
-
"@turbostarter/tsconfig": "0.1.0"
|
|
52
|
+
"@turbostarter/prettier-config": "0.1.0",
|
|
53
|
+
"@turbostarter/tsconfig": "0.1.0",
|
|
54
|
+
"@turbostarter/vitest-config": "0.1.0"
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
57
|
"build": "bun build src/index.ts --target=node --outfile dist/index.js --banner \"#!/usr/bin/env node\" && chmod +x dist/index.js",
|