claudemesh-cli 0.4.0 → 0.5.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.
Files changed (2) hide show
  1. package/dist/index.js +949 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -46486,6 +46486,265 @@ var TOOLS = [
46486
46486
  },
46487
46487
  required: ["id"]
46488
46488
  }
46489
+ },
46490
+ {
46491
+ name: "vector_store",
46492
+ description: "Store an embedding in a per-mesh Qdrant collection. Auto-creates the collection on first use.",
46493
+ inputSchema: {
46494
+ type: "object",
46495
+ properties: {
46496
+ collection: { type: "string", description: "Collection name" },
46497
+ text: { type: "string", description: "Text to embed and store" },
46498
+ metadata: {
46499
+ type: "object",
46500
+ description: "Optional metadata to attach"
46501
+ }
46502
+ },
46503
+ required: ["collection", "text"]
46504
+ }
46505
+ },
46506
+ {
46507
+ name: "vector_search",
46508
+ description: "Semantic search over stored embeddings in a collection.",
46509
+ inputSchema: {
46510
+ type: "object",
46511
+ properties: {
46512
+ collection: { type: "string", description: "Collection name" },
46513
+ query: { type: "string", description: "Search query text" },
46514
+ limit: {
46515
+ type: "number",
46516
+ description: "Max results (default: 10)"
46517
+ }
46518
+ },
46519
+ required: ["collection", "query"]
46520
+ }
46521
+ },
46522
+ {
46523
+ name: "vector_delete",
46524
+ description: "Remove an embedding from a collection.",
46525
+ inputSchema: {
46526
+ type: "object",
46527
+ properties: {
46528
+ collection: { type: "string", description: "Collection name" },
46529
+ id: { type: "string", description: "Embedding ID to delete" }
46530
+ },
46531
+ required: ["collection", "id"]
46532
+ }
46533
+ },
46534
+ {
46535
+ name: "list_collections",
46536
+ description: "List vector collections in this mesh.",
46537
+ inputSchema: { type: "object", properties: {} }
46538
+ },
46539
+ {
46540
+ name: "graph_query",
46541
+ description: "Run a read-only Cypher query on the per-mesh Neo4j database.",
46542
+ inputSchema: {
46543
+ type: "object",
46544
+ properties: {
46545
+ cypher: { type: "string", description: "Cypher MATCH query" }
46546
+ },
46547
+ required: ["cypher"]
46548
+ }
46549
+ },
46550
+ {
46551
+ name: "graph_execute",
46552
+ description: "Run a write Cypher query (CREATE, MERGE, DELETE) on the per-mesh Neo4j database.",
46553
+ inputSchema: {
46554
+ type: "object",
46555
+ properties: {
46556
+ cypher: { type: "string", description: "Cypher write query" }
46557
+ },
46558
+ required: ["cypher"]
46559
+ }
46560
+ },
46561
+ {
46562
+ name: "mesh_query",
46563
+ description: "Run a SELECT query on the per-mesh shared database.",
46564
+ inputSchema: {
46565
+ type: "object",
46566
+ properties: {
46567
+ sql: { type: "string", description: "SQL SELECT query" }
46568
+ },
46569
+ required: ["sql"]
46570
+ }
46571
+ },
46572
+ {
46573
+ name: "mesh_execute",
46574
+ description: "Run DDL/DML on the per-mesh database (CREATE TABLE, INSERT, UPDATE, DELETE).",
46575
+ inputSchema: {
46576
+ type: "object",
46577
+ properties: {
46578
+ sql: { type: "string", description: "SQL statement" }
46579
+ },
46580
+ required: ["sql"]
46581
+ }
46582
+ },
46583
+ {
46584
+ name: "mesh_schema",
46585
+ description: "List tables and columns in the per-mesh shared database.",
46586
+ inputSchema: { type: "object", properties: {} }
46587
+ },
46588
+ {
46589
+ name: "create_stream",
46590
+ description: "Create a real-time data stream in the mesh.",
46591
+ inputSchema: {
46592
+ type: "object",
46593
+ properties: {
46594
+ name: { type: "string", description: "Stream name" }
46595
+ },
46596
+ required: ["name"]
46597
+ }
46598
+ },
46599
+ {
46600
+ name: "publish",
46601
+ description: "Push data to a stream. Subscribers receive it in real-time.",
46602
+ inputSchema: {
46603
+ type: "object",
46604
+ properties: {
46605
+ stream: { type: "string", description: "Stream name" },
46606
+ data: { description: "Any JSON data to publish" }
46607
+ },
46608
+ required: ["stream", "data"]
46609
+ }
46610
+ },
46611
+ {
46612
+ name: "subscribe",
46613
+ description: "Subscribe to a stream. Data pushes arrive as channel notifications.",
46614
+ inputSchema: {
46615
+ type: "object",
46616
+ properties: {
46617
+ stream: { type: "string", description: "Stream name" }
46618
+ },
46619
+ required: ["stream"]
46620
+ }
46621
+ },
46622
+ {
46623
+ name: "list_streams",
46624
+ description: "List active streams in the mesh.",
46625
+ inputSchema: { type: "object", properties: {} }
46626
+ },
46627
+ {
46628
+ name: "share_context",
46629
+ description: "Share your session understanding with the mesh. Call after exploring a codebase area.",
46630
+ inputSchema: {
46631
+ type: "object",
46632
+ properties: {
46633
+ summary: {
46634
+ type: "string",
46635
+ description: "Summary of what you explored/learned"
46636
+ },
46637
+ files_read: {
46638
+ type: "array",
46639
+ items: { type: "string" },
46640
+ description: "File paths you read"
46641
+ },
46642
+ key_findings: {
46643
+ type: "array",
46644
+ items: { type: "string" },
46645
+ description: "Key findings or insights"
46646
+ },
46647
+ tags: {
46648
+ type: "array",
46649
+ items: { type: "string" },
46650
+ description: "Tags for categorization"
46651
+ }
46652
+ },
46653
+ required: ["summary"]
46654
+ }
46655
+ },
46656
+ {
46657
+ name: "get_context",
46658
+ description: "Find context from peers who explored an area. Check before re-reading files another peer already analyzed.",
46659
+ inputSchema: {
46660
+ type: "object",
46661
+ properties: {
46662
+ query: {
46663
+ type: "string",
46664
+ description: "Search query (file path, topic, etc.)"
46665
+ }
46666
+ },
46667
+ required: ["query"]
46668
+ }
46669
+ },
46670
+ {
46671
+ name: "list_contexts",
46672
+ description: "See what all peers currently know about the codebase.",
46673
+ inputSchema: { type: "object", properties: {} }
46674
+ },
46675
+ {
46676
+ name: "create_task",
46677
+ description: "Create a work item for the mesh.",
46678
+ inputSchema: {
46679
+ type: "object",
46680
+ properties: {
46681
+ title: { type: "string", description: "Task title" },
46682
+ assignee: {
46683
+ type: "string",
46684
+ description: "Peer name to assign (optional)"
46685
+ },
46686
+ priority: {
46687
+ type: "string",
46688
+ enum: ["low", "normal", "high", "urgent"],
46689
+ description: "Priority level (default: normal)"
46690
+ },
46691
+ tags: {
46692
+ type: "array",
46693
+ items: { type: "string" },
46694
+ description: "Tags for categorization"
46695
+ }
46696
+ },
46697
+ required: ["title"]
46698
+ }
46699
+ },
46700
+ {
46701
+ name: "claim_task",
46702
+ description: "Claim an unclaimed task to take ownership.",
46703
+ inputSchema: {
46704
+ type: "object",
46705
+ properties: {
46706
+ id: { type: "string", description: "Task ID" }
46707
+ },
46708
+ required: ["id"]
46709
+ }
46710
+ },
46711
+ {
46712
+ name: "complete_task",
46713
+ description: "Mark a task as done with an optional result summary.",
46714
+ inputSchema: {
46715
+ type: "object",
46716
+ properties: {
46717
+ id: { type: "string", description: "Task ID" },
46718
+ result: {
46719
+ type: "string",
46720
+ description: "Summary of what was done"
46721
+ }
46722
+ },
46723
+ required: ["id"]
46724
+ }
46725
+ },
46726
+ {
46727
+ name: "list_tasks",
46728
+ description: "List tasks filtered by status and/or assignee.",
46729
+ inputSchema: {
46730
+ type: "object",
46731
+ properties: {
46732
+ status: {
46733
+ type: "string",
46734
+ enum: ["open", "claimed", "completed"],
46735
+ description: "Filter by status"
46736
+ },
46737
+ assignee: {
46738
+ type: "string",
46739
+ description: "Filter by assignee name"
46740
+ }
46741
+ }
46742
+ }
46743
+ },
46744
+ {
46745
+ name: "mesh_info",
46746
+ description: "Get a complete overview of the mesh: peers, groups, state, memory, files, tasks, streams, tables. Call on session start for full situational awareness.",
46747
+ inputSchema: { type: "object", properties: {} }
46489
46748
  }
