claudemesh-cli 1.34.5 → 1.34.7

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.
@@ -104,7 +104,7 @@ __export(exports_urls, {
104
104
  VERSION: () => VERSION,
105
105
  URLS: () => URLS
106
106
  });
107
- var URLS, VERSION = "1.34.5", env;
107
+ var URLS, VERSION = "1.34.7", env;
108
108
  var init_urls = __esm(() => {
109
109
  URLS = {
110
110
  BROKER: process.env.CLAUDEMESH_BROKER_URL ?? "wss://ic.claudemesh.com/ws",
@@ -4022,7 +4022,9 @@ __export(exports_daemon_route, {
4022
4022
  tryListInboxViaDaemon: () => tryListInboxViaDaemon,
4023
4023
  tryGetStateViaDaemon: () => tryGetStateViaDaemon,
4024
4024
  tryGetSkillViaDaemon: () => tryGetSkillViaDaemon,
4025
- tryForgetViaDaemon: () => tryForgetViaDaemon
4025
+ tryForgetViaDaemon: () => tryForgetViaDaemon,
4026
+ tryFlushInboxViaDaemon: () => tryFlushInboxViaDaemon,
4027
+ tryDeleteInboxRowViaDaemon: () => tryDeleteInboxRowViaDaemon
4026
4028
  });
4027
4029
  function meshQuery(mesh) {
4028
4030
  return mesh ? `?mesh=${encodeURIComponent(mesh)}` : "";
@@ -4066,6 +4068,48 @@ async function tryListInboxViaDaemon(mesh, limit = 100) {
4066
4068
  return null;
4067
4069
  }
4068
4070
  }
4071
+ async function tryFlushInboxViaDaemon(args = {}) {
4072
+ if (!await daemonReachable())
4073
+ return null;
4074
+ try {
4075
+ const params = [];
4076
+ if (args.mesh)
4077
+ params.push(`mesh=${encodeURIComponent(args.mesh)}`);
4078
+ if (args.beforeIso)
4079
+ params.push(`before=${encodeURIComponent(args.beforeIso)}`);
4080
+ const path = `/v1/inbox${params.length ? `?${params.join("&")}` : ""}`;
4081
+ const res = await ipc({ path, method: "DELETE", timeoutMs: 3000 });
4082
+ if (res.status !== 200)
4083
+ return null;
4084
+ return typeof res.body.removed === "number" ? res.body.removed : null;
4085
+ } catch (err) {
4086
+ const msg = String(err);
4087
+ if (/ENOENT|ECONNREFUSED|ipc_timeout/.test(msg))
4088
+ return null;
4089
+ return null;
4090
+ }
4091
+ }
4092
+ async function tryDeleteInboxRowViaDaemon(id) {
4093
+ if (!await daemonReachable())
4094
+ return null;
4095
+ try {
4096
+ const res = await ipc({
4097
+ path: `/v1/inbox/${encodeURIComponent(id)}`,
4098
+ method: "DELETE",
4099
+ timeoutMs: 3000
4100
+ });
4101
+ if (res.status === 404)
4102
+ return false;
4103
+ if (res.status !== 200)
4104
+ return null;
4105
+ return (res.body.removed ?? 0) > 0;
4106
+ } catch (err) {
4107
+ const msg = String(err);
4108
+ if (/ENOENT|ECONNREFUSED|ipc_timeout/.test(msg))
4109
+ return null;
4110
+ return null;
4111
+ }
4112
+ }
4069
4113
  async function tryListSkillsViaDaemon(mesh) {
4070
4114
  if (!await daemonReachable())
4071
4115
  return null;
@@ -8239,6 +8283,87 @@ var init_send = __esm(() => {
8239
8283
  init_styles();
8240
8284
  });
8241
8285
 
8286
+ // src/commands/inbox-actions.ts
8287
+ var exports_inbox_actions = {};
8288
+ __export(exports_inbox_actions, {
8289
+ runInboxFlush: () => runInboxFlush,
8290
+ runInboxDelete: () => runInboxDelete
8291
+ });
8292
+ async function runInboxFlush(flags) {
8293
+ const hasFilter = !!(flags.mesh || flags.before);
8294
+ if (!hasFilter && !flags.all) {
8295
+ if (flags.json) {
8296
+ process.stdout.write(JSON.stringify({ ok: false, error: "missing_filter" }) + `
8297
+ `);
8298
+ return;
8299
+ }
8300
+ render.info(dim(`Refusing to flush every row on every mesh.
8301
+ ` + " Re-run with --mesh <slug>, --before <iso-timestamp>, or --all to confirm."));
8302
+ process.exit(1);
8303
+ }
8304
+ const removed = await tryFlushInboxViaDaemon({
8305
+ ...flags.mesh ? { mesh: flags.mesh } : {},
8306
+ ...flags.before ? { beforeIso: flags.before } : {}
8307
+ });
8308
+ if (removed === null) {
8309
+ if (flags.json) {
8310
+ process.stdout.write(JSON.stringify({ ok: false, error: "daemon_unreachable" }) + `
8311
+ `);
8312
+ return;
8313
+ }
8314
+ render.info(dim("Daemon not reachable. Run `claudemesh daemon up` and retry."));
8315
+ process.exit(1);
8316
+ }
8317
+ if (flags.json) {
8318
+ process.stdout.write(JSON.stringify({ ok: true, removed }) + `
8319
+ `);
8320
+ return;
8321
+ }
8322
+ const scope = flags.mesh ? `mesh "${flags.mesh}"` : flags.before ? `older than ${flags.before}` : "all meshes";
8323
+ render.info(`✔ Flushed ${removed} message${removed === 1 ? "" : "s"} from ${scope}.`);
8324
+ }
8325
+ async function runInboxDelete(id, flags) {
8326
+ if (!id) {
8327
+ if (flags.json) {
8328
+ process.stdout.write(JSON.stringify({ ok: false, error: "missing_id" }) + `
8329
+ `);
8330
+ return;
8331
+ }
8332
+ render.info(dim("Usage: claudemesh inbox delete <message-id>"));
8333
+ process.exit(1);
8334
+ }
8335
+ const ok = await tryDeleteInboxRowViaDaemon(id);
8336
+ if (ok === null) {
8337
+ if (flags.json) {
8338
+ process.stdout.write(JSON.stringify({ ok: false, error: "daemon_unreachable" }) + `
8339
+ `);
8340
+ return;
8341
+ }
8342
+ render.info(dim("Daemon not reachable. Run `claudemesh daemon up` and retry."));
8343
+ process.exit(1);
8344
+ }
8345
+ if (!ok) {
8346
+ if (flags.json) {
8347
+ process.stdout.write(JSON.stringify({ ok: false, error: "not_found", id }) + `
8348
+ `);
8349
+ return;
8350
+ }
8351
+ render.info(dim(`No inbox row with id "${id}".`));
8352
+ process.exit(1);
8353
+ }
8354
+ if (flags.json) {
8355
+ process.stdout.write(JSON.stringify({ ok: true, id }) + `
8356
+ `);
8357
+ return;
8358
+ }
8359
+ render.info(`✔ Deleted inbox row ${id}.`);
8360
+ }
8361
+ var init_inbox_actions = __esm(() => {
8362
+ init_daemon_route();
8363
+ init_render();
8364
+ init_styles();
8365
+ });
8366
+
8242
8367
  // src/commands/inbox.ts
8243
8368
  var exports_inbox = {};
8244
8369
  __export(exports_inbox, {
@@ -9502,6 +9627,25 @@ function listInbox(db, p) {
9502
9627
  args.push(Math.min(Math.max(p.limit ?? 100, 1), 1000));
9503
9628
  return db.prepare(sql).all(...args);
9504
9629
  }
9630
+ function deleteInboxRow(db, id) {
9631
+ const r = db.prepare(`DELETE FROM inbox WHERE id = ?`).run(id);
9632
+ return Number(r.changes) > 0;
9633
+ }
9634
+ function flushInbox(db, p) {
9635
+ const where = [];
9636
+ const args = [];
9637
+ if (p.mesh !== undefined) {
9638
+ where.push("mesh = ?");
9639
+ args.push(p.mesh);
9640
+ }
9641
+ if (p.before !== undefined) {
9642
+ where.push("received_at < ?");
9643
+ args.push(p.before);
9644
+ }
9645
+ const sql = `DELETE FROM inbox ${where.length ? "WHERE " + where.join(" AND ") : ""}`;
9646
+ const r = db.prepare(sql).run(...args);
9647
+ return Number(r.changes);
9648
+ }
9505
9649
 
9506
9650
  // src/daemon/events.ts
9507
9651
  class EventBus {
@@ -10266,6 +10410,39 @@ function makeHandler(opts) {
10266
10410
  });
10267
10411
  return;
10268
10412
  }
10413
+ if (req.method === "DELETE" && url.pathname === "/v1/inbox") {
10414
+ if (!opts.inboxDb) {
10415
+ respond(res, 503, { error: "inbox not initialised" });
10416
+ return;
10417
+ }
10418
+ const meshFilter = meshFromCtx(url.searchParams.get("mesh")) ?? undefined;
10419
+ const beforeRaw = url.searchParams.get("before");
10420
+ const before = beforeRaw ? Date.parse(beforeRaw) : undefined;
10421
+ const removed = flushInbox(opts.inboxDb, {
10422
+ ...meshFilter ? { mesh: meshFilter } : {},
10423
+ ...Number.isFinite(before) ? { before } : {}
10424
+ });
10425
+ respond(res, 200, { removed });
10426
+ return;
10427
+ }
10428
+ if (req.method === "DELETE" && url.pathname.startsWith("/v1/inbox/")) {
10429
+ if (!opts.inboxDb) {
10430
+ respond(res, 503, { error: "inbox not initialised" });
10431
+ return;
10432
+ }
10433
+ const id = url.pathname.slice("/v1/inbox/".length);
10434
+ if (!id) {
10435
+ respond(res, 400, { error: "missing id" });
10436
+ return;
10437
+ }
10438
+ const ok = deleteInboxRow(opts.inboxDb, id);
10439
+ if (!ok) {
10440
+ respond(res, 404, { error: "not found", id });
10441
+ return;
10442
+ }
10443
+ respond(res, 200, { removed: 1, id });
10444
+ return;
10445
+ }
10269
10446
  if (req.method === "GET" && url.pathname === "/v1/outbox") {
10270
10447
  if (!opts.outboxDb) {
10271
10448
  respond(res, 503, { error: "outbox not initialised" });
@@ -16095,6 +16272,13 @@ claudemesh inbox --mesh <slug> # scoped to one mesh
16095
16272
  claudemesh inbox --mesh <slug> --limit 20 # custom cap
16096
16273
  claudemesh inbox --json # full row (sender_pubkey, mesh, body, received_at, …)
16097
16274
 
16275
+ # inbox flush + delete — 1.34.7+
16276
+ claudemesh inbox flush --mesh <slug> # delete all rows on one mesh
16277
+ claudemesh inbox flush --before <iso-timestamp> # delete rows older than timestamp
16278
+ claudemesh inbox flush --all # delete every row on every mesh (required guard)
16279
+ claudemesh inbox delete <id> # delete one inbox row by id (alias: rm)
16280
+ claudemesh inbox flush --mesh <slug> --json # JSON: { ok: true, removed: N }
16281
+
16098
16282
  # delivery status (alias: claudemesh msg-status <id>)
16099
16283
  claudemesh message status <message-id>
16100
16284
  claudemesh message status <message-id> --json
@@ -18480,18 +18664,16 @@ ${mf.allowed_tools.map((t) => ` - ${t}`).join(`
18480
18664
  } catch {}
18481
18665
  }
18482
18666
  });
18483
- const WELCOME_GRACE_FAST_MS = 5000;
18484
- const WELCOME_GRACE_SLOW_MS = 15000;
18667
+ const WELCOME_GRACE_MS = 3000;
18668
+ let welcomeSent = false;
18485
18669
  server.oninitialized = () => {
18486
18670
  mcpLog("server_initialized");
18671
+ if (welcomeSent)
18672
+ return;
18673
+ welcomeSent = true;
18487
18674
  setTimeout(() => {
18488
- mcpLog("welcome_attempt", { lane: "fast", grace_ms: WELCOME_GRACE_FAST_MS });
18489
- emitMeshWelcome(server, mcpLog);
18490
- }, WELCOME_GRACE_FAST_MS);
18491
- setTimeout(() => {
18492
- mcpLog("welcome_attempt", { lane: "slow", grace_ms: WELCOME_GRACE_SLOW_MS });
18493
18675
  emitMeshWelcome(server, mcpLog);
18494
- }, WELCOME_GRACE_SLOW_MS);
18676
+ }, WELCOME_GRACE_MS);
18495
18677
  };
18496
18678
  const transport = new StdioServerTransport;
18497
18679
  await server.connect(transport);
@@ -18604,10 +18786,10 @@ async function emitMeshWelcome(server, mcpLog) {
18604
18786
  self_session_pubkey: selfSessionPubkey ?? "",
18605
18787
  self_role: selfRole ?? "",
18606
18788
  mesh_slug: selfMeshSlug ?? "",
18607
- peer_count: peerCount >= 0 ? peerCount : null,
18608
- peer_names: peerNames,
18609
- unread_count: inboxItems.length,
18610
- latest_message_ids: inboxItems.slice(0, 10).map((it) => String(it.id ?? ""))
18789
+ peer_count: peerCount >= 0 ? String(peerCount) : "",
18790
+ peer_names: JSON.stringify(peerNames),
18791
+ unread_count: String(inboxItems.length),
18792
+ latest_message_ids: JSON.stringify(inboxItems.slice(0, 10).map((it) => String(it.id ?? "")))
18611
18793
  }
18612
18794
  }
18613
18795
  });
@@ -19493,6 +19675,10 @@ Message (resource form)
19493
19675
  claudemesh message inbox read persisted inbox (alias: inbox)
19494
19676
  flags: [--mesh <slug>] [--limit N] [--json]
19495
19677
  reads ~/.claudemesh/daemon/inbox.db via daemon
19678
+ claudemesh inbox flush bulk-delete inbox rows
19679
+ flags: [--mesh <slug>] [--before <iso-timestamp>] [--all]
19680
+ --all required when neither --mesh nor --before is set
19681
+ claudemesh inbox delete <id> delete one inbox row by id (alias: rm)
19496
19682
  claudemesh message status <id> delivery status (alias: msg-status)
19497
19683
 
19498
19684
  Memory (resource form)
@@ -19849,8 +20035,26 @@ async function main() {
19849
20035
  break;
19850
20036
  }
19851
20037
  case "inbox": {
19852
- const { runInbox: runInbox2 } = await Promise.resolve().then(() => (init_inbox(), exports_inbox));
19853
- await runInbox2({ mesh: flags.mesh, json: !!flags.json, limit: typeof flags.limit === "number" ? flags.limit : typeof flags.limit === "string" ? Number.parseInt(flags.limit, 10) : undefined });
20038
+ const sub = positionals[0];
20039
+ if (sub === "flush") {
20040
+ const { runInboxFlush: runInboxFlush2 } = await Promise.resolve().then(() => (init_inbox_actions(), exports_inbox_actions));
20041
+ await runInboxFlush2({
20042
+ mesh: flags.mesh,
20043
+ before: flags.before,
20044
+ all: !!flags.all,
20045
+ json: !!flags.json
20046
+ });
20047
+ } else if (sub === "delete" || sub === "rm") {
20048
+ const { runInboxDelete: runInboxDelete2 } = await Promise.resolve().then(() => (init_inbox_actions(), exports_inbox_actions));
20049
+ await runInboxDelete2(positionals[1] ?? "", { json: !!flags.json });
20050
+ } else {
20051
+ const { runInbox: runInbox2 } = await Promise.resolve().then(() => (init_inbox(), exports_inbox));
20052
+ await runInbox2({
20053
+ mesh: flags.mesh,
20054
+ json: !!flags.json,
20055
+ limit: typeof flags.limit === "number" ? flags.limit : typeof flags.limit === "string" ? Number.parseInt(flags.limit, 10) : undefined
20056
+ });
20057
+ }
19854
20058
  break;
19855
20059
  }
19856
20060
  case "state": {
@@ -20104,8 +20308,26 @@ async function main() {
20104
20308
  const { runSend: runSend2 } = await Promise.resolve().then(() => (init_send(), exports_send));
20105
20309
  await runSend2({ mesh: flags.mesh, priority: flags.priority, json: !!flags.json, self: !!flags.self }, positionals[1] ?? "", positionals.slice(2).join(" "));
20106
20310
  } else if (sub === "inbox") {
20107
- const { runInbox: runInbox2 } = await Promise.resolve().then(() => (init_inbox(), exports_inbox));
20108
- await runInbox2({ mesh: flags.mesh, json: !!flags.json, limit: typeof flags.limit === "number" ? flags.limit : typeof flags.limit === "string" ? Number.parseInt(flags.limit, 10) : undefined });
20311
+ const sub2 = positionals[1];
20312
+ if (sub2 === "flush") {
20313
+ const { runInboxFlush: runInboxFlush2 } = await Promise.resolve().then(() => (init_inbox_actions(), exports_inbox_actions));
20314
+ await runInboxFlush2({
20315
+ mesh: flags.mesh,
20316
+ before: flags.before,
20317
+ all: !!flags.all,
20318
+ json: !!flags.json
20319
+ });
20320
+ } else if (sub2 === "delete" || sub2 === "rm") {
20321
+ const { runInboxDelete: runInboxDelete2 } = await Promise.resolve().then(() => (init_inbox_actions(), exports_inbox_actions));
20322
+ await runInboxDelete2(positionals[2] ?? "", { json: !!flags.json });
20323
+ } else {
20324
+ const { runInbox: runInbox2 } = await Promise.resolve().then(() => (init_inbox(), exports_inbox));
20325
+ await runInbox2({
20326
+ mesh: flags.mesh,
20327
+ json: !!flags.json,
20328
+ limit: typeof flags.limit === "number" ? flags.limit : typeof flags.limit === "string" ? Number.parseInt(flags.limit, 10) : undefined
20329
+ });
20330
+ }
20109
20331
  } else if (sub === "status") {
20110
20332
  const { runMsgStatus: runMsgStatus2 } = await Promise.resolve().then(() => (init_broker_actions(), exports_broker_actions));
20111
20333
  process.exit(await runMsgStatus2(positionals[1], { mesh: flags.mesh, json: !!flags.json }));
@@ -20658,4 +20880,4 @@ main().catch((err) => {
20658
20880
  process.exit(EXIT.INTERNAL_ERROR);
20659
20881
  });
20660
20882
 
20661
- //# debugId=EF9DE01AAAC037BD64756E2164756E21
20883
+ //# debugId=FB01D4AF897A4CD164756E2164756E21