claudemesh-cli 0.3.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.
- package/dist/index.js +1272 -44
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -46250,8 +46250,11 @@ var TOOLS = [
|
|
|
46250
46250
|
type: "object",
|
|
46251
46251
|
properties: {
|
|
46252
46252
|
to: {
|
|
46253
|
-
|
|
46254
|
-
|
|
46253
|
+
oneOf: [
|
|
46254
|
+
{ type: "string", description: "Peer name, pubkey, @group" },
|
|
46255
|
+
{ type: "array", items: { type: "string" }, description: "Multiple targets" }
|
|
46256
|
+
],
|
|
46257
|
+
description: "Single target or array of targets"
|
|
46255
46258
|
},
|
|
46256
46259
|
message: { type: "string", description: "Message text" },
|
|
46257
46260
|
priority: {
|
|
@@ -46415,6 +46418,333 @@ var TOOLS = [
|
|
|
46415
46418
|
},
|
|
46416
46419
|
required: ["id"]
|
|
46417
46420
|
}
|
|
46421
|
+
},
|
|
46422
|
+
{
|
|
46423
|
+
name: "share_file",
|
|
46424
|
+
description: "Share a persistent file with the mesh. All current and future peers can access it.",
|
|
46425
|
+
inputSchema: {
|
|
46426
|
+
type: "object",
|
|
46427
|
+
properties: {
|
|
46428
|
+
path: { type: "string", description: "Local file path to share" },
|
|
46429
|
+
name: {
|
|
46430
|
+
type: "string",
|
|
46431
|
+
description: "Display name (defaults to filename)"
|
|
46432
|
+
},
|
|
46433
|
+
tags: {
|
|
46434
|
+
type: "array",
|
|
46435
|
+
items: { type: "string" },
|
|
46436
|
+
description: "Tags for categorization"
|
|
46437
|
+
}
|
|
46438
|
+
},
|
|
46439
|
+
required: ["path"]
|
|
46440
|
+
}
|
|
46441
|
+
},
|
|
46442
|
+
{
|
|
46443
|
+
name: "get_file",
|
|
46444
|
+
description: "Download a shared file to a local path.",
|
|
46445
|
+
inputSchema: {
|
|
46446
|
+
type: "object",
|
|
46447
|
+
properties: {
|
|
46448
|
+
id: { type: "string", description: "File ID" },
|
|
46449
|
+
save_to: {
|
|
46450
|
+
type: "string",
|
|
46451
|
+
description: "Local path to save the file"
|
|
46452
|
+
}
|
|
46453
|
+
},
|
|
46454
|
+
required: ["id", "save_to"]
|
|
46455
|
+
}
|
|
46456
|
+
},
|
|
46457
|
+
{
|
|
46458
|
+
name: "list_files",
|
|
46459
|
+
description: "List files shared in the mesh.",
|
|
46460
|
+
inputSchema: {
|
|
46461
|
+
type: "object",
|
|
46462
|
+
properties: {
|
|
46463
|
+
query: { type: "string", description: "Search by name or tags" },
|
|
46464
|
+
from: { type: "string", description: "Filter by uploader name" }
|
|
46465
|
+
}
|
|
46466
|
+
}
|
|
46467
|
+
},
|
|
46468
|
+
{
|
|
46469
|
+
name: "file_status",
|
|
46470
|
+
description: "Check who has accessed a shared file.",
|
|
46471
|
+
inputSchema: {
|
|
46472
|
+
type: "object",
|
|
46473
|
+
properties: {
|
|
46474
|
+
id: { type: "string", description: "File ID" }
|
|
46475
|
+
},
|
|
46476
|
+
required: ["id"]
|
|
46477
|
+
}
|
|
46478
|
+
},
|
|
46479
|
+
{
|
|
46480
|
+
name: "delete_file",
|
|
46481
|
+
description: "Remove a shared file from the mesh.",
|
|
46482
|
+
inputSchema: {
|
|
46483
|
+
type: "object",
|
|
46484
|
+
properties: {
|
|
46485
|
+
id: { type: "string", description: "File ID" }
|
|
46486
|
+
},
|
|
46487
|
+
required: ["id"]
|
|
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: {} }
|
|
46418
46748
|
}
|
|
46419
46749
|
];
|
|
46420
46750
|
|
|
@@ -46719,91 +47049,435 @@ class BrokerClient {
|
|
|
46719
47049
|
return;
|
|
46720
47050
|
this.ws.send(JSON.stringify({ type: "set_state", key, value }));
|
|
46721
47051
|
}
|
|
46722
|
-
async getState(key) {
|
|
47052
|
+
async getState(key) {
|
|
47053
|
+
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47054
|
+
return null;
|
|
47055
|
+
return new Promise((resolve) => {
|
|
47056
|
+
this.stateResolvers.push(resolve);
|
|
47057
|
+
this.ws.send(JSON.stringify({ type: "get_state", key }));
|
|
47058
|
+
setTimeout(() => {
|
|
47059
|
+
const idx = this.stateResolvers.indexOf(resolve);
|
|
47060
|
+
if (idx !== -1) {
|
|
47061
|
+
this.stateResolvers.splice(idx, 1);
|
|
47062
|
+
resolve(null);
|
|
47063
|
+
}
|
|
47064
|
+
}, 5000);
|
|
47065
|
+
});
|
|
47066
|
+
}
|
|
47067
|
+
async listState() {
|
|
47068
|
+
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47069
|
+
return [];
|
|
47070
|
+
return new Promise((resolve) => {
|
|
47071
|
+
this.stateListResolvers.push(resolve);
|
|
47072
|
+
this.ws.send(JSON.stringify({ type: "list_state" }));
|
|
47073
|
+
setTimeout(() => {
|
|
47074
|
+
const idx = this.stateListResolvers.indexOf(resolve);
|
|
47075
|
+
if (idx !== -1) {
|
|
47076
|
+
this.stateListResolvers.splice(idx, 1);
|
|
47077
|
+
resolve([]);
|
|
47078
|
+
}
|
|
47079
|
+
}, 5000);
|
|
47080
|
+
});
|
|
47081
|
+
}
|
|
47082
|
+
async remember(content, tags) {
|
|
47083
|
+
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47084
|
+
return null;
|
|
47085
|
+
return new Promise((resolve) => {
|
|
47086
|
+
this.memoryStoreResolvers.push(resolve);
|
|
47087
|
+
this.ws.send(JSON.stringify({ type: "remember", content, tags }));
|
|
47088
|
+
setTimeout(() => {
|
|
47089
|
+
const idx = this.memoryStoreResolvers.indexOf(resolve);
|
|
47090
|
+
if (idx !== -1) {
|
|
47091
|
+
this.memoryStoreResolvers.splice(idx, 1);
|
|
47092
|
+
resolve(null);
|
|
47093
|
+
}
|
|
47094
|
+
}, 5000);
|
|
47095
|
+
});
|
|
47096
|
+
}
|
|
47097
|
+
async recall(query) {
|
|
47098
|
+
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47099
|
+
return [];
|
|
47100
|
+
return new Promise((resolve) => {
|
|
47101
|
+
this.memoryRecallResolvers.push(resolve);
|
|
47102
|
+
this.ws.send(JSON.stringify({ type: "recall", query }));
|
|
47103
|
+
setTimeout(() => {
|
|
47104
|
+
const idx = this.memoryRecallResolvers.indexOf(resolve);
|
|
47105
|
+
if (idx !== -1) {
|
|
47106
|
+
this.memoryRecallResolvers.splice(idx, 1);
|
|
47107
|
+
resolve([]);
|
|
47108
|
+
}
|
|
47109
|
+
}, 5000);
|
|
47110
|
+
});
|
|
47111
|
+
}
|
|
47112
|
+
async forget(memoryId) {
|
|
47113
|
+
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47114
|
+
return;
|
|
47115
|
+
this.ws.send(JSON.stringify({ type: "forget", memoryId }));
|
|
47116
|
+
}
|
|
47117
|
+
messageStatusResolvers = [];
|
|
47118
|
+
fileUrlResolvers = [];
|
|
47119
|
+
fileListResolvers = [];
|
|
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;
|
|
47134
|
+
async messageStatus(messageId) {
|
|
47135
|
+
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47136
|
+
return null;
|
|
47137
|
+
return new Promise((resolve) => {
|
|
47138
|
+
this.messageStatusResolvers.push(resolve);
|
|
47139
|
+
this.ws.send(JSON.stringify({ type: "message_status", messageId }));
|
|
47140
|
+
setTimeout(() => {
|
|
47141
|
+
const idx = this.messageStatusResolvers.indexOf(resolve);
|
|
47142
|
+
if (idx !== -1) {
|
|
47143
|
+
this.messageStatusResolvers.splice(idx, 1);
|
|
47144
|
+
resolve(null);
|
|
47145
|
+
}
|
|
47146
|
+
}, 5000);
|
|
47147
|
+
});
|
|
47148
|
+
}
|
|
47149
|
+
async getFile(fileId) {
|
|
47150
|
+
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47151
|
+
return null;
|
|
47152
|
+
return new Promise((resolve) => {
|
|
47153
|
+
this.fileUrlResolvers.push(resolve);
|
|
47154
|
+
this.ws.send(JSON.stringify({ type: "get_file", fileId }));
|
|
47155
|
+
setTimeout(() => {
|
|
47156
|
+
const idx = this.fileUrlResolvers.indexOf(resolve);
|
|
47157
|
+
if (idx !== -1) {
|
|
47158
|
+
this.fileUrlResolvers.splice(idx, 1);
|
|
47159
|
+
resolve(null);
|
|
47160
|
+
}
|
|
47161
|
+
}, 5000);
|
|
47162
|
+
});
|
|
47163
|
+
}
|
|
47164
|
+
async listFiles(query, from) {
|
|
47165
|
+
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47166
|
+
return [];
|
|
47167
|
+
return new Promise((resolve) => {
|
|
47168
|
+
this.fileListResolvers.push(resolve);
|
|
47169
|
+
this.ws.send(JSON.stringify({ type: "list_files", query, from }));
|
|
47170
|
+
setTimeout(() => {
|
|
47171
|
+
const idx = this.fileListResolvers.indexOf(resolve);
|
|
47172
|
+
if (idx !== -1) {
|
|
47173
|
+
this.fileListResolvers.splice(idx, 1);
|
|
47174
|
+
resolve([]);
|
|
47175
|
+
}
|
|
47176
|
+
}, 5000);
|
|
47177
|
+
});
|
|
47178
|
+
}
|
|
47179
|
+
async fileStatus(fileId) {
|
|
47180
|
+
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47181
|
+
return [];
|
|
47182
|
+
return new Promise((resolve) => {
|
|
47183
|
+
this.fileStatusResolvers.push(resolve);
|
|
47184
|
+
this.ws.send(JSON.stringify({ type: "file_status", fileId }));
|
|
47185
|
+
setTimeout(() => {
|
|
47186
|
+
const idx = this.fileStatusResolvers.indexOf(resolve);
|
|
47187
|
+
if (idx !== -1) {
|
|
47188
|
+
this.fileStatusResolvers.splice(idx, 1);
|
|
47189
|
+
resolve([]);
|
|
47190
|
+
}
|
|
47191
|
+
}, 5000);
|
|
47192
|
+
});
|
|
47193
|
+
}
|
|
47194
|
+
async deleteFile(fileId) {
|
|
47195
|
+
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47196
|
+
return;
|
|
47197
|
+
this.ws.send(JSON.stringify({ type: "delete_file", fileId }));
|
|
47198
|
+
}
|
|
47199
|
+
async uploadFile(filePath, meshId, memberId, opts) {
|
|
47200
|
+
const { readFileSync: readFileSync2 } = await import("node:fs");
|
|
47201
|
+
const { basename } = await import("node:path");
|
|
47202
|
+
const data = readFileSync2(filePath);
|
|
47203
|
+
const fileName = opts.name ?? basename(filePath);
|
|
47204
|
+
const brokerHttp = this.mesh.brokerUrl.replace("wss://", "https://").replace("ws://", "http://").replace("/ws", "");
|
|
47205
|
+
const res = await fetch(`${brokerHttp}/upload`, {
|
|
47206
|
+
method: "POST",
|
|
47207
|
+
headers: {
|
|
47208
|
+
"Content-Type": "application/octet-stream",
|
|
47209
|
+
"X-Mesh-Id": meshId,
|
|
47210
|
+
"X-Member-Id": memberId,
|
|
47211
|
+
"X-File-Name": fileName,
|
|
47212
|
+
"X-Tags": JSON.stringify(opts.tags ?? []),
|
|
47213
|
+
"X-Persistent": String(opts.persistent ?? true),
|
|
47214
|
+
"X-Target-Spec": opts.targetSpec ?? ""
|
|
47215
|
+
},
|
|
47216
|
+
body: data,
|
|
47217
|
+
signal: AbortSignal.timeout(30000)
|
|
47218
|
+
});
|
|
47219
|
+
const body = await res.json();
|
|
47220
|
+
return body.fileId ?? null;
|
|
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) {
|
|
46723
47378
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
46724
47379
|
return null;
|
|
46725
47380
|
return new Promise((resolve) => {
|
|
46726
|
-
this.
|
|
46727
|
-
this.ws.send(JSON.stringify({ type: "
|
|
47381
|
+
this.meshQueryResolvers.push(resolve);
|
|
47382
|
+
this.ws.send(JSON.stringify({ type: "mesh_query", sql }));
|
|
46728
47383
|
setTimeout(() => {
|
|
46729
|
-
const idx = this.
|
|
47384
|
+
const idx = this.meshQueryResolvers.indexOf(resolve);
|
|
46730
47385
|
if (idx !== -1) {
|
|
46731
|
-
this.
|
|
47386
|
+
this.meshQueryResolvers.splice(idx, 1);
|
|
46732
47387
|
resolve(null);
|
|
46733
47388
|
}
|
|
46734
47389
|
}, 5000);
|
|
46735
47390
|
});
|
|
46736
47391
|
}
|
|
46737
|
-
async
|
|
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() {
|
|
46738
47398
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
46739
47399
|
return [];
|
|
46740
47400
|
return new Promise((resolve) => {
|
|
46741
|
-
this.
|
|
46742
|
-
this.ws.send(JSON.stringify({ type: "
|
|
47401
|
+
this.meshSchemaResolvers.push(resolve);
|
|
47402
|
+
this.ws.send(JSON.stringify({ type: "mesh_schema" }));
|
|
46743
47403
|
setTimeout(() => {
|
|
46744
|
-
const idx = this.
|
|
47404
|
+
const idx = this.meshSchemaResolvers.indexOf(resolve);
|
|
46745
47405
|
if (idx !== -1) {
|
|
46746
|
-
this.
|
|
47406
|
+
this.meshSchemaResolvers.splice(idx, 1);
|
|
46747
47407
|
resolve([]);
|
|
46748
47408
|
}
|
|
46749
47409
|
}, 5000);
|
|
46750
47410
|
});
|
|
46751
47411
|
}
|
|
46752
|
-
async
|
|
47412
|
+
async createStream(name) {
|
|
46753
47413
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
46754
47414
|
return null;
|
|
46755
47415
|
return new Promise((resolve) => {
|
|
46756
|
-
this.
|
|
46757
|
-
this.ws.send(JSON.stringify({ type: "
|
|
47416
|
+
this.streamCreatedResolvers.push(resolve);
|
|
47417
|
+
this.ws.send(JSON.stringify({ type: "create_stream", name }));
|
|
46758
47418
|
setTimeout(() => {
|
|
46759
|
-
const idx = this.
|
|
47419
|
+
const idx = this.streamCreatedResolvers.indexOf(resolve);
|
|
46760
47420
|
if (idx !== -1) {
|
|
46761
|
-
this.
|
|
47421
|
+
this.streamCreatedResolvers.splice(idx, 1);
|
|
46762
47422
|
resolve(null);
|
|
46763
47423
|
}
|
|
46764
47424
|
}, 5000);
|
|
46765
47425
|
});
|
|
46766
47426
|
}
|
|
46767
|
-
async
|
|
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() {
|
|
46768
47443
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
46769
47444
|
return [];
|
|
46770
47445
|
return new Promise((resolve) => {
|
|
46771
|
-
this.
|
|
46772
|
-
this.ws.send(JSON.stringify({ type: "
|
|
47446
|
+
this.streamListResolvers.push(resolve);
|
|
47447
|
+
this.ws.send(JSON.stringify({ type: "list_streams" }));
|
|
46773
47448
|
setTimeout(() => {
|
|
46774
|
-
const idx = this.
|
|
47449
|
+
const idx = this.streamListResolvers.indexOf(resolve);
|
|
46775
47450
|
if (idx !== -1) {
|
|
46776
|
-
this.
|
|
47451
|
+
this.streamListResolvers.splice(idx, 1);
|
|
46777
47452
|
resolve([]);
|
|
46778
47453
|
}
|
|
46779
47454
|
}, 5000);
|
|
46780
47455
|
});
|
|
46781
47456
|
}
|
|
46782
|
-
|
|
46783
|
-
|
|
46784
|
-
|
|
46785
|
-
this.ws.send(JSON.stringify({ type: "forget", memoryId }));
|
|
47457
|
+
onStreamData(handler) {
|
|
47458
|
+
this.streamDataHandlers.add(handler);
|
|
47459
|
+
return () => this.streamDataHandlers.delete(handler);
|
|
46786
47460
|
}
|
|
46787
|
-
|
|
46788
|
-
|
|
47461
|
+
onStateChange(handler) {
|
|
47462
|
+
this.stateChangeHandlers.add(handler);
|
|
47463
|
+
return () => this.stateChangeHandlers.delete(handler);
|
|
47464
|
+
}
|
|
47465
|
+
meshInfoResolvers = [];
|
|
47466
|
+
async meshInfo() {
|
|
46789
47467
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
46790
47468
|
return null;
|
|
46791
47469
|
return new Promise((resolve) => {
|
|
46792
|
-
this.
|
|
46793
|
-
this.ws.send(JSON.stringify({ type: "
|
|
47470
|
+
this.meshInfoResolvers.push(resolve);
|
|
47471
|
+
this.ws.send(JSON.stringify({ type: "mesh_info" }));
|
|
46794
47472
|
setTimeout(() => {
|
|
46795
|
-
const idx = this.
|
|
47473
|
+
const idx = this.meshInfoResolvers.indexOf(resolve);
|
|
46796
47474
|
if (idx !== -1) {
|
|
46797
|
-
this.
|
|
47475
|
+
this.meshInfoResolvers.splice(idx, 1);
|
|
46798
47476
|
resolve(null);
|
|
46799
47477
|
}
|
|
46800
47478
|
}, 5000);
|
|
46801
47479
|
});
|
|
46802
47480
|
}
|
|
46803
|
-
onStateChange(handler) {
|
|
46804
|
-
this.stateChangeHandlers.add(handler);
|
|
46805
|
-
return () => this.stateChangeHandlers.delete(handler);
|
|
46806
|
-
}
|
|
46807
47481
|
close() {
|
|
46808
47482
|
this.closed = true;
|
|
46809
47483
|
if (this.helloTimer)
|
|
@@ -46941,6 +47615,139 @@ class BrokerClient {
|
|
|
46941
47615
|
resolver(msg);
|
|
46942
47616
|
return;
|
|
46943
47617
|
}
|
|
47618
|
+
if (msg.type === "file_url") {
|
|
47619
|
+
const resolver = this.fileUrlResolvers.shift();
|
|
47620
|
+
if (resolver) {
|
|
47621
|
+
if (msg.url) {
|
|
47622
|
+
resolver({ url: String(msg.url), name: String(msg.name ?? "") });
|
|
47623
|
+
} else {
|
|
47624
|
+
resolver(null);
|
|
47625
|
+
}
|
|
47626
|
+
}
|
|
47627
|
+
return;
|
|
47628
|
+
}
|
|
47629
|
+
if (msg.type === "file_list") {
|
|
47630
|
+
const files = msg.files ?? [];
|
|
47631
|
+
const resolver = this.fileListResolvers.shift();
|
|
47632
|
+
if (resolver)
|
|
47633
|
+
resolver(files);
|
|
47634
|
+
return;
|
|
47635
|
+
}
|
|
47636
|
+
if (msg.type === "file_status_result") {
|
|
47637
|
+
const accesses = msg.accesses ?? [];
|
|
47638
|
+
const resolver = this.fileStatusResolvers.shift();
|
|
47639
|
+
if (resolver)
|
|
47640
|
+
resolver(accesses);
|
|
47641
|
+
return;
|
|
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
|
+
}
|
|
46944
47751
|
if (msg.type === "error") {
|
|
46945
47752
|
this.debug(`broker error: ${msg.code} ${msg.message}`);
|
|
46946
47753
|
const id = msg.id ? String(msg.id) : null;
|
|
@@ -47141,9 +47948,44 @@ When you receive a <channel source="claudemesh" ...> message, RESPOND IMMEDIATEL
|
|
|
47141
47948
|
| remember(content, tags?) | Store persistent knowledge with optional tags. |
|
|
47142
47949
|
| recall(query) | Full-text search over mesh memory. |
|
|
47143
47950
|
| forget(id) | Soft-delete a memory entry. |
|
|
47951
|
+
| share_file(path, name?, tags?) | Share a persistent file with the mesh. |
|
|
47952
|
+
| get_file(id, save_to) | Download a shared file to a local path. |
|
|
47953
|
+
| list_files(query?, from?) | Find files shared in the mesh. |
|
|
47954
|
+
| file_status(id) | Check who has accessed a file. |
|
|
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. |
|
|
47144
47976
|
|
|
47145
47977
|
If multiple meshes are joined, prefix \`to\` with \`<mesh-slug>:\` to disambiguate (e.g. \`dev-team:Alice\`).
|
|
47146
47978
|
|
|
47979
|
+
Multi-target: send_message accepts an array of targets for the 'to' field.
|
|
47980
|
+
send_message(to: ["Alice", "@backend"], message: "sprint starts")
|
|
47981
|
+
Targets are deduplicated — each peer receives the message once.
|
|
47982
|
+
|
|
47983
|
+
Targeted views: when different audiences need different details about the same event,
|
|
47984
|
+
send tailored messages instead of one generic broadcast:
|
|
47985
|
+
send_message(to: "@frontend", message: "Auth v2: useAuth hook changed, see src/auth/")
|
|
47986
|
+
send_message(to: "@backend", message: "Auth v2: new /api/auth/v2 endpoints, v1 deprecated")
|
|
47987
|
+
send_message(to: "@pm", message: "Auth v2 done. 3 points, no blockers.")
|
|
47988
|
+
|
|
47147
47989
|
## Groups
|
|
47148
47990
|
Groups are routing labels. Send to @groupname to multicast to all members. Roles are metadata that peers interpret: a "lead" gathers input before synthesizing a response, a "member" contributes when asked, an "observer" watches silently. Join and leave groups dynamically with join_group/leave_group. Check list_peers to see who belongs to which groups and their roles.
|
|
47149
47991
|
|
|
@@ -47153,6 +47995,28 @@ Shared key-value store scoped to the mesh. Use get_state/set_state for live coor
|
|
|
47153
47995
|
## Memory
|
|
47154
47996
|
Persistent knowledge that survives across sessions. Use remember(content, tags?) to store lessons, decisions, and incidents. Use recall(query) to search before asking peers. New peers should recall at session start to load institutional knowledge.
|
|
47155
47997
|
|
|
47998
|
+
## Files
|
|
47999
|
+
share_file for persistent references, send_message(file:) for ephemeral attachments.
|
|
48000
|
+
Tags on shared files make them searchable. Use list_files to find what peers shared.
|
|
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
|
+
|
|
47156
48020
|
## Priority
|
|
47157
48021
|
- "now": interrupt immediately, even if recipient is in DND (use for urgent: broken deploy, blocking issue)
|
|
47158
48022
|
- "next" (default): deliver when recipient goes idle (normal coordination)
|
|
@@ -47174,13 +48038,27 @@ Call list_peers at session start to understand who is online, their roles, and w
|
|
|
47174
48038
|
const { to, message, priority } = args ?? {};
|
|
47175
48039
|
if (!to || !message)
|
|
47176
48040
|
return text("send_message: `to` and `message` required", true);
|
|
47177
|
-
const
|
|
47178
|
-
|
|
47179
|
-
|
|
47180
|
-
|
|
47181
|
-
|
|
47182
|
-
|
|
47183
|
-
|
|
48041
|
+
const targets = Array.isArray(to) ? to : [to];
|
|
48042
|
+
const results = [];
|
|
48043
|
+
const seen = new Set;
|
|
48044
|
+
for (const target of targets) {
|
|
48045
|
+
const { client, targetSpec, error: error2 } = await resolveClient(target);
|
|
48046
|
+
if (!client) {
|
|
48047
|
+
results.push(`✗ ${target}: ${error2 ?? "no client resolved"}`);
|
|
48048
|
+
continue;
|
|
48049
|
+
}
|
|
48050
|
+
if (seen.has(targetSpec))
|
|
48051
|
+
continue;
|
|
48052
|
+
seen.add(targetSpec);
|
|
48053
|
+
const result = await client.send(targetSpec, message, priority ?? "next");
|
|
48054
|
+
if (!result.ok) {
|
|
48055
|
+
results.push(`✗ ${target}: ${result.error}`);
|
|
48056
|
+
} else {
|
|
48057
|
+
results.push(`✓ ${target} → ${result.messageId}`);
|
|
48058
|
+
}
|
|
48059
|
+
}
|
|
48060
|
+
return text(results.join(`
|
|
48061
|
+
`));
|
|
47184
48062
|
}
|
|
47185
48063
|
case "list_peers": {
|
|
47186
48064
|
const { mesh_slug } = args ?? {};
|
|
@@ -47342,6 +48220,341 @@ ${lines.join(`
|
|
|
47342
48220
|
await client.forget(id);
|
|
47343
48221
|
return text(`Forgotten: ${id}`);
|
|
47344
48222
|
}
|
|
48223
|
+
case "share_file": {
|
|
48224
|
+
const { path: filePath, name: fileName, tags } = args ?? {};
|
|
48225
|
+
if (!filePath)
|
|
48226
|
+
return text("share_file: `path` required", true);
|
|
48227
|
+
const { existsSync: existsSync2 } = await import("node:fs");
|
|
48228
|
+
if (!existsSync2(filePath))
|
|
48229
|
+
return text(`share_file: file not found: ${filePath}`, true);
|
|
48230
|
+
const client = allClients()[0];
|
|
48231
|
+
if (!client)
|
|
48232
|
+
return text("share_file: not connected", true);
|
|
48233
|
+
const fileId = await client.uploadFile(filePath, client.meshId, client.meshSlug, {
|
|
48234
|
+
name: fileName,
|
|
48235
|
+
tags,
|
|
48236
|
+
persistent: true
|
|
48237
|
+
});
|
|
48238
|
+
if (!fileId)
|
|
48239
|
+
return text("share_file: upload failed", true);
|
|
48240
|
+
return text(`Shared: ${fileName ?? filePath} (${fileId})`);
|
|
48241
|
+
}
|
|
48242
|
+
case "get_file": {
|
|
48243
|
+
const { id, save_to } = args ?? {};
|
|
48244
|
+
if (!id || !save_to)
|
|
48245
|
+
return text("get_file: `id` and `save_to` required", true);
|
|
48246
|
+
const client = allClients()[0];
|
|
48247
|
+
if (!client)
|
|
48248
|
+
return text("get_file: not connected", true);
|
|
48249
|
+
const result = await client.getFile(id);
|
|
48250
|
+
if (!result)
|
|
48251
|
+
return text(`get_file: file ${id} not found`, true);
|
|
48252
|
+
const res = await fetch(result.url, { signal: AbortSignal.timeout(30000) });
|
|
48253
|
+
if (!res.ok)
|
|
48254
|
+
return text(`get_file: download failed (${res.status})`, true);
|
|
48255
|
+
const { writeFileSync: writeFileSync2, mkdirSync: mkdirSync2 } = await import("node:fs");
|
|
48256
|
+
const { dirname: dirname2 } = await import("node:path");
|
|
48257
|
+
mkdirSync2(dirname2(save_to), { recursive: true });
|
|
48258
|
+
writeFileSync2(save_to, Buffer.from(await res.arrayBuffer()));
|
|
48259
|
+
return text(`Downloaded: ${result.name} → ${save_to}`);
|
|
48260
|
+
}
|
|
48261
|
+
case "list_files": {
|
|
48262
|
+
const { query, from } = args ?? {};
|
|
48263
|
+
const client = allClients()[0];
|
|
48264
|
+
if (!client)
|
|
48265
|
+
return text("list_files: not connected", true);
|
|
48266
|
+
const files = await client.listFiles(query, from);
|
|
48267
|
+
if (files.length === 0)
|
|
48268
|
+
return text("No files found.");
|
|
48269
|
+
const lines = files.map((f) => `- **${f.name}** (${f.id.slice(0, 8)}…, ${f.size} bytes) by ${f.uploadedBy}${f.tags.length ? ` [${f.tags.join(", ")}]` : ""}`);
|
|
48270
|
+
return text(lines.join(`
|
|
48271
|
+
`));
|
|
48272
|
+
}
|
|
48273
|
+
case "file_status": {
|
|
48274
|
+
const { id } = args ?? {};
|
|
48275
|
+
if (!id)
|
|
48276
|
+
return text("file_status: `id` required", true);
|
|
48277
|
+
const client = allClients()[0];
|
|
48278
|
+
if (!client)
|
|
48279
|
+
return text("file_status: not connected", true);
|
|
48280
|
+
const accesses = await client.fileStatus(id);
|
|
48281
|
+
if (accesses.length === 0)
|
|
48282
|
+
return text("No one has accessed this file yet.");
|
|
48283
|
+
const lines = accesses.map((a) => `- ${a.peerName} at ${a.accessedAt}`);
|
|
48284
|
+
return text(`Accessed by:
|
|
48285
|
+
${lines.join(`
|
|
48286
|
+
`)}`);
|
|
48287
|
+
}
|
|
48288
|
+
case "delete_file": {
|
|
48289
|
+
const { id } = args ?? {};
|
|
48290
|
+
if (!id)
|
|
48291
|
+
return text("delete_file: `id` required", true);
|
|
48292
|
+
const client = allClients()[0];
|
|
48293
|
+
if (!client)
|
|
48294
|
+
return text("delete_file: not connected", true);
|
|
48295
|
+
await client.deleteFile(id);
|
|
48296
|
+
return text(`Deleted: ${id}`);
|
|
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
|
+
}
|
|
47345
48558
|
default:
|
|
47346
48559
|
return text(`Unknown tool: ${name}`, true);
|
|
47347
48560
|
}
|
|
@@ -47373,6 +48586,21 @@ ${lines.join(`
|
|
|
47373
48586
|
});
|
|
47374
48587
|
} catch {}
|
|
47375
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
|
+
});
|
|
47376
48604
|
client.onStateChange(async (change) => {
|
|
47377
48605
|
try {
|
|
47378
48606
|
await server.notification({
|
|
@@ -48273,7 +49501,7 @@ init_config();
|
|
|
48273
49501
|
// package.json
|
|
48274
49502
|
var package_default = {
|
|
48275
49503
|
name: "claudemesh-cli",
|
|
48276
|
-
version: "0.
|
|
49504
|
+
version: "0.5.0",
|
|
48277
49505
|
description: "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.",
|
|
48278
49506
|
keywords: [
|
|
48279
49507
|
"claude-code",
|