46490
46749
  ];
46491
46750
 
@@ -46859,6 +47118,19 @@ class BrokerClient {
46859
47118
  fileUrlResolvers = [];
46860
47119
  fileListResolvers = [];
46861
47120
  fileStatusResolvers = [];
47121
+ vectorStoredResolvers = [];
47122
+ vectorResultsResolvers = [];
47123
+ collectionListResolvers = [];
47124
+ graphResultResolvers = [];
47125
+ contextListResolvers = [];
47126
+ contextResultsResolvers = [];
47127
+ taskCreatedResolvers = [];
47128
+ taskListResolvers = [];
47129
+ meshQueryResolvers = [];
47130
+ meshSchemaResolvers = [];
47131
+ streamCreatedResolvers = [];
47132
+ streamListResolvers = [];
47133
+ streamDataHandlers = new Set;
46862
47134
  async messageStatus(messageId) {
46863
47135
  if (!this.ws || this.ws.readyState !== this.ws.OPEN)
46864
47136
  return null;
@@ -46947,10 +47219,265 @@ class BrokerClient {
46947
47219
  const body = await res.json();
46948
47220
  return body.fileId ?? null;
46949
47221
  }
47222
+ async vectorStore(collection, text, metadata) {
47223
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47224
+ return null;
47225
+ return new Promise((resolve) => {
47226
+ this.vectorStoredResolvers.push(resolve);
47227
+ this.ws.send(JSON.stringify({ type: "vector_store", collection, text, metadata }));
47228
+ setTimeout(() => {
47229
+ const idx = this.vectorStoredResolvers.indexOf(resolve);
47230
+ if (idx !== -1) {
47231
+ this.vectorStoredResolvers.splice(idx, 1);
47232
+ resolve(null);
47233
+ }
47234
+ }, 5000);
47235
+ });
47236
+ }
47237
+ async vectorSearch(collection, query, limit) {
47238
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47239
+ return [];
47240
+ return new Promise((resolve) => {
47241
+ this.vectorResultsResolvers.push(resolve);
47242
+ this.ws.send(JSON.stringify({ type: "vector_search", collection, query, limit }));
47243
+ setTimeout(() => {
47244
+ const idx = this.vectorResultsResolvers.indexOf(resolve);
47245
+ if (idx !== -1) {
47246
+ this.vectorResultsResolvers.splice(idx, 1);
47247
+ resolve([]);
47248
+ }
47249
+ }, 5000);
47250
+ });
47251
+ }
47252
+ async vectorDelete(collection, id) {
47253
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47254
+ return;
47255
+ this.ws.send(JSON.stringify({ type: "vector_delete", collection, id }));
47256
+ }
47257
+ async listCollections() {
47258
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47259
+ return [];
47260
+ return new Promise((resolve) => {
47261
+ this.collectionListResolvers.push(resolve);
47262
+ this.ws.send(JSON.stringify({ type: "list_collections" }));
47263
+ setTimeout(() => {
47264
+ const idx = this.collectionListResolvers.indexOf(resolve);
47265
+ if (idx !== -1) {
47266
+ this.collectionListResolvers.splice(idx, 1);
47267
+ resolve([]);
47268
+ }
47269
+ }, 5000);
47270
+ });
47271
+ }
47272
+ async graphQuery(cypher) {
47273
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47274
+ return [];
47275
+ return new Promise((resolve) => {
47276
+ this.graphResultResolvers.push(resolve);
47277
+ this.ws.send(JSON.stringify({ type: "graph_query", cypher }));
47278
+ setTimeout(() => {
47279
+ const idx = this.graphResultResolvers.indexOf(resolve);
47280
+ if (idx !== -1) {
47281
+ this.graphResultResolvers.splice(idx, 1);
47282
+ resolve([]);
47283
+ }
47284
+ }, 5000);
47285
+ });
47286
+ }
47287
+ async graphExecute(cypher) {
47288
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47289
+ return [];
47290
+ return new Promise((resolve) => {
47291
+ this.graphResultResolvers.push(resolve);
47292
+ this.ws.send(JSON.stringify({ type: "graph_execute", cypher }));
47293
+ setTimeout(() => {
47294
+ const idx = this.graphResultResolvers.indexOf(resolve);
47295
+ if (idx !== -1) {
47296
+ this.graphResultResolvers.splice(idx, 1);
47297
+ resolve([]);
47298
+ }
47299
+ }, 5000);
47300
+ });
47301
+ }
47302
+ async shareContext(summary, filesRead, keyFindings, tags) {
47303
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47304
+ return;
47305
+ this.ws.send(JSON.stringify({ type: "share_context", summary, filesRead, keyFindings, tags }));
47306
+ }
47307
+ async getContext(query) {
47308
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47309
+ return [];
47310
+ return new Promise((resolve) => {
47311
+ this.contextResultsResolvers.push(resolve);
47312
+ this.ws.send(JSON.stringify({ type: "get_context", query }));
47313
+ setTimeout(() => {
47314
+ const idx = this.contextResultsResolvers.indexOf(resolve);
47315
+ if (idx !== -1) {
47316
+ this.contextResultsResolvers.splice(idx, 1);
47317
+ resolve([]);
47318
+ }
47319
+ }, 5000);
47320
+ });
47321
+ }
47322
+ async listContexts() {
47323
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47324
+ return [];
47325
+ return new Promise((resolve) => {
47326
+ this.contextListResolvers.push(resolve);
47327
+ this.ws.send(JSON.stringify({ type: "list_contexts" }));
47328
+ setTimeout(() => {
47329
+ const idx = this.contextListResolvers.indexOf(resolve);
47330
+ if (idx !== -1) {
47331
+ this.contextListResolvers.splice(idx, 1);
47332
+ resolve([]);
47333
+ }
47334
+ }, 5000);
47335
+ });
47336
+ }
47337
+ async createTask(title, assignee, priority, tags) {
47338
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47339
+ return null;
47340
+ return new Promise((resolve) => {
47341
+ this.taskCreatedResolvers.push(resolve);
47342
+ this.ws.send(JSON.stringify({ type: "create_task", title, assignee, priority, tags }));
47343
+ setTimeout(() => {
47344
+ const idx = this.taskCreatedResolvers.indexOf(resolve);
47345
+ if (idx !== -1) {
47346
+ this.taskCreatedResolvers.splice(idx, 1);
47347
+ resolve(null);
47348
+ }
47349
+ }, 5000);
47350
+ });
47351
+ }
47352
+ async claimTask(id) {
47353
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47354
+ return;
47355
+ this.ws.send(JSON.stringify({ type: "claim_task", id }));
47356
+ }
47357
+ async completeTask(id, result) {
47358
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47359
+ return;
47360
+ this.ws.send(JSON.stringify({ type: "complete_task", id, result }));
47361
+ }
47362
+ async listTasks(status, assignee) {
47363
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47364
+ return [];
47365
+ return new Promise((resolve) => {
47366
+ this.taskListResolvers.push(resolve);
47367
+ this.ws.send(JSON.stringify({ type: "list_tasks", status, assignee }));
47368
+ setTimeout(() => {
47369
+ const idx = this.taskListResolvers.indexOf(resolve);
47370
+ if (idx !== -1) {
47371
+ this.taskListResolvers.splice(idx, 1);
47372
+ resolve([]);
47373
+ }
47374
+ }, 5000);
47375
+ });
47376
+ }
47377
+ async meshQuery(sql) {
47378
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47379
+ return null;
47380
+ return new Promise((resolve) => {
47381
+ this.meshQueryResolvers.push(resolve);
47382
+ this.ws.send(JSON.stringify({ type: "mesh_query", sql }));
47383
+ setTimeout(() => {
47384
+ const idx = this.meshQueryResolvers.indexOf(resolve);
47385
+ if (idx !== -1) {
47386
+ this.meshQueryResolvers.splice(idx, 1);
47387
+ resolve(null);
47388
+ }
47389
+ }, 5000);
47390
+ });
47391
+ }
47392
+ async meshExecute(sql) {
47393
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47394
+ return;
47395
+ this.ws.send(JSON.stringify({ type: "mesh_execute", sql }));
47396
+ }
47397
+ async meshSchema() {
47398
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47399
+ return [];
47400
+ return new Promise((resolve) => {
47401
+ this.meshSchemaResolvers.push(resolve);
47402
+ this.ws.send(JSON.stringify({ type: "mesh_schema" }));
47403
+ setTimeout(() => {
47404
+ const idx = this.meshSchemaResolvers.indexOf(resolve);
47405
+ if (idx !== -1) {
47406
+ this.meshSchemaResolvers.splice(idx, 1);
47407
+ resolve([]);
47408
+ }
47409
+ }, 5000);
47410
+ });
47411
+ }
47412
+ async createStream(name) {
47413
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47414
+ return null;
47415
+ return new Promise((resolve) => {
47416
+ this.streamCreatedResolvers.push(resolve);
47417
+ this.ws.send(JSON.stringify({ type: "create_stream", name }));
47418
+ setTimeout(() => {
47419
+ const idx = this.streamCreatedResolvers.indexOf(resolve);
47420
+ if (idx !== -1) {
47421
+ this.streamCreatedResolvers.splice(idx, 1);
47422
+ resolve(null);
47423
+ }
47424
+ }, 5000);
47425
+ });
47426
+ }
47427
+ async publish(stream, data) {
47428
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47429
+ return;
47430
+ this.ws.send(JSON.stringify({ type: "publish", stream, data }));
47431
+ }
47432
+ async subscribe(stream) {
47433
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47434
+ return;
47435
+ this.ws.send(JSON.stringify({ type: "subscribe", stream }));
47436
+ }
47437
+ async unsubscribe(stream) {
47438
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47439
+ return;
47440
+ this.ws.send(JSON.stringify({ type: "unsubscribe", stream }));
47441
+ }
47442
+ async listStreams() {
47443
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47444
+ return [];
47445
+ return new Promise((resolve) => {
47446
+ this.streamListResolvers.push(resolve);
47447
+ this.ws.send(JSON.stringify({ type: "list_streams" }));
47448
+ setTimeout(() => {
47449
+ const idx = this.streamListResolvers.indexOf(resolve);
47450
+ if (idx !== -1) {
47451
+ this.streamListResolvers.splice(idx, 1);
47452
+ resolve([]);
47453
+ }
47454
+ }, 5000);
47455
+ });
47456
+ }
47457
+ onStreamData(handler) {
47458
+ this.streamDataHandlers.add(handler);
47459
+ return () => this.streamDataHandlers.delete(handler);
47460
+ }
46950
47461
  onStateChange(handler) {
46951
47462
  this.stateChangeHandlers.add(handler);
46952
47463
  return () => this.stateChangeHandlers.delete(handler);
46953
47464
  }
47465
+ meshInfoResolvers = [];
47466
+ async meshInfo() {
47467
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN)
47468
+ return null;
47469
+ return new Promise((resolve) => {
47470
+ this.meshInfoResolvers.push(resolve);
47471
+ this.ws.send(JSON.stringify({ type: "mesh_info" }));
47472
+ setTimeout(() => {
47473
+ const idx = this.meshInfoResolvers.indexOf(resolve);
47474
+ if (idx !== -1) {
47475
+ this.meshInfoResolvers.splice(idx, 1);
47476
+ resolve(null);
47477
+ }
47478
+ }, 5000);
47479
+ });
47480
+ }
46954
47481
  close() {
46955
47482
  this.closed = true;
46956
47483
  if (this.helloTimer)
@@ -47113,6 +47640,114 @@ class BrokerClient {
47113
47640
  resolver(accesses);
47114
47641
  return;
47115
47642
  }
47643
+ if (msg.type === "vector_stored") {
47644
+ const resolver = this.vectorStoredResolvers.shift();
47645
+ if (resolver)
47646
+ resolver(msg.id ? String(msg.id) : null);
47647
+ return;
47648
+ }
47649
+ if (msg.type === "vector_results") {
47650
+ const results = msg.results ?? [];
47651
+ const resolver = this.vectorResultsResolvers.shift();
47652
+ if (resolver)
47653
+ resolver(results);
47654
+ return;
47655
+ }
47656
+ if (msg.type === "collection_list") {
47657
+ const collections = msg.collections ?? [];
47658
+ const resolver = this.collectionListResolvers.shift();
47659
+ if (resolver)
47660
+ resolver(collections);
47661
+ return;
47662
+ }
47663
+ if (msg.type === "graph_result") {
47664
+ const rows = msg.rows ?? [];
47665
+ const resolver = this.graphResultResolvers.shift();
47666
+ if (resolver)
47667
+ resolver(rows);
47668
+ return;
47669
+ }
47670
+ if (msg.type === "context_list") {
47671
+ const contexts = msg.contexts ?? [];
47672
+ const resolver = this.contextListResolvers.shift();
47673
+ if (resolver)
47674
+ resolver(contexts);
47675
+ return;
47676
+ }
47677
+ if (msg.type === "context_results") {
47678
+ const contexts = msg.contexts ?? [];
47679
+ const resolver = this.contextResultsResolvers.shift();
47680
+ if (resolver)
47681
+ resolver(contexts);
47682
+ return;
47683
+ }
47684
+ if (msg.type === "task_created") {
47685
+ const resolver = this.taskCreatedResolvers.shift();
47686
+ if (resolver)
47687
+ resolver(msg.id ? String(msg.id) : null);
47688
+ return;
47689
+ }
47690
+ if (msg.type === "task_list") {
47691
+ const tasks = msg.tasks ?? [];
47692
+ const resolver = this.taskListResolvers.shift();
47693
+ if (resolver)
47694
+ resolver(tasks);
47695
+ return;
47696
+ }
47697
+ if (msg.type === "mesh_query_result") {
47698
+ const resolver = this.meshQueryResolvers.shift();
47699
+ if (resolver) {
47700
+ if (msg.columns) {
47701
+ resolver({
47702
+ columns: msg.columns ?? [],
47703
+ rows: msg.rows ?? [],
47704
+ rowCount: msg.rowCount ?? 0
47705
+ });
47706
+ } else {
47707
+ resolver(null);
47708
+ }
47709
+ }
47710
+ return;
47711
+ }
47712
+ if (msg.type === "mesh_schema_result") {
47713
+ const tables = msg.tables ?? [];
47714
+ const resolver = this.meshSchemaResolvers.shift();
47715
+ if (resolver)
47716
+ resolver(tables);
47717
+ return;
47718
+ }
47719
+ if (msg.type === "stream_created") {
47720
+ const resolver = this.streamCreatedResolvers.shift();
47721
+ if (resolver)
47722
+ resolver(msg.id ? String(msg.id) : null);
47723
+ return;
47724
+ }
47725
+ if (msg.type === "stream_list") {
47726
+ const streams = msg.streams ?? [];
47727
+ const resolver = this.streamListResolvers.shift();
47728
+ if (resolver)
47729
+ resolver(streams);
47730
+ return;
47731
+ }
47732
+ if (msg.type === "stream_data") {
47733
+ const evt = {
47734
+ stream: String(msg.stream ?? ""),
47735
+ data: msg.data,
47736
+ publishedBy: String(msg.publishedBy ?? "")
47737
+ };
47738
+ for (const h of this.streamDataHandlers) {
47739
+ try {
47740
+ h(evt);
47741
+ } catch {}
47742
+ }
47743
+ return;
47744
+ }
47745
+ if (msg.type === "mesh_info_result") {
47746
+ const resolver = this.meshInfoResolvers.shift();
47747
+ if (resolver)
47748
+ resolver(msg);
47749
+ return;
47750
+ }
47116
47751
  if (msg.type === "error") {
47117
47752
  this.debug(`broker error: ${msg.code} ${msg.message}`);
47118
47753
  const id = msg.id ? String(msg.id) : null;
@@ -47318,6 +47953,26 @@ When you receive a <channel source="claudemesh" ...> message, RESPOND IMMEDIATEL
47318
47953
  | list_files(query?, from?) | Find files shared in the mesh. |
47319
47954
  | file_status(id) | Check who has accessed a file. |
47320
47955
  | delete_file(id) | Remove a shared file from the mesh. |
47956
+ | vector_store(collection, text, metadata?) | Store embedding in per-mesh Qdrant collection. |
47957
+ | vector_search(collection, query, limit?) | Semantic search over stored embeddings. |
47958
+ | vector_delete(collection, id) | Remove an embedding. |
47959
+ | list_collections() | List vector collections in this mesh. |
47960
+ | graph_query(cypher) | Read-only Cypher query on per-mesh Neo4j. |
47961
+ | graph_execute(cypher) | Write Cypher query (CREATE, MERGE, DELETE). |
47962
+ | mesh_query(sql) | Run a SELECT query on the per-mesh shared database. |
47963
+ | mesh_execute(sql) | Run DDL/DML on the per-mesh database (CREATE TABLE, INSERT, UPDATE, DELETE). |
47964
+ | mesh_schema() | List tables and columns in the per-mesh shared database. |
47965
+ | create_stream(name) | Create a real-time data stream in the mesh. |
47966
+ | publish(stream, data) | Push data to a stream. Subscribers receive it in real-time. |
47967
+ | subscribe(stream) | Subscribe to a stream. Data pushes arrive as channel notifications. |
47968
+ | list_streams() | List active streams in the mesh. |
47969
+ | share_context(summary, files_read?, key_findings?, tags?) | Share session understanding with peers. |
47970
+ | get_context(query) | Find context from peers who explored an area. |
47971
+ | list_contexts() | See what all peers currently know. |
47972
+ | create_task(title, assignee?, priority?, tags?) | Create a work item. |
47973
+ | claim_task(id) | Claim an unclaimed task. |
47974
+ | complete_task(id, result?) | Mark task done with optional result. |
47975
+ | list_tasks(status?, assignee?) | List tasks filtered by status/assignee. |
47321
47976
 
47322
47977
  If multiple meshes are joined, prefix \`to\` with \`<mesh-slug>:\` to disambiguate (e.g. \`dev-team:Alice\`).
47323
47978
 
@@ -47344,6 +47999,24 @@ Persistent knowledge that survives across sessions. Use remember(content, tags?)
47344
47999
  share_file for persistent references, send_message(file:) for ephemeral attachments.
47345
48000
  Tags on shared files make them searchable. Use list_files to find what peers shared.
47346
48001
 
48002
+ ## Vectors
48003
+ Store and search semantic embeddings. Use vector_store to index content, vector_search to find similar content.
48004
+
48005
+ ## Graph
48006
+ Build and query entity relationship graphs. Use graph_execute for writes (CREATE, MERGE), graph_query for reads (MATCH).
48007
+
48008
+ ## Mesh Database
48009
+ Per-mesh PostgreSQL database. Use mesh_execute for DDL/DML (CREATE TABLE, INSERT), mesh_query for SELECT, mesh_schema to inspect tables. Schema auto-created on first use.
48010
+
48011
+ ## Streams
48012
+ Real-time data channels. create_stream to start one, publish to push data, subscribe to receive pushes. Use for build logs, deploy status, live metrics.
48013
+
48014
+ ## Context
48015
+ Share your session understanding with peers. Use share_context after exploring a codebase area. Check get_context before re-reading files another peer already analyzed.
48016
+
48017
+ ## Tasks
48018
+ Create and claim work items. create_task to propose work, claim_task to take ownership, complete_task when done. Prevents duplicate effort.
48019
+
47347
48020
  ## Priority
47348
48021
  - "now": interrupt immediately, even if recipient is in DND (use for urgent: broken deploy, blocking issue)
47349
48022
  - "next" (default): deliver when recipient goes idle (normal coordination)
@@ -47622,6 +48295,266 @@ ${lines.join(`
47622
48295
  await client.deleteFile(id);
47623
48296
  return text(`Deleted: ${id}`);
47624
48297
  }
48298
+ case "vector_store": {
48299
+ const { collection, text: storeText, metadata } = args ?? {};
48300
+ if (!collection || !storeText)
48301
+ return text("vector_store: `collection` and `text` required", true);
48302
+ const client = allClients()[0];
48303
+ if (!client)
48304
+ return text("vector_store: not connected", true);
48305
+ const id = await client.vectorStore(collection, storeText, metadata);
48306
+ return text(`Stored in ${collection}${id ? ` (${id})` : ""}`);
48307
+ }
48308
+ case "vector_search": {
48309
+ const { collection, query, limit } = args ?? {};
48310
+ if (!collection || !query)
48311
+ return text("vector_search: `collection` and `query` required", true);
48312
+ const client = allClients()[0];
48313
+ if (!client)
48314
+ return text("vector_search: not connected", true);
48315
+ const results = await client.vectorSearch(collection, query, limit);
48316
+ if (results.length === 0)
48317
+ return text(`No results in ${collection} for "${query}".`);
48318
+ const lines = results.map((r) => `- [${r.id.slice(0, 8)}…] (score: ${r.score.toFixed(3)}) ${r.text.slice(0, 120)}${r.text.length > 120 ? "…" : ""}`);
48319
+ return text(`${results.length} result(s) in ${collection}:
48320
+ ${lines.join(`
48321
+ `)}`);
48322
+ }
48323
+ case "vector_delete": {
48324
+ const { collection, id } = args ?? {};
48325
+ if (!collection || !id)
48326
+ return text("vector_delete: `collection` and `id` required", true);
48327
+ const client = allClients()[0];
48328
+ if (!client)
48329
+ return text("vector_delete: not connected", true);
48330
+ await client.vectorDelete(collection, id);
48331
+ return text(`Deleted ${id} from ${collection}`);
48332
+ }
48333
+ case "list_collections": {
48334
+ const client = allClients()[0];
48335
+ if (!client)
48336
+ return text("list_collections: not connected", true);
48337
+ const collections = await client.listCollections();
48338
+ if (collections.length === 0)
48339
+ return text("No vector collections.");
48340
+ return text(`Collections:
48341
+ ${collections.map((c) => `- ${c}`).join(`
48342
+ `)}`);
48343
+ }
48344
+ case "graph_query": {
48345
+ const { cypher } = args ?? {};
48346
+ if (!cypher)
48347
+ return text("graph_query: `cypher` required", true);
48348
+ const client = allClients()[0];
48349
+ if (!client)
48350
+ return text("graph_query: not connected", true);
48351
+ const rows = await client.graphQuery(cypher);
48352
+ if (rows.length === 0)
48353
+ return text("No results.");
48354
+ return text(JSON.stringify(rows, null, 2));
48355
+ }
48356
+ case "graph_execute": {
48357
+ const { cypher } = args ?? {};
48358
+ if (!cypher)
48359
+ return text("graph_execute: `cypher` required", true);
48360
+ const client = allClients()[0];
48361
+ if (!client)
48362
+ return text("graph_execute: not connected", true);
48363
+ const rows = await client.graphExecute(cypher);
48364
+ return text(rows.length > 0 ? JSON.stringify(rows, null, 2) : "Executed successfully.");
48365
+ }
48366
+ case "share_context": {
48367
+ const { summary, files_read, key_findings, tags } = args ?? {};
48368
+ if (!summary)
48369
+ return text("share_context: `summary` required", true);
48370
+ const client = allClients()[0];
48371
+ if (!client)
48372
+ return text("share_context: not connected", true);
48373
+ await client.shareContext(summary, files_read, key_findings, tags);
48374
+ return text(`Context shared: "${summary.slice(0, 80)}${summary.length > 80 ? "…" : ""}"`);
48375
+ }
48376
+ case "get_context": {
48377
+ const { query } = args ?? {};
48378
+ if (!query)
48379
+ return text("get_context: `query` required", true);
48380
+ const client = allClients()[0];
48381
+ if (!client)
48382
+ return text("get_context: not connected", true);
48383
+ const contexts = await client.getContext(query);
48384
+ if (contexts.length === 0)
48385
+ return text(`No context found for "${query}".`);
48386
+ const lines = contexts.map((c) => {
48387
+ const files = c.filesRead.length ? `
48388
+ Files: ${c.filesRead.join(", ")}` : "";
48389
+ const findings = c.keyFindings.length ? `
48390
+ Findings: ${c.keyFindings.join("; ")}` : "";
48391
+ return `- **${c.peerName}** (${c.updatedAt}): ${c.summary}${files}${findings}`;
48392
+ });
48393
+ return text(`${contexts.length} context(s):
48394
+ ${lines.join(`
48395
+ `)}`);
48396
+ }
48397
+ case "list_contexts": {
48398
+ const client = allClients()[0];
48399
+ if (!client)
48400
+ return text("list_contexts: not connected", true);
48401
+ const contexts = await client.listContexts();
48402
+ if (contexts.length === 0)
48403
+ return text("No peer contexts shared yet.");
48404
+ const lines = contexts.map((c) => `- **${c.peerName}**: ${c.summary}${c.tags.length ? ` [${c.tags.join(", ")}]` : ""}`);
48405
+ return text(`Peer contexts:
48406
+ ${lines.join(`
48407
+ `)}`);
48408
+ }
48409
+ case "create_task": {
48410
+ const { title, assignee, priority, tags } = args ?? {};
48411
+ if (!title)
48412
+ return text("create_task: `title` required", true);
48413
+ const client = allClients()[0];
48414
+ if (!client)
48415
+ return text("create_task: not connected", true);
48416
+ const id = await client.createTask(title, assignee, priority, tags);
48417
+ return text(`Task created${id ? ` (${id})` : ""}: "${title}"${assignee ? ` → ${assignee}` : ""}`);
48418
+ }
48419
+ case "claim_task": {
48420
+ const { id } = args ?? {};
48421
+ if (!id)
48422
+ return text("claim_task: `id` required", true);
48423
+ const client = allClients()[0];
48424
+ if (!client)
48425
+ return text("claim_task: not connected", true);
48426
+ await client.claimTask(id);
48427
+ return text(`Claimed task: ${id}`);
48428
+ }
48429
+ case "complete_task": {
48430
+ const { id, result } = args ?? {};
48431
+ if (!id)
48432
+ return text("complete_task: `id` required", true);
48433
+ const client = allClients()[0];
48434
+ if (!client)
48435
+ return text("complete_task: not connected", true);
48436
+ await client.completeTask(id, result);
48437
+ return text(`Completed task: ${id}${result ? ` — ${result}` : ""}`);
48438
+ }
48439
+ case "list_tasks": {
48440
+ const { status, assignee } = args ?? {};
48441
+ const client = allClients()[0];
48442
+ if (!client)
48443
+ return text("list_tasks: not connected", true);
48444
+ const tasks = await client.listTasks(status, assignee);
48445
+ if (tasks.length === 0)
48446
+ return text("No tasks found.");
48447
+ const lines = tasks.map((t) => `- [${t.id.slice(0, 8)}…] **${t.title}** (${t.status}, ${t.priority}) ${t.assignee ? `→ ${t.assignee}` : "unassigned"} (by ${t.createdBy})`);
48448
+ return text(`${tasks.length} task(s):
48449
+ ${lines.join(`
48450
+ `)}`);
48451
+ }
48452
+ case "mesh_query": {
48453
+ const { sql: querySql } = args ?? {};
48454
+ if (!querySql)
48455
+ return text("mesh_query: `sql` required", true);
48456
+ const client = allClients()[0];
48457
+ if (!client)
48458
+ return text("mesh_query: not connected", true);
48459
+ const result = await client.meshQuery(querySql);
48460
+ if (!result)
48461
+ return text("mesh_query: query failed or timed out", true);
48462
+ if (result.rows.length === 0)
48463
+ return text(`Query returned 0 rows.`);
48464
+ const header = `| ${result.columns.join(" | ")} |`;
48465
+ const sep = `| ${result.columns.map(() => "---").join(" | ")} |`;
48466
+ const rows = result.rows.map((r) => `| ${result.columns.map((c) => String(r[c] ?? "")).join(" | ")} |`);
48467
+ return text(`${result.rowCount} row(s):
48468
+ ${header}
48469
+ ${sep}
48470
+ ${rows.join(`
48471
+ `)}`);
48472
+ }
48473
+ case "mesh_execute": {
48474
+ const { sql: execSql } = args ?? {};
48475
+ if (!execSql)
48476
+ return text("mesh_execute: `sql` required", true);
48477
+ const client = allClients()[0];
48478
+ if (!client)
48479
+ return text("mesh_execute: not connected", true);
48480
+ await client.meshExecute(execSql);
48481
+ return text(`Executed.`);
48482
+ }
48483
+ case "mesh_schema": {
48484
+ const client = allClients()[0];
48485
+ if (!client)
48486
+ return text("mesh_schema: not connected", true);
48487
+ const tables = await client.meshSchema();
48488
+ if (!tables || tables.length === 0)
48489
+ return text("No tables in mesh database.");
48490
+ const lines = tables.map((t) => `**${t.name}**: ${t.columns.map((c) => `${c.name} (${c.type}${c.nullable ? ", nullable" : ""})`).join(", ")}`);
48491
+ return text(lines.join(`
48492
+ `));
48493
+ }
48494
+ case "create_stream": {
48495
+ const { name: streamName } = args ?? {};
48496
+ if (!streamName)
48497
+ return text("create_stream: `name` required", true);
48498
+ const client = allClients()[0];
48499
+ if (!client)
48500
+ return text("create_stream: not connected", true);
48501
+ const streamId = await client.createStream(streamName);
48502
+ return text(`Stream created: ${streamName}${streamId ? ` (${streamId})` : ""}`);
48503
+ }
48504
+ case "publish": {
48505
+ const { stream: pubStream, data: pubData } = args ?? {};
48506
+ if (!pubStream)
48507
+ return text("publish: `stream` required", true);
48508
+ const client = allClients()[0];
48509
+ if (!client)
48510
+ return text("publish: not connected", true);
48511
+ await client.publish(pubStream, pubData);
48512
+ return text(`Published to ${pubStream}.`);
48513
+ }
48514
+ case "subscribe": {
48515
+ const { stream: subStream } = args ?? {};
48516
+ if (!subStream)
48517
+ return text("subscribe: `stream` required", true);
48518
+ const client = allClients()[0];
48519
+ if (!client)
48520
+ return text("subscribe: not connected", true);
48521
+ await client.subscribe(subStream);
48522
+ return text(`Subscribed to ${subStream}. Data pushes will arrive as channel notifications.`);
48523
+ }
48524
+ case "list_streams": {
48525
+ const client = allClients()[0];
48526
+ if (!client)
48527
+ return text("list_streams: not connected", true);
48528
+ const streams = await client.listStreams();
48529
+ if (streams.length === 0)
48530
+ return text("No active streams.");
48531
+ const lines = streams.map((s) => `- **${s.name}** (${s.id.slice(0, 8)}…) by ${s.createdBy}, ${s.subscriberCount} subscriber(s)`);
48532
+ return text(lines.join(`
48533
+ `));
48534
+ }
48535
+ case "mesh_info": {
48536
+ const client = allClients()[0];
48537
+ if (!client)
48538
+ return text("mesh_info: not connected", true);
48539
+ const info = await client.meshInfo();
48540
+ if (!info)
48541
+ return text("mesh_info: timed out", true);
48542
+ const lines = [
48543
+ `**Mesh**: ${info.mesh}`,
48544
+ `**Peers**: ${info.peers}`,
48545
+ `**Groups**: ${info.groups?.join(", ") || "none"}`,
48546
+ `**State keys**: ${info.stateKeys?.join(", ") || "none"}`,
48547
+ `**Memories**: ${info.memoryCount}`,
48548
+ `**Files**: ${info.fileCount}`,
48549
+ `**Tasks**: open=${info.tasks?.open ?? 0}, claimed=${info.tasks?.claimed ?? 0}, done=${info.tasks?.done ?? 0}`,
48550
+ `**Streams**: ${info.streams?.join(", ") || "none"}`,
48551
+ `**Tables**: ${info.tables?.join(", ") || "none"}`,
48552
+ `**Your name**: ${info.yourName}`,
48553
+ `**Your groups**: ${info.yourGroups?.map((g) => `@${g.name}${g.role ? ":" + g.role : ""}`).join(", ") || "none"}`
48554
+ ];
48555
+ return text(lines.join(`
48556
+ `));
48557
+ }
47625
48558
  default:
47626
48559
  return text(`Unknown tool: ${name}`, true);
47627
48560
  }
@@ -47653,6 +48586,21 @@ ${lines.join(`
47653
48586
  });
47654
48587
  } catch {}
47655
48588
  });
48589
+ client.onStreamData(async (evt) => {
48590
+ try {
48591
+ await server.notification({
48592
+ method: "notifications/claude/channel",
48593
+ params: {
48594
+ content: `[stream:${evt.stream}] from ${evt.publishedBy}: ${JSON.stringify(evt.data)}`,
48595
+ meta: {
48596
+ kind: "stream_data",
48597
+ stream: evt.stream,
48598
+ published_by: evt.publishedBy
48599
+ }
48600
+ }
48601
+ });
48602
+ } catch {}
48603
+ });
47656
48604
  client.onStateChange(async (change) => {
47657
48605
  try {
47658
48606
  await server.notification({
@@ -48553,7 +49501,7 @@ init_config();
48553
49501
  // package.json
48554
49502
  var package_default = {
48555
49503
  name: "claudemesh-cli",
48556
- version: "0.4.0",
49504
+ version: "0.5.0",
48557
49505
  description: "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.",
48558
49506
  keywords: [
48559
49507
  "claude-code",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudemesh-cli",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.",
5
5
  "keywords": [
6
6
  "claude-code",