claudemesh-cli 0.6.5 → 0.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +805 -493
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -47374,6 +47374,49 @@ var TOOLS = [
|
|
|
47374
47374
|
}
|
|
47375
47375
|
}
|
|
47376
47376
|
},
|
|
47377
|
+
{
|
|
47378
|
+
name: "schedule_reminder",
|
|
47379
|
+
description: "Schedule a reminder message delivered back to yourself at a future time. The broker fires it as a push when the time arrives. Use to prompt yourself to check on something later.",
|
|
47380
|
+
inputSchema: {
|
|
47381
|
+
type: "object",
|
|
47382
|
+
properties: {
|
|
47383
|
+
message: { type: "string", description: "Reminder text" },
|
|
47384
|
+
deliver_at: { type: "number", description: "Unix timestamp (ms) when to deliver" },
|
|
47385
|
+
in_seconds: { type: "number", description: "Alternative to deliver_at: fire after N seconds" }
|
|
47386
|
+
},
|
|
47387
|
+
required: ["message"]
|
|
47388
|
+
}
|
|
47389
|
+
},
|
|
47390
|
+
{
|
|
47391
|
+
name: "send_later",
|
|
47392
|
+
description: "Send a message to a peer, @group, or broadcast (*) at a future time. The broker holds it and delivers when the time arrives.",
|
|
47393
|
+
inputSchema: {
|
|
47394
|
+
type: "object",
|
|
47395
|
+
properties: {
|
|
47396
|
+
to: { type: "string", description: "Recipient: display name, pubkey hex, @group, or *" },
|
|
47397
|
+
message: { type: "string", description: "Message text" },
|
|
47398
|
+
deliver_at: { type: "number", description: "Unix timestamp (ms) when to deliver" },
|
|
47399
|
+
in_seconds: { type: "number", description: "Alternative to deliver_at: fire after N seconds" }
|
|
47400
|
+
},
|
|
47401
|
+
required: ["to", "message"]
|
|
47402
|
+
}
|
|
47403
|
+
},
|
|
47404
|
+
{
|
|
47405
|
+
name: "list_scheduled",
|
|
47406
|
+
description: "List all your pending scheduled messages: id, recipient, preview, and delivery time.",
|
|
47407
|
+
inputSchema: { type: "object", properties: {} }
|
|
47408
|
+
},
|
|
47409
|
+
{
|
|
47410
|
+
name: "cancel_scheduled",
|
|
47411
|
+
description: "Cancel a pending scheduled message before it fires.",
|
|
47412
|
+
inputSchema: {
|
|
47413
|
+
type: "object",
|
|
47414
|
+
properties: {
|
|
47415
|
+
id: { type: "string", description: "Scheduled message ID" }
|
|
47416
|
+
},
|
|
47417
|
+
required: ["id"]
|
|
47418
|
+
}
|
|
47419
|
+
},
|
|
47377
47420
|
{
|
|
47378
47421
|
name: "mesh_info",
|
|
47379
47422
|
description: "Get a complete overview of the mesh: peers, groups, state, memory, files, tasks, streams, tables. Call on session start for full situational awareness.",
|
|
@@ -47468,15 +47511,15 @@ class BrokerClient {
|
|
|
47468
47511
|
outbound = [];
|
|
47469
47512
|
pushHandlers = new Set;
|
|
47470
47513
|
pushBuffer = [];
|
|
47471
|
-
listPeersResolvers =
|
|
47472
|
-
stateResolvers =
|
|
47473
|
-
stateListResolvers =
|
|
47474
|
-
memoryStoreResolvers =
|
|
47475
|
-
memoryRecallResolvers =
|
|
47514
|
+
listPeersResolvers = new Map;
|
|
47515
|
+
stateResolvers = new Map;
|
|
47516
|
+
stateListResolvers = new Map;
|
|
47517
|
+
memoryStoreResolvers = new Map;
|
|
47518
|
+
memoryRecallResolvers = new Map;
|
|
47476
47519
|
stateChangeHandlers = new Set;
|
|
47477
47520
|
sessionPubkey = null;
|
|
47478
47521
|
sessionSecretKey = null;
|
|
47479
|
-
grantFileAccessResolvers =
|
|
47522
|
+
grantFileAccessResolvers = new Map;
|
|
47480
47523
|
closed = false;
|
|
47481
47524
|
reconnectAttempt = 0;
|
|
47482
47525
|
helloTimer = null;
|
|
@@ -47503,6 +47546,9 @@ class BrokerClient {
|
|
|
47503
47546
|
getSessionSecretKey() {
|
|
47504
47547
|
return this.sessionSecretKey;
|
|
47505
47548
|
}
|
|
47549
|
+
makeReqId() {
|
|
47550
|
+
return Math.random().toString(36).slice(2) + Date.now().toString(36);
|
|
47551
|
+
}
|
|
47506
47552
|
async connect() {
|
|
47507
47553
|
if (this.closed)
|
|
47508
47554
|
throw new Error("client is closed");
|
|
@@ -47656,15 +47702,12 @@ class BrokerClient {
|
|
|
47656
47702
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47657
47703
|
return [];
|
|
47658
47704
|
return new Promise((resolve) => {
|
|
47659
|
-
this.
|
|
47660
|
-
this.
|
|
47661
|
-
|
|
47662
|
-
const idx = this.listPeersResolvers.indexOf(resolve);
|
|
47663
|
-
if (idx !== -1) {
|
|
47664
|
-
this.listPeersResolvers.splice(idx, 1);
|
|
47705
|
+
const reqId = this.makeReqId();
|
|
47706
|
+
this.listPeersResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
47707
|
+
if (this.listPeersResolvers.delete(reqId))
|
|
47665
47708
|
resolve([]);
|
|
47666
|
-
|
|
47667
|
-
|
|
47709
|
+
}, 5000) });
|
|
47710
|
+
this.ws.send(JSON.stringify({ type: "list_peers", _reqId: reqId }));
|
|
47668
47711
|
});
|
|
47669
47712
|
}
|
|
47670
47713
|
async setSummary(summary) {
|
|
@@ -47691,60 +47734,48 @@ class BrokerClient {
|
|
|
47691
47734
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47692
47735
|
return null;
|
|
47693
47736
|
return new Promise((resolve) => {
|
|
47694
|
-
this.
|
|
47695
|
-
this.
|
|
47696
|
-
|
|
47697
|
-
const idx = this.stateResolvers.indexOf(resolve);
|
|
47698
|
-
if (idx !== -1) {
|
|
47699
|
-
this.stateResolvers.splice(idx, 1);
|
|
47737
|
+
const reqId = this.makeReqId();
|
|
47738
|
+
this.stateResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
47739
|
+
if (this.stateResolvers.delete(reqId))
|
|
47700
47740
|
resolve(null);
|
|
47701
|
-
|
|
47702
|
-
|
|
47741
|
+
}, 5000) });
|
|
47742
|
+
this.ws.send(JSON.stringify({ type: "get_state", key, _reqId: reqId }));
|
|
47703
47743
|
});
|
|
47704
47744
|
}
|
|
47705
47745
|
async listState() {
|
|
47706
47746
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47707
47747
|
return [];
|
|
47708
47748
|
return new Promise((resolve) => {
|
|
47709
|
-
this.
|
|
47710
|
-
this.
|
|
47711
|
-
|
|
47712
|
-
const idx = this.stateListResolvers.indexOf(resolve);
|
|
47713
|
-
if (idx !== -1) {
|
|
47714
|
-
this.stateListResolvers.splice(idx, 1);
|
|
47749
|
+
const reqId = this.makeReqId();
|
|
47750
|
+
this.stateListResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
47751
|
+
if (this.stateListResolvers.delete(reqId))
|
|
47715
47752
|
resolve([]);
|
|
47716
|
-
|
|
47717
|
-
|
|
47753
|
+
}, 5000) });
|
|
47754
|
+
this.ws.send(JSON.stringify({ type: "list_state", _reqId: reqId }));
|
|
47718
47755
|
});
|
|
47719
47756
|
}
|
|
47720
47757
|
async remember(content, tags) {
|
|
47721
47758
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47722
47759
|
return null;
|
|
47723
47760
|
return new Promise((resolve) => {
|
|
47724
|
-
this.
|
|
47725
|
-
this.
|
|
47726
|
-
|
|
47727
|
-
const idx = this.memoryStoreResolvers.indexOf(resolve);
|
|
47728
|
-
if (idx !== -1) {
|
|
47729
|
-
this.memoryStoreResolvers.splice(idx, 1);
|
|
47761
|
+
const reqId = this.makeReqId();
|
|
47762
|
+
this.memoryStoreResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
47763
|
+
if (this.memoryStoreResolvers.delete(reqId))
|
|
47730
47764
|
resolve(null);
|
|
47731
|
-
|
|
47732
|
-
|
|
47765
|
+
}, 5000) });
|
|
47766
|
+
this.ws.send(JSON.stringify({ type: "remember", content, tags, _reqId: reqId }));
|
|
47733
47767
|
});
|
|
47734
47768
|
}
|
|
47735
47769
|
async recall(query) {
|
|
47736
47770
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47737
47771
|
return [];
|
|
47738
47772
|
return new Promise((resolve) => {
|
|
47739
|
-
this.
|
|
47740
|
-
this.
|
|
47741
|
-
|
|
47742
|
-
const idx = this.memoryRecallResolvers.indexOf(resolve);
|
|
47743
|
-
if (idx !== -1) {
|
|
47744
|
-
this.memoryRecallResolvers.splice(idx, 1);
|
|
47773
|
+
const reqId = this.makeReqId();
|
|
47774
|
+
this.memoryRecallResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
47775
|
+
if (this.memoryRecallResolvers.delete(reqId))
|
|
47745
47776
|
resolve([]);
|
|
47746
|
-
|
|
47747
|
-
|
|
47777
|
+
}, 5000) });
|
|
47778
|
+
this.ws.send(JSON.stringify({ type: "recall", query, _reqId: reqId }));
|
|
47748
47779
|
});
|
|
47749
47780
|
}
|
|
47750
47781
|
async forget(memoryId) {
|
|
@@ -47752,81 +47783,108 @@ class BrokerClient {
|
|
|
47752
47783
|
return;
|
|
47753
47784
|
this.ws.send(JSON.stringify({ type: "forget", memoryId }));
|
|
47754
47785
|
}
|
|
47755
|
-
|
|
47756
|
-
|
|
47757
|
-
|
|
47758
|
-
|
|
47759
|
-
|
|
47760
|
-
|
|
47761
|
-
|
|
47762
|
-
|
|
47763
|
-
|
|
47764
|
-
|
|
47765
|
-
|
|
47766
|
-
|
|
47767
|
-
|
|
47768
|
-
|
|
47769
|
-
|
|
47770
|
-
|
|
47786
|
+
async scheduleMessage(to, message, deliverAt) {
|
|
47787
|
+
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47788
|
+
return null;
|
|
47789
|
+
return new Promise((resolve) => {
|
|
47790
|
+
const reqId = this.makeReqId();
|
|
47791
|
+
this.scheduledAckResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
47792
|
+
if (this.scheduledAckResolvers.delete(reqId))
|
|
47793
|
+
resolve(null);
|
|
47794
|
+
}, 8000) });
|
|
47795
|
+
this.ws.send(JSON.stringify({ type: "schedule", to, message, deliverAt, _reqId: reqId }));
|
|
47796
|
+
});
|
|
47797
|
+
}
|
|
47798
|
+
async listScheduled() {
|
|
47799
|
+
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47800
|
+
return [];
|
|
47801
|
+
return new Promise((resolve) => {
|
|
47802
|
+
const reqId = this.makeReqId();
|
|
47803
|
+
this.scheduledListResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
47804
|
+
if (this.scheduledListResolvers.delete(reqId))
|
|
47805
|
+
resolve([]);
|
|
47806
|
+
}, 5000) });
|
|
47807
|
+
this.ws.send(JSON.stringify({ type: "list_scheduled", _reqId: reqId }));
|
|
47808
|
+
});
|
|
47809
|
+
}
|
|
47810
|
+
async cancelScheduled(scheduledId) {
|
|
47811
|
+
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47812
|
+
return false;
|
|
47813
|
+
return new Promise((resolve) => {
|
|
47814
|
+
const reqId = this.makeReqId();
|
|
47815
|
+
this.cancelScheduledResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
47816
|
+
if (this.cancelScheduledResolvers.delete(reqId))
|
|
47817
|
+
resolve(false);
|
|
47818
|
+
}, 5000) });
|
|
47819
|
+
this.ws.send(JSON.stringify({ type: "cancel_scheduled", scheduledId, _reqId: reqId }));
|
|
47820
|
+
});
|
|
47821
|
+
}
|
|
47822
|
+
messageStatusResolvers = new Map;
|
|
47823
|
+
fileUrlResolvers = new Map;
|
|
47824
|
+
fileListResolvers = new Map;
|
|
47825
|
+
fileStatusResolvers = new Map;
|
|
47826
|
+
vectorStoredResolvers = new Map;
|
|
47827
|
+
vectorResultsResolvers = new Map;
|
|
47828
|
+
collectionListResolvers = new Map;
|
|
47829
|
+
graphResultResolvers = new Map;
|
|
47830
|
+
contextListResolvers = new Map;
|
|
47831
|
+
contextResultsResolvers = new Map;
|
|
47832
|
+
taskCreatedResolvers = new Map;
|
|
47833
|
+
taskListResolvers = new Map;
|
|
47834
|
+
meshQueryResolvers = new Map;
|
|
47835
|
+
meshSchemaResolvers = new Map;
|
|
47836
|
+
streamCreatedResolvers = new Map;
|
|
47837
|
+
streamListResolvers = new Map;
|
|
47771
47838
|
streamDataHandlers = new Set;
|
|
47839
|
+
scheduledAckResolvers = new Map;
|
|
47840
|
+
scheduledListResolvers = new Map;
|
|
47841
|
+
cancelScheduledResolvers = new Map;
|
|
47772
47842
|
async messageStatus(messageId) {
|
|
47773
47843
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47774
47844
|
return null;
|
|
47775
47845
|
return new Promise((resolve) => {
|
|
47776
|
-
this.
|
|
47777
|
-
this.
|
|
47778
|
-
|
|
47779
|
-
const idx = this.messageStatusResolvers.indexOf(resolve);
|
|
47780
|
-
if (idx !== -1) {
|
|
47781
|
-
this.messageStatusResolvers.splice(idx, 1);
|
|
47846
|
+
const reqId = this.makeReqId();
|
|
47847
|
+
this.messageStatusResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
47848
|
+
if (this.messageStatusResolvers.delete(reqId))
|
|
47782
47849
|
resolve(null);
|
|
47783
|
-
|
|
47784
|
-
|
|
47850
|
+
}, 5000) });
|
|
47851
|
+
this.ws.send(JSON.stringify({ type: "message_status", messageId, _reqId: reqId }));
|
|
47785
47852
|
});
|
|
47786
47853
|
}
|
|
47787
47854
|
async getFile(fileId) {
|
|
47788
47855
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47789
47856
|
return null;
|
|
47790
47857
|
return new Promise((resolve) => {
|
|
47791
|
-
this.
|
|
47792
|
-
this.
|
|
47793
|
-
|
|
47794
|
-
const idx = this.fileUrlResolvers.indexOf(resolve);
|
|
47795
|
-
if (idx !== -1) {
|
|
47796
|
-
this.fileUrlResolvers.splice(idx, 1);
|
|
47858
|
+
const reqId = this.makeReqId();
|
|
47859
|
+
this.fileUrlResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
47860
|
+
if (this.fileUrlResolvers.delete(reqId))
|
|
47797
47861
|
resolve(null);
|
|
47798
|
-
|
|
47799
|
-
|
|
47862
|
+
}, 5000) });
|
|
47863
|
+
this.ws.send(JSON.stringify({ type: "get_file", fileId, _reqId: reqId }));
|
|
47800
47864
|
});
|
|
47801
47865
|
}
|
|
47802
47866
|
async listFiles(query, from) {
|
|
47803
47867
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47804
47868
|
return [];
|
|
47805
47869
|
return new Promise((resolve) => {
|
|
47806
|
-
this.
|
|
47807
|
-
this.
|
|
47808
|
-
|
|
47809
|
-
const idx = this.fileListResolvers.indexOf(resolve);
|
|
47810
|
-
if (idx !== -1) {
|
|
47811
|
-
this.fileListResolvers.splice(idx, 1);
|
|
47870
|
+
const reqId = this.makeReqId();
|
|
47871
|
+
this.fileListResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
47872
|
+
if (this.fileListResolvers.delete(reqId))
|
|
47812
47873
|
resolve([]);
|
|
47813
|
-
|
|
47814
|
-
|
|
47874
|
+
}, 5000) });
|
|
47875
|
+
this.ws.send(JSON.stringify({ type: "list_files", query, from, _reqId: reqId }));
|
|
47815
47876
|
});
|
|
47816
47877
|
}
|
|
47817
47878
|
async fileStatus(fileId) {
|
|
47818
47879
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47819
47880
|
return [];
|
|
47820
47881
|
return new Promise((resolve) => {
|
|
47821
|
-
this.
|
|
47822
|
-
this.
|
|
47823
|
-
|
|
47824
|
-
const idx = this.fileStatusResolvers.indexOf(resolve);
|
|
47825
|
-
if (idx !== -1) {
|
|
47826
|
-
this.fileStatusResolvers.splice(idx, 1);
|
|
47882
|
+
const reqId = this.makeReqId();
|
|
47883
|
+
this.fileStatusResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
47884
|
+
if (this.fileStatusResolvers.delete(reqId))
|
|
47827
47885
|
resolve([]);
|
|
47828
|
-
|
|
47829
|
-
|
|
47886
|
+
}, 5000) });
|
|
47887
|
+
this.ws.send(JSON.stringify({ type: "file_status", fileId, _reqId: reqId }));
|
|
47830
47888
|
});
|
|
47831
47889
|
}
|
|
47832
47890
|
async deleteFile(fileId) {
|
|
@@ -47867,46 +47925,36 @@ class BrokerClient {
|
|
|
47867
47925
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47868
47926
|
return false;
|
|
47869
47927
|
return new Promise((resolve) => {
|
|
47870
|
-
const
|
|
47871
|
-
|
|
47872
|
-
|
|
47873
|
-
setTimeout(() => {
|
|
47874
|
-
const idx = resolvers.indexOf(resolve);
|
|
47875
|
-
if (idx !== -1) {
|
|
47876
|
-
resolvers.splice(idx, 1);
|
|
47928
|
+
const reqId = this.makeReqId();
|
|
47929
|
+
this.grantFileAccessResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
47930
|
+
if (this.grantFileAccessResolvers.delete(reqId))
|
|
47877
47931
|
resolve(false);
|
|
47878
|
-
|
|
47879
|
-
|
|
47932
|
+
}, 5000) });
|
|
47933
|
+
this.ws.send(JSON.stringify({ type: "grant_file_access", fileId, peerPubkey, sealedKey, _reqId: reqId }));
|
|
47880
47934
|
});
|
|
47881
47935
|
}
|
|
47882
47936
|
async vectorStore(collection, text, metadata) {
|
|
47883
47937
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47884
47938
|
return null;
|
|
47885
47939
|
return new Promise((resolve) => {
|
|
47886
|
-
this.
|
|
47887
|
-
this.
|
|
47888
|
-
|
|
47889
|
-
const idx = this.vectorStoredResolvers.indexOf(resolve);
|
|
47890
|
-
if (idx !== -1) {
|
|
47891
|
-
this.vectorStoredResolvers.splice(idx, 1);
|
|
47940
|
+
const reqId = this.makeReqId();
|
|
47941
|
+
this.vectorStoredResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
47942
|
+
if (this.vectorStoredResolvers.delete(reqId))
|
|
47892
47943
|
resolve(null);
|
|
47893
|
-
|
|
47894
|
-
|
|
47944
|
+
}, 5000) });
|
|
47945
|
+
this.ws.send(JSON.stringify({ type: "vector_store", collection, text, metadata, _reqId: reqId }));
|
|
47895
47946
|
});
|
|
47896
47947
|
}
|
|
47897
47948
|
async vectorSearch(collection, query, limit) {
|
|
47898
47949
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47899
47950
|
return [];
|
|
47900
47951
|
return new Promise((resolve) => {
|
|
47901
|
-
this.
|
|
47902
|
-
this.
|
|
47903
|
-
|
|
47904
|
-
const idx = this.vectorResultsResolvers.indexOf(resolve);
|
|
47905
|
-
if (idx !== -1) {
|
|
47906
|
-
this.vectorResultsResolvers.splice(idx, 1);
|
|
47952
|
+
const reqId = this.makeReqId();
|
|
47953
|
+
this.vectorResultsResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
47954
|
+
if (this.vectorResultsResolvers.delete(reqId))
|
|
47907
47955
|
resolve([]);
|
|
47908
|
-
|
|
47909
|
-
|
|
47956
|
+
}, 5000) });
|
|
47957
|
+
this.ws.send(JSON.stringify({ type: "vector_search", collection, query, limit, _reqId: reqId }));
|
|
47910
47958
|
});
|
|
47911
47959
|
}
|
|
47912
47960
|
async vectorDelete(collection, id) {
|
|
@@ -47918,45 +47966,36 @@ class BrokerClient {
|
|
|
47918
47966
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47919
47967
|
return [];
|
|
47920
47968
|
return new Promise((resolve) => {
|
|
47921
|
-
this.
|
|
47922
|
-
this.
|
|
47923
|
-
|
|
47924
|
-
const idx = this.collectionListResolvers.indexOf(resolve);
|
|
47925
|
-
if (idx !== -1) {
|
|
47926
|
-
this.collectionListResolvers.splice(idx, 1);
|
|
47969
|
+
const reqId = this.makeReqId();
|
|
47970
|
+
this.collectionListResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
47971
|
+
if (this.collectionListResolvers.delete(reqId))
|
|
47927
47972
|
resolve([]);
|
|
47928
|
-
|
|
47929
|
-
|
|
47973
|
+
}, 5000) });
|
|
47974
|
+
this.ws.send(JSON.stringify({ type: "list_collections", _reqId: reqId }));
|
|
47930
47975
|
});
|
|
47931
47976
|
}
|
|
47932
47977
|
async graphQuery(cypher) {
|
|
47933
47978
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47934
47979
|
return [];
|
|
47935
47980
|
return new Promise((resolve) => {
|
|
47936
|
-
this.
|
|
47937
|
-
this.
|
|
47938
|
-
|
|
47939
|
-
const idx = this.graphResultResolvers.indexOf(resolve);
|
|
47940
|
-
if (idx !== -1) {
|
|
47941
|
-
this.graphResultResolvers.splice(idx, 1);
|
|
47981
|
+
const reqId = this.makeReqId();
|
|
47982
|
+
this.graphResultResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
47983
|
+
if (this.graphResultResolvers.delete(reqId))
|
|
47942
47984
|
resolve([]);
|
|
47943
|
-
|
|
47944
|
-
|
|
47985
|
+
}, 5000) });
|
|
47986
|
+
this.ws.send(JSON.stringify({ type: "graph_query", cypher, _reqId: reqId }));
|
|
47945
47987
|
});
|
|
47946
47988
|
}
|
|
47947
47989
|
async graphExecute(cypher) {
|
|
47948
47990
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47949
47991
|
return [];
|
|
47950
47992
|
return new Promise((resolve) => {
|
|
47951
|
-
this.
|
|
47952
|
-
this.
|
|
47953
|
-
|
|
47954
|
-
const idx = this.graphResultResolvers.indexOf(resolve);
|
|
47955
|
-
if (idx !== -1) {
|
|
47956
|
-
this.graphResultResolvers.splice(idx, 1);
|
|
47993
|
+
const reqId = this.makeReqId();
|
|
47994
|
+
this.graphResultResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
47995
|
+
if (this.graphResultResolvers.delete(reqId))
|
|
47957
47996
|
resolve([]);
|
|
47958
|
-
|
|
47959
|
-
|
|
47997
|
+
}, 5000) });
|
|
47998
|
+
this.ws.send(JSON.stringify({ type: "graph_execute", cypher, _reqId: reqId }));
|
|
47960
47999
|
});
|
|
47961
48000
|
}
|
|
47962
48001
|
async shareContext(summary, filesRead, keyFindings, tags) {
|
|
@@ -47968,45 +48007,36 @@ class BrokerClient {
|
|
|
47968
48007
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47969
48008
|
return [];
|
|
47970
48009
|
return new Promise((resolve) => {
|
|
47971
|
-
this.
|
|
47972
|
-
this.
|
|
47973
|
-
|
|
47974
|
-
const idx = this.contextResultsResolvers.indexOf(resolve);
|
|
47975
|
-
if (idx !== -1) {
|
|
47976
|
-
this.contextResultsResolvers.splice(idx, 1);
|
|
48010
|
+
const reqId = this.makeReqId();
|
|
48011
|
+
this.contextResultsResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
48012
|
+
if (this.contextResultsResolvers.delete(reqId))
|
|
47977
48013
|
resolve([]);
|
|
47978
|
-
|
|
47979
|
-
|
|
48014
|
+
}, 5000) });
|
|
48015
|
+
this.ws.send(JSON.stringify({ type: "get_context", query, _reqId: reqId }));
|
|
47980
48016
|
});
|
|
47981
48017
|
}
|
|
47982
48018
|
async listContexts() {
|
|
47983
48019
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47984
48020
|
return [];
|
|
47985
48021
|
return new Promise((resolve) => {
|
|
47986
|
-
this.
|
|
47987
|
-
this.
|
|
47988
|
-
|
|
47989
|
-
const idx = this.contextListResolvers.indexOf(resolve);
|
|
47990
|
-
if (idx !== -1) {
|
|
47991
|
-
this.contextListResolvers.splice(idx, 1);
|
|
48022
|
+
const reqId = this.makeReqId();
|
|
48023
|
+
this.contextListResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
48024
|
+
if (this.contextListResolvers.delete(reqId))
|
|
47992
48025
|
resolve([]);
|
|
47993
|
-
|
|
47994
|
-
|
|
48026
|
+
}, 5000) });
|
|
48027
|
+
this.ws.send(JSON.stringify({ type: "list_contexts", _reqId: reqId }));
|
|
47995
48028
|
});
|
|
47996
48029
|
}
|
|
47997
48030
|
async createTask(title, assignee, priority, tags) {
|
|
47998
48031
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
47999
48032
|
return null;
|
|
48000
48033
|
return new Promise((resolve) => {
|
|
48001
|
-
this.
|
|
48002
|
-
this.
|
|
48003
|
-
|
|
48004
|
-
const idx = this.taskCreatedResolvers.indexOf(resolve);
|
|
48005
|
-
if (idx !== -1) {
|
|
48006
|
-
this.taskCreatedResolvers.splice(idx, 1);
|
|
48034
|
+
const reqId = this.makeReqId();
|
|
48035
|
+
this.taskCreatedResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
48036
|
+
if (this.taskCreatedResolvers.delete(reqId))
|
|
48007
48037
|
resolve(null);
|
|
48008
|
-
|
|
48009
|
-
|
|
48038
|
+
}, 5000) });
|
|
48039
|
+
this.ws.send(JSON.stringify({ type: "create_task", title, assignee, priority, tags, _reqId: reqId }));
|
|
48010
48040
|
});
|
|
48011
48041
|
}
|
|
48012
48042
|
async claimTask(id) {
|
|
@@ -48023,30 +48053,24 @@ class BrokerClient {
|
|
|
48023
48053
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
48024
48054
|
return [];
|
|
48025
48055
|
return new Promise((resolve) => {
|
|
48026
|
-
this.
|
|
48027
|
-
this.
|
|
48028
|
-
|
|
48029
|
-
const idx = this.taskListResolvers.indexOf(resolve);
|
|
48030
|
-
if (idx !== -1) {
|
|
48031
|
-
this.taskListResolvers.splice(idx, 1);
|
|
48056
|
+
const reqId = this.makeReqId();
|
|
48057
|
+
this.taskListResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
48058
|
+
if (this.taskListResolvers.delete(reqId))
|
|
48032
48059
|
resolve([]);
|
|
48033
|
-
|
|
48034
|
-
|
|
48060
|
+
}, 5000) });
|
|
48061
|
+
this.ws.send(JSON.stringify({ type: "list_tasks", status, assignee, _reqId: reqId }));
|
|
48035
48062
|
});
|
|
48036
48063
|
}
|
|
48037
48064
|
async meshQuery(sql) {
|
|
48038
48065
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
48039
48066
|
return null;
|
|
48040
48067
|
return new Promise((resolve) => {
|
|
48041
|
-
this.
|
|
48042
|
-
this.
|
|
48043
|
-
|
|
48044
|
-
const idx = this.meshQueryResolvers.indexOf(resolve);
|
|
48045
|
-
if (idx !== -1) {
|
|
48046
|
-
this.meshQueryResolvers.splice(idx, 1);
|
|
48068
|
+
const reqId = this.makeReqId();
|
|
48069
|
+
this.meshQueryResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
48070
|
+
if (this.meshQueryResolvers.delete(reqId))
|
|
48047
48071
|
resolve(null);
|
|
48048
|
-
|
|
48049
|
-
|
|
48072
|
+
}, 5000) });
|
|
48073
|
+
this.ws.send(JSON.stringify({ type: "mesh_query", sql, _reqId: reqId }));
|
|
48050
48074
|
});
|
|
48051
48075
|
}
|
|
48052
48076
|
async meshExecute(sql) {
|
|
@@ -48058,30 +48082,24 @@ class BrokerClient {
|
|
|
48058
48082
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
48059
48083
|
return [];
|
|
48060
48084
|
return new Promise((resolve) => {
|
|
48061
|
-
this.
|
|
48062
|
-
this.
|
|
48063
|
-
|
|
48064
|
-
const idx = this.meshSchemaResolvers.indexOf(resolve);
|
|
48065
|
-
if (idx !== -1) {
|
|
48066
|
-
this.meshSchemaResolvers.splice(idx, 1);
|
|
48085
|
+
const reqId = this.makeReqId();
|
|
48086
|
+
this.meshSchemaResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
48087
|
+
if (this.meshSchemaResolvers.delete(reqId))
|
|
48067
48088
|
resolve([]);
|
|
48068
|
-
|
|
48069
|
-
|
|
48089
|
+
}, 5000) });
|
|
48090
|
+
this.ws.send(JSON.stringify({ type: "mesh_schema", _reqId: reqId }));
|
|
48070
48091
|
});
|
|
48071
48092
|
}
|
|
48072
48093
|
async createStream(name) {
|
|
48073
48094
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
48074
48095
|
return null;
|
|
48075
48096
|
return new Promise((resolve) => {
|
|
48076
|
-
this.
|
|
48077
|
-
this.
|
|
48078
|
-
|
|
48079
|
-
const idx = this.streamCreatedResolvers.indexOf(resolve);
|
|
48080
|
-
if (idx !== -1) {
|
|
48081
|
-
this.streamCreatedResolvers.splice(idx, 1);
|
|
48097
|
+
const reqId = this.makeReqId();
|
|
48098
|
+
this.streamCreatedResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
48099
|
+
if (this.streamCreatedResolvers.delete(reqId))
|
|
48082
48100
|
resolve(null);
|
|
48083
|
-
|
|
48084
|
-
|
|
48101
|
+
}, 5000) });
|
|
48102
|
+
this.ws.send(JSON.stringify({ type: "create_stream", name, _reqId: reqId }));
|
|
48085
48103
|
});
|
|
48086
48104
|
}
|
|
48087
48105
|
async publish(stream, data) {
|
|
@@ -48103,15 +48121,12 @@ class BrokerClient {
|
|
|
48103
48121
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
48104
48122
|
return [];
|
|
48105
48123
|
return new Promise((resolve) => {
|
|
48106
|
-
this.
|
|
48107
|
-
this.
|
|
48108
|
-
|
|
48109
|
-
const idx = this.streamListResolvers.indexOf(resolve);
|
|
48110
|
-
if (idx !== -1) {
|
|
48111
|
-
this.streamListResolvers.splice(idx, 1);
|
|
48124
|
+
const reqId = this.makeReqId();
|
|
48125
|
+
this.streamListResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
48126
|
+
if (this.streamListResolvers.delete(reqId))
|
|
48112
48127
|
resolve([]);
|
|
48113
|
-
|
|
48114
|
-
|
|
48128
|
+
}, 5000) });
|
|
48129
|
+
this.ws.send(JSON.stringify({ type: "list_streams", _reqId: reqId }));
|
|
48115
48130
|
});
|
|
48116
48131
|
}
|
|
48117
48132
|
onStreamData(handler) {
|
|
@@ -48122,20 +48137,17 @@ class BrokerClient {
|
|
|
48122
48137
|
this.stateChangeHandlers.add(handler);
|
|
48123
48138
|
return () => this.stateChangeHandlers.delete(handler);
|
|
48124
48139
|
}
|
|
48125
|
-
meshInfoResolvers =
|
|
48140
|
+
meshInfoResolvers = new Map;
|
|
48126
48141
|
async meshInfo() {
|
|
48127
48142
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN)
|
|
48128
48143
|
return null;
|
|
48129
48144
|
return new Promise((resolve) => {
|
|
48130
|
-
this.
|
|
48131
|
-
this.
|
|
48132
|
-
|
|
48133
|
-
const idx = this.meshInfoResolvers.indexOf(resolve);
|
|
48134
|
-
if (idx !== -1) {
|
|
48135
|
-
this.meshInfoResolvers.splice(idx, 1);
|
|
48145
|
+
const reqId = this.makeReqId();
|
|
48146
|
+
this.meshInfoResolvers.set(reqId, { resolve, timer: setTimeout(() => {
|
|
48147
|
+
if (this.meshInfoResolvers.delete(reqId))
|
|
48136
48148
|
resolve(null);
|
|
48137
|
-
|
|
48138
|
-
|
|
48149
|
+
}, 5000) });
|
|
48150
|
+
this.ws.send(JSON.stringify({ type: "mesh_info", _reqId: reqId }));
|
|
48139
48151
|
});
|
|
48140
48152
|
}
|
|
48141
48153
|
close() {
|
|
@@ -48151,7 +48163,26 @@ class BrokerClient {
|
|
|
48151
48163
|
}
|
|
48152
48164
|
this.setConnStatus("closed");
|
|
48153
48165
|
}
|
|
48166
|
+
resolveFromMap(map2, reqId, value) {
|
|
48167
|
+
let entry = reqId ? map2.get(reqId) : undefined;
|
|
48168
|
+
if (!entry) {
|
|
48169
|
+
const first = map2.entries().next().value;
|
|
48170
|
+
if (first) {
|
|
48171
|
+
entry = first[1];
|
|
48172
|
+
map2.delete(first[0]);
|
|
48173
|
+
}
|
|
48174
|
+
} else {
|
|
48175
|
+
map2.delete(reqId);
|
|
48176
|
+
}
|
|
48177
|
+
if (entry) {
|
|
48178
|
+
clearTimeout(entry.timer);
|
|
48179
|
+
entry.resolve(value);
|
|
48180
|
+
return true;
|
|
48181
|
+
}
|
|
48182
|
+
return false;
|
|
48183
|
+
}
|
|
48154
48184
|
handleServerMessage(msg) {
|
|
48185
|
+
const msgReqId = msg._reqId;
|
|
48155
48186
|
if (msg.type === "ack") {
|
|
48156
48187
|
const pending = this.pendingSends.get(String(msg.id ?? ""));
|
|
48157
48188
|
if (pending) {
|
|
@@ -48165,9 +48196,7 @@ class BrokerClient {
|
|
|
48165
48196
|
}
|
|
48166
48197
|
if (msg.type === "peers_list") {
|
|
48167
48198
|
const peers = msg.peers ?? [];
|
|
48168
|
-
|
|
48169
|
-
if (resolver)
|
|
48170
|
-
resolver(peers);
|
|
48199
|
+
this.resolveFromMap(this.listPeersResolvers, msgReqId, peers);
|
|
48171
48200
|
return;
|
|
48172
48201
|
}
|
|
48173
48202
|
if (msg.type === "push") {
|
|
@@ -48221,26 +48250,21 @@ class BrokerClient {
|
|
|
48221
48250
|
return;
|
|
48222
48251
|
}
|
|
48223
48252
|
if (msg.type === "state_result") {
|
|
48224
|
-
|
|
48225
|
-
|
|
48226
|
-
|
|
48227
|
-
|
|
48228
|
-
|
|
48229
|
-
|
|
48230
|
-
|
|
48231
|
-
|
|
48232
|
-
|
|
48233
|
-
} else {
|
|
48234
|
-
resolver(null);
|
|
48235
|
-
}
|
|
48253
|
+
if (msg.key) {
|
|
48254
|
+
this.resolveFromMap(this.stateResolvers, msgReqId, {
|
|
48255
|
+
key: String(msg.key),
|
|
48256
|
+
value: msg.value,
|
|
48257
|
+
updatedBy: String(msg.updatedBy ?? ""),
|
|
48258
|
+
updatedAt: String(msg.updatedAt ?? "")
|
|
48259
|
+
});
|
|
48260
|
+
} else {
|
|
48261
|
+
this.resolveFromMap(this.stateResolvers, msgReqId, null);
|
|
48236
48262
|
}
|
|
48237
48263
|
return;
|
|
48238
48264
|
}
|
|
48239
48265
|
if (msg.type === "state_list") {
|
|
48240
48266
|
const entries = msg.entries ?? [];
|
|
48241
|
-
|
|
48242
|
-
if (resolver)
|
|
48243
|
-
resolver(entries);
|
|
48267
|
+
this.resolveFromMap(this.stateListResolvers, msgReqId, entries);
|
|
48244
48268
|
return;
|
|
48245
48269
|
}
|
|
48246
48270
|
if (msg.type === "state_change") {
|
|
@@ -48257,147 +48281,107 @@ class BrokerClient {
|
|
|
48257
48281
|
return;
|
|
48258
48282
|
}
|
|
48259
48283
|
if (msg.type === "memory_stored") {
|
|
48260
|
-
|
|
48261
|
-
if (resolver)
|
|
48262
|
-
resolver(msg.id ? String(msg.id) : null);
|
|
48284
|
+
this.resolveFromMap(this.memoryStoreResolvers, msgReqId, msg.id ? String(msg.id) : null);
|
|
48263
48285
|
return;
|
|
48264
48286
|
}
|
|
48265
48287
|
if (msg.type === "memory_results") {
|
|
48266
48288
|
const memories = msg.memories ?? [];
|
|
48267
|
-
|
|
48268
|
-
if (resolver)
|
|
48269
|
-
resolver(memories);
|
|
48289
|
+
this.resolveFromMap(this.memoryRecallResolvers, msgReqId, memories);
|
|
48270
48290
|
return;
|
|
48271
48291
|
}
|
|
48272
48292
|
if (msg.type === "message_status_result") {
|
|
48273
|
-
|
|
48274
|
-
if (resolver)
|
|
48275
|
-
resolver(msg);
|
|
48293
|
+
this.resolveFromMap(this.messageStatusResolvers, msgReqId, msg);
|
|
48276
48294
|
return;
|
|
48277
48295
|
}
|
|
48278
48296
|
if (msg.type === "file_url") {
|
|
48279
|
-
|
|
48280
|
-
|
|
48281
|
-
|
|
48282
|
-
|
|
48283
|
-
|
|
48284
|
-
|
|
48285
|
-
|
|
48286
|
-
|
|
48287
|
-
|
|
48288
|
-
} else {
|
|
48289
|
-
resolver(null);
|
|
48290
|
-
}
|
|
48297
|
+
if (msg.url) {
|
|
48298
|
+
this.resolveFromMap(this.fileUrlResolvers, msgReqId, {
|
|
48299
|
+
url: String(msg.url),
|
|
48300
|
+
name: String(msg.name ?? ""),
|
|
48301
|
+
encrypted: msg.encrypted ? true : undefined,
|
|
48302
|
+
sealedKey: msg.sealedKey ? String(msg.sealedKey) : undefined
|
|
48303
|
+
});
|
|
48304
|
+
} else {
|
|
48305
|
+
this.resolveFromMap(this.fileUrlResolvers, msgReqId, null);
|
|
48291
48306
|
}
|
|
48292
48307
|
return;
|
|
48293
48308
|
}
|
|
48294
48309
|
if (msg.type === "file_list") {
|
|
48295
48310
|
const files = msg.files ?? [];
|
|
48296
|
-
|
|
48297
|
-
if (resolver)
|
|
48298
|
-
resolver(files);
|
|
48311
|
+
this.resolveFromMap(this.fileListResolvers, msgReqId, files);
|
|
48299
48312
|
return;
|
|
48300
48313
|
}
|
|
48301
48314
|
if (msg.type === "file_status_result") {
|
|
48302
48315
|
const accesses = msg.accesses ?? [];
|
|
48303
|
-
|
|
48304
|
-
if (resolver)
|
|
48305
|
-
resolver(accesses);
|
|
48316
|
+
this.resolveFromMap(this.fileStatusResolvers, msgReqId, accesses);
|
|
48306
48317
|
return;
|
|
48307
48318
|
}
|
|
48308
48319
|
if (msg.type === "grant_file_access_ok") {
|
|
48309
|
-
|
|
48310
|
-
if (resolver)
|
|
48311
|
-
resolver(true);
|
|
48320
|
+
this.resolveFromMap(this.grantFileAccessResolvers, msgReqId, true);
|
|
48312
48321
|
return;
|
|
48313
48322
|
}
|
|
48314
48323
|
if (msg.type === "vector_stored") {
|
|
48315
|
-
|
|
48316
|
-
if (resolver)
|
|
48317
|
-
resolver(msg.id ? String(msg.id) : null);
|
|
48324
|
+
this.resolveFromMap(this.vectorStoredResolvers, msgReqId, msg.id ? String(msg.id) : null);
|
|
48318
48325
|
return;
|
|
48319
48326
|
}
|
|
48320
48327
|
if (msg.type === "vector_results") {
|
|
48321
48328
|
const results = msg.results ?? [];
|
|
48322
|
-
|
|
48323
|
-
if (resolver)
|
|
48324
|
-
resolver(results);
|
|
48329
|
+
this.resolveFromMap(this.vectorResultsResolvers, msgReqId, results);
|
|
48325
48330
|
return;
|
|
48326
48331
|
}
|
|
48327
48332
|
if (msg.type === "collection_list") {
|
|
48328
48333
|
const collections = msg.collections ?? [];
|
|
48329
|
-
|
|
48330
|
-
if (resolver)
|
|
48331
|
-
resolver(collections);
|
|
48334
|
+
this.resolveFromMap(this.collectionListResolvers, msgReqId, collections);
|
|
48332
48335
|
return;
|
|
48333
48336
|
}
|
|
48334
48337
|
if (msg.type === "graph_result") {
|
|
48335
48338
|
const rows = msg.records ?? [];
|
|
48336
|
-
|
|
48337
|
-
if (resolver)
|
|
48338
|
-
resolver(rows);
|
|
48339
|
+
this.resolveFromMap(this.graphResultResolvers, msgReqId, rows);
|
|
48339
48340
|
return;
|
|
48340
48341
|
}
|
|
48341
48342
|
if (msg.type === "context_list") {
|
|
48342
48343
|
const contexts = msg.contexts ?? [];
|
|
48343
|
-
|
|
48344
|
-
if (resolver)
|
|
48345
|
-
resolver(contexts);
|
|
48344
|
+
this.resolveFromMap(this.contextListResolvers, msgReqId, contexts);
|
|
48346
48345
|
return;
|
|
48347
48346
|
}
|
|
48348
48347
|
if (msg.type === "context_results") {
|
|
48349
48348
|
const contexts = msg.contexts ?? [];
|
|
48350
|
-
|
|
48351
|
-
if (resolver)
|
|
48352
|
-
resolver(contexts);
|
|
48349
|
+
this.resolveFromMap(this.contextResultsResolvers, msgReqId, contexts);
|
|
48353
48350
|
return;
|
|
48354
48351
|
}
|
|
48355
48352
|
if (msg.type === "task_created") {
|
|
48356
|
-
|
|
48357
|
-
if (resolver)
|
|
48358
|
-
resolver(msg.id ? String(msg.id) : null);
|
|
48353
|
+
this.resolveFromMap(this.taskCreatedResolvers, msgReqId, msg.id ? String(msg.id) : null);
|
|
48359
48354
|
return;
|
|
48360
48355
|
}
|
|
48361
48356
|
if (msg.type === "task_list") {
|
|
48362
48357
|
const tasks = msg.tasks ?? [];
|
|
48363
|
-
|
|
48364
|
-
if (resolver)
|
|
48365
|
-
resolver(tasks);
|
|
48358
|
+
this.resolveFromMap(this.taskListResolvers, msgReqId, tasks);
|
|
48366
48359
|
return;
|
|
48367
48360
|
}
|
|
48368
48361
|
if (msg.type === "mesh_query_result") {
|
|
48369
|
-
|
|
48370
|
-
|
|
48371
|
-
|
|
48372
|
-
|
|
48373
|
-
|
|
48374
|
-
|
|
48375
|
-
|
|
48376
|
-
|
|
48377
|
-
} else {
|
|
48378
|
-
resolver(null);
|
|
48379
|
-
}
|
|
48362
|
+
if (msg.columns) {
|
|
48363
|
+
this.resolveFromMap(this.meshQueryResolvers, msgReqId, {
|
|
48364
|
+
columns: msg.columns ?? [],
|
|
48365
|
+
rows: msg.rows ?? [],
|
|
48366
|
+
rowCount: msg.rowCount ?? 0
|
|
48367
|
+
});
|
|
48368
|
+
} else {
|
|
48369
|
+
this.resolveFromMap(this.meshQueryResolvers, msgReqId, null);
|
|
48380
48370
|
}
|
|
48381
48371
|
return;
|
|
48382
48372
|
}
|
|
48383
48373
|
if (msg.type === "mesh_schema_result") {
|
|
48384
48374
|
const tables = msg.tables ?? [];
|
|
48385
|
-
|
|
48386
|
-
if (resolver)
|
|
48387
|
-
resolver(tables);
|
|
48375
|
+
this.resolveFromMap(this.meshSchemaResolvers, msgReqId, tables);
|
|
48388
48376
|
return;
|
|
48389
48377
|
}
|
|
48390
48378
|
if (msg.type === "stream_created") {
|
|
48391
|
-
|
|
48392
|
-
if (resolver)
|
|
48393
|
-
resolver(msg.id ? String(msg.id) : null);
|
|
48379
|
+
this.resolveFromMap(this.streamCreatedResolvers, msgReqId, msg.id ? String(msg.id) : null);
|
|
48394
48380
|
return;
|
|
48395
48381
|
}
|
|
48396
48382
|
if (msg.type === "stream_list") {
|
|
48397
48383
|
const streams = msg.streams ?? [];
|
|
48398
|
-
|
|
48399
|
-
if (resolver)
|
|
48400
|
-
resolver(streams);
|
|
48384
|
+
this.resolveFromMap(this.streamListResolvers, msgReqId, streams);
|
|
48401
48385
|
return;
|
|
48402
48386
|
}
|
|
48403
48387
|
if (msg.type === "stream_data") {
|
|
@@ -48414,9 +48398,23 @@ class BrokerClient {
|
|
|
48414
48398
|
return;
|
|
48415
48399
|
}
|
|
48416
48400
|
if (msg.type === "mesh_info_result") {
|
|
48417
|
-
|
|
48418
|
-
|
|
48419
|
-
|
|
48401
|
+
this.resolveFromMap(this.meshInfoResolvers, msgReqId, msg);
|
|
48402
|
+
return;
|
|
48403
|
+
}
|
|
48404
|
+
if (msg.type === "scheduled_ack") {
|
|
48405
|
+
this.resolveFromMap(this.scheduledAckResolvers, msgReqId, {
|
|
48406
|
+
scheduledId: String(msg.scheduledId ?? ""),
|
|
48407
|
+
deliverAt: Number(msg.deliverAt ?? 0)
|
|
48408
|
+
});
|
|
48409
|
+
return;
|
|
48410
|
+
}
|
|
48411
|
+
if (msg.type === "scheduled_list") {
|
|
48412
|
+
const messages = msg.messages ?? [];
|
|
48413
|
+
this.resolveFromMap(this.scheduledListResolvers, msgReqId, messages);
|
|
48414
|
+
return;
|
|
48415
|
+
}
|
|
48416
|
+
if (msg.type === "cancel_scheduled_ack") {
|
|
48417
|
+
this.resolveFromMap(this.cancelScheduledResolvers, msgReqId, Boolean(msg.ok));
|
|
48420
48418
|
return;
|
|
48421
48419
|
}
|
|
48422
48420
|
if (msg.type === "error") {
|
|
@@ -48435,36 +48433,42 @@ class BrokerClient {
|
|
|
48435
48433
|
}
|
|
48436
48434
|
}
|
|
48437
48435
|
if (!handledByPendingSend) {
|
|
48438
|
-
|
|
48439
|
-
this.stateResolvers
|
|
48440
|
-
|
|
48441
|
-
this.
|
|
48442
|
-
|
|
48443
|
-
this.
|
|
48444
|
-
|
|
48445
|
-
this.
|
|
48446
|
-
|
|
48447
|
-
this.
|
|
48448
|
-
|
|
48449
|
-
this.
|
|
48450
|
-
|
|
48451
|
-
this.
|
|
48452
|
-
|
|
48453
|
-
this.
|
|
48454
|
-
|
|
48455
|
-
this.
|
|
48456
|
-
|
|
48457
|
-
this.
|
|
48458
|
-
|
|
48459
|
-
this.
|
|
48460
|
-
|
|
48461
|
-
this.
|
|
48462
|
-
|
|
48463
|
-
this.
|
|
48464
|
-
|
|
48465
|
-
|
|
48466
|
-
|
|
48467
|
-
|
|
48436
|
+
const allMaps = [
|
|
48437
|
+
[this.stateResolvers, null],
|
|
48438
|
+
[this.stateListResolvers, []],
|
|
48439
|
+
[this.memoryStoreResolvers, null],
|
|
48440
|
+
[this.memoryRecallResolvers, []],
|
|
48441
|
+
[this.fileUrlResolvers, null],
|
|
48442
|
+
[this.fileListResolvers, []],
|
|
48443
|
+
[this.fileStatusResolvers, []],
|
|
48444
|
+
[this.graphResultResolvers, []],
|
|
48445
|
+
[this.vectorStoredResolvers, null],
|
|
48446
|
+
[this.vectorResultsResolvers, []],
|
|
48447
|
+
[this.taskListResolvers, []],
|
|
48448
|
+
[this.meshQueryResolvers, null],
|
|
48449
|
+
[this.contextResultsResolvers, []],
|
|
48450
|
+
[this.contextListResolvers, []],
|
|
48451
|
+
[this.streamListResolvers, []],
|
|
48452
|
+
[this.scheduledAckResolvers, null],
|
|
48453
|
+
[this.scheduledListResolvers, []],
|
|
48454
|
+
[this.cancelScheduledResolvers, false],
|
|
48455
|
+
[this.messageStatusResolvers, null],
|
|
48456
|
+
[this.grantFileAccessResolvers, false],
|
|
48457
|
+
[this.collectionListResolvers, []],
|
|
48458
|
+
[this.meshSchemaResolvers, []],
|
|
48459
|
+
[this.taskCreatedResolvers, null],
|
|
48460
|
+
[this.streamCreatedResolvers, null],
|
|
48461
|
+
[this.listPeersResolvers, []],
|
|
48462
|
+
[this.meshInfoResolvers, null]
|
|
48463
|
+
];
|
|
48464
|
+
for (const [map2, defaultVal] of allMaps) {
|
|
48465
|
+
const first = map2.entries().next().value;
|
|
48466
|
+
if (first) {
|
|
48467
|
+
map2.delete(first[0]);
|
|
48468
|
+
clearTimeout(first[1].timer);
|
|
48469
|
+
first[1].resolve(defaultVal);
|
|
48470
|
+
break;
|
|
48471
|
+
}
|
|
48468
48472
|
}
|
|
48469
48473
|
}
|
|
48470
48474
|
}
|
|
@@ -48515,17 +48519,17 @@ async function ensureClient(mesh) {
|
|
|
48515
48519
|
const existing = clients.get(mesh.meshId);
|
|
48516
48520
|
if (existing)
|
|
48517
48521
|
return existing;
|
|
48518
|
-
const
|
|
48519
|
-
clients.set(mesh.meshId,
|
|
48522
|
+
const client2 = new BrokerClient(mesh, { debug: env.CLAUDEMESH_DEBUG, displayName: configDisplayName });
|
|
48523
|
+
clients.set(mesh.meshId, client2);
|
|
48520
48524
|
try {
|
|
48521
|
-
await
|
|
48525
|
+
await client2.connect();
|
|
48522
48526
|
for (const g of configGroups ?? []) {
|
|
48523
48527
|
try {
|
|
48524
|
-
await
|
|
48528
|
+
await client2.joinGroup(g.name, g.role);
|
|
48525
48529
|
} catch {}
|
|
48526
48530
|
}
|
|
48527
48531
|
} catch {}
|
|
48528
|
-
return
|
|
48532
|
+
return client2;
|
|
48529
48533
|
}
|
|
48530
48534
|
async function startClients(config2) {
|
|
48531
48535
|
configDisplayName = config2.displayName;
|
|
@@ -48608,12 +48612,12 @@ async function resolveClient(to) {
|
|
|
48608
48612
|
var peerNameCache = new Map;
|
|
48609
48613
|
var peerNameCacheAge = 0;
|
|
48610
48614
|
var CACHE_TTL_MS = 30000;
|
|
48611
|
-
async function resolvePeerName(
|
|
48615
|
+
async function resolvePeerName(client2, pubkey) {
|
|
48612
48616
|
const now = Date.now();
|
|
48613
48617
|
if (now - peerNameCacheAge > CACHE_TTL_MS) {
|
|
48614
48618
|
peerNameCache.clear();
|
|
48615
48619
|
try {
|
|
48616
|
-
const peers = await
|
|
48620
|
+
const peers = await client2.listPeers();
|
|
48617
48621
|
for (const p of peers)
|
|
48618
48622
|
peerNameCache.set(p.pubkey, p.displayName);
|
|
48619
48623
|
} catch {}
|
|
@@ -48763,15 +48767,15 @@ Your message mode is "${messageMode}".
|
|
|
48763
48767
|
const results = [];
|
|
48764
48768
|
const seen = new Set;
|
|
48765
48769
|
for (const target of targets) {
|
|
48766
|
-
const { client, targetSpec, error: error2 } = await resolveClient(target);
|
|
48767
|
-
if (!
|
|
48770
|
+
const { client: client2, targetSpec, error: error2 } = await resolveClient(target);
|
|
48771
|
+
if (!client2) {
|
|
48768
48772
|
results.push(`✗ ${target}: ${error2 ?? "no client resolved"}`);
|
|
48769
48773
|
continue;
|
|
48770
48774
|
}
|
|
48771
48775
|
if (seen.has(targetSpec))
|
|
48772
48776
|
continue;
|
|
48773
48777
|
seen.add(targetSpec);
|
|
48774
|
-
const result = await
|
|
48778
|
+
const result = await client2.send(targetSpec, message, priority ?? "next");
|
|
48775
48779
|
if (!result.ok) {
|
|
48776
48780
|
results.push(`✗ ${target}: ${result.error}`);
|
|
48777
48781
|
} else {
|
|
@@ -48892,19 +48896,19 @@ ${drained.join(`
|
|
|
48892
48896
|
const { key } = args ?? {};
|
|
48893
48897
|
if (!key)
|
|
48894
48898
|
return text("get_state: `key` required", true);
|
|
48895
|
-
const
|
|
48896
|
-
if (!
|
|
48899
|
+
const client2 = allClients()[0];
|
|
48900
|
+
if (!client2)
|
|
48897
48901
|
return text("get_state: not connected", true);
|
|
48898
|
-
const result = await
|
|
48902
|
+
const result = await client2.getState(key);
|
|
48899
48903
|
if (!result)
|
|
48900
48904
|
return text(`State "${key}" not found.`);
|
|
48901
48905
|
return text(`${key} = ${JSON.stringify(result.value)} (set by ${result.updatedBy} at ${result.updatedAt})`);
|
|
48902
48906
|
}
|
|
48903
48907
|
case "list_state": {
|
|
48904
|
-
const
|
|
48905
|
-
if (!
|
|
48908
|
+
const client2 = allClients()[0];
|
|
48909
|
+
if (!client2)
|
|
48906
48910
|
return text("list_state: not connected", true);
|
|
48907
|
-
const entries = await
|
|
48911
|
+
const entries = await client2.listState();
|
|
48908
48912
|
if (entries.length === 0)
|
|
48909
48913
|
return text("No shared state set.");
|
|
48910
48914
|
const lines = entries.map((e) => `- **${e.key}** = ${JSON.stringify(e.value)} (by ${e.updatedBy})`);
|
|
@@ -48915,20 +48919,20 @@ ${drained.join(`
|
|
|
48915
48919
|
const { content, tags } = args ?? {};
|
|
48916
48920
|
if (!content)
|
|
48917
48921
|
return text("remember: `content` required", true);
|
|
48918
|
-
const
|
|
48919
|
-
if (!
|
|
48922
|
+
const client2 = allClients()[0];
|
|
48923
|
+
if (!client2)
|
|
48920
48924
|
return text("remember: not connected", true);
|
|
48921
|
-
const id = await
|
|
48925
|
+
const id = await client2.remember(content, tags);
|
|
48922
48926
|
return text(`Remembered${id ? ` (${id})` : ""}: "${content.slice(0, 80)}${content.length > 80 ? "..." : ""}"`);
|
|
48923
48927
|
}
|
|
48924
48928
|
case "recall": {
|
|
48925
48929
|
const { query } = args ?? {};
|
|
48926
48930
|
if (!query)
|
|
48927
48931
|
return text("recall: `query` required", true);
|
|
48928
|
-
const
|
|
48929
|
-
if (!
|
|
48932
|
+
const client2 = allClients()[0];
|
|
48933
|
+
if (!client2)
|
|
48930
48934
|
return text("recall: not connected", true);
|
|
48931
|
-
const memories = await
|
|
48935
|
+
const memories = await client2.recall(query);
|
|
48932
48936
|
if (memories.length === 0)
|
|
48933
48937
|
return text(`No memories found for "${query}".`);
|
|
48934
48938
|
const lines = memories.map((m) => `- [${m.id.slice(0, 8)}] ${m.content} (by ${m.rememberedBy}, ${m.rememberedAt})`);
|
|
@@ -48940,12 +48944,63 @@ ${lines.join(`
|
|
|
48940
48944
|
const { id } = args ?? {};
|
|
48941
48945
|
if (!id)
|
|
48942
48946
|
return text("forget: `id` required", true);
|
|
48943
|
-
const
|
|
48944
|
-
if (!
|
|
48947
|
+
const client2 = allClients()[0];
|
|
48948
|
+
if (!client2)
|
|
48945
48949
|
return text("forget: not connected", true);
|
|
48946
|
-
await
|
|
48950
|
+
await client2.forget(id);
|
|
48947
48951
|
return text(`Forgotten: ${id}`);
|
|
48948
48952
|
}
|
|
48953
|
+
case "schedule_reminder":
|
|
48954
|
+
case "send_later": {
|
|
48955
|
+
const sArgs = args ?? {};
|
|
48956
|
+
if (!sArgs.message)
|
|
48957
|
+
return text(`${name}: \`message\` required`, true);
|
|
48958
|
+
const to = name === "schedule_reminder" ? "self" : sArgs.to ?? "";
|
|
48959
|
+
if (name === "send_later" && !to)
|
|
48960
|
+
return text("send_later: `to` required", true);
|
|
48961
|
+
let deliverAt;
|
|
48962
|
+
if (sArgs.deliver_at) {
|
|
48963
|
+
deliverAt = Number(sArgs.deliver_at);
|
|
48964
|
+
} else if (sArgs.in_seconds) {
|
|
48965
|
+
deliverAt = Date.now() + Number(sArgs.in_seconds) * 1000;
|
|
48966
|
+
} else {
|
|
48967
|
+
return text(`${name}: provide \`deliver_at\` (ms timestamp) or \`in_seconds\``, true);
|
|
48968
|
+
}
|
|
48969
|
+
let targetSpec = to;
|
|
48970
|
+
if (name === "send_later" && !to.startsWith("@") && to !== "*" && !/^[0-9a-f]{64}$/i.test(to) && to !== "self") {
|
|
48971
|
+
const peers = await client.listPeers();
|
|
48972
|
+
const match = peers.find((p) => p.displayName.toLowerCase() === to.toLowerCase());
|
|
48973
|
+
if (!match) {
|
|
48974
|
+
const names = peers.map((p) => p.displayName).join(", ");
|
|
48975
|
+
return text(`send_later: peer "${to}" not found. Online: ${names || "(none)"}`, true);
|
|
48976
|
+
}
|
|
48977
|
+
targetSpec = match.pubkey;
|
|
48978
|
+
}
|
|
48979
|
+
if (name === "schedule_reminder") {
|
|
48980
|
+
targetSpec = client.getSessionPubkey() ?? "*";
|
|
48981
|
+
}
|
|
48982
|
+
const result = await client.scheduleMessage(targetSpec, sArgs.message, deliverAt);
|
|
48983
|
+
if (!result)
|
|
48984
|
+
return text(`${name}: broker did not acknowledge — check connection`, true);
|
|
48985
|
+
const when = new Date(result.deliverAt).toISOString();
|
|
48986
|
+
return text(name === "schedule_reminder" ? `Reminder scheduled (${result.scheduledId.slice(0, 8)}): "${sArgs.message.slice(0, 60)}" at ${when}` : `Message to "${to}" scheduled (${result.scheduledId.slice(0, 8)}) for ${when}`);
|
|
48987
|
+
}
|
|
48988
|
+
case "list_scheduled": {
|
|
48989
|
+
const scheduled = await client.listScheduled();
|
|
48990
|
+
if (scheduled.length === 0)
|
|
48991
|
+
return text("No pending scheduled messages.");
|
|
48992
|
+
const lines = scheduled.map((m) => `- [${m.id.slice(0, 8)}] → ${m.to === client.getSessionPubkey() ? "self (reminder)" : m.to} at ${new Date(m.deliverAt).toISOString()}: "${m.message.slice(0, 60)}${m.message.length > 60 ? "…" : ""}"`);
|
|
48993
|
+
return text(`${scheduled.length} scheduled:
|
|
48994
|
+
${lines.join(`
|
|
48995
|
+
`)}`);
|
|
48996
|
+
}
|
|
48997
|
+
case "cancel_scheduled": {
|
|
48998
|
+
const { id: schedId } = args ?? {};
|
|
48999
|
+
if (!schedId)
|
|
49000
|
+
return text("cancel_scheduled: `id` required", true);
|
|
49001
|
+
const ok = await client.cancelScheduled(schedId);
|
|
49002
|
+
return text(ok ? `Cancelled: ${schedId}` : `Not found or already fired: ${schedId}`, !ok);
|
|
49003
|
+
}
|
|
48949
49004
|
case "share_file": {
|
|
48950
49005
|
const { path: filePath, name: fileName, tags, to: fileTo } = args ?? {};
|
|
48951
49006
|
if (!filePath)
|
|
@@ -48953,15 +49008,15 @@ ${lines.join(`
|
|
|
48953
49008
|
const { existsSync: existsSync2 } = await import("node:fs");
|
|
48954
49009
|
if (!existsSync2(filePath))
|
|
48955
49010
|
return text(`share_file: file not found: ${filePath}`, true);
|
|
48956
|
-
const
|
|
48957
|
-
if (!
|
|
49011
|
+
const client2 = allClients()[0];
|
|
49012
|
+
if (!client2)
|
|
48958
49013
|
return text("share_file: not connected", true);
|
|
48959
49014
|
if (fileTo) {
|
|
48960
49015
|
const { encryptFile: encryptFile2, sealKeyForPeer: sealKeyForPeer2 } = await Promise.resolve().then(() => (init_file_crypto(), exports_file_crypto));
|
|
48961
49016
|
const { readFileSync: readFileSync2, writeFileSync: writeFileSync2, mkdtempSync, unlinkSync, rmdirSync } = await import("node:fs");
|
|
48962
49017
|
const { tmpdir } = await import("node:os");
|
|
48963
49018
|
const { join: join2, basename } = await import("node:path");
|
|
48964
|
-
const peers = await
|
|
49019
|
+
const peers = await client2.listPeers();
|
|
48965
49020
|
const targetPeer = peers.find((p) => p.pubkey === fileTo || p.displayName === fileTo);
|
|
48966
49021
|
if (!targetPeer) {
|
|
48967
49022
|
return text(`share_file: peer not found: ${fileTo}`, true);
|
|
@@ -48969,7 +49024,7 @@ ${lines.join(`
|
|
|
48969
49024
|
const plaintext = readFileSync2(filePath);
|
|
48970
49025
|
const { ciphertext, nonce, key } = await encryptFile2(new Uint8Array(plaintext));
|
|
48971
49026
|
const sealedForTarget = await sealKeyForPeer2(key, targetPeer.pubkey);
|
|
48972
|
-
const myPubkey =
|
|
49027
|
+
const myPubkey = client2.getSessionPubkey();
|
|
48973
49028
|
const sealedForSelf = myPubkey ? await sealKeyForPeer2(key, myPubkey) : null;
|
|
48974
49029
|
const fileKeys = [
|
|
48975
49030
|
{ peerPubkey: targetPeer.pubkey, sealedKey: sealedForTarget },
|
|
@@ -48986,7 +49041,7 @@ ${lines.join(`
|
|
|
48986
49041
|
const tmpPath = join2(tmpDir, baseName);
|
|
48987
49042
|
writeFileSync2(tmpPath, combined);
|
|
48988
49043
|
try {
|
|
48989
|
-
const fileId = await
|
|
49044
|
+
const fileId = await client2.uploadFile(tmpPath, client2.meshId, client2.meshSlug, {
|
|
48990
49045
|
name: baseName,
|
|
48991
49046
|
tags,
|
|
48992
49047
|
persistent: true,
|
|
@@ -49007,7 +49062,7 @@ ${lines.join(`
|
|
|
49007
49062
|
}
|
|
49008
49063
|
}
|
|
49009
49064
|
try {
|
|
49010
|
-
const fileId = await
|
|
49065
|
+
const fileId = await client2.uploadFile(filePath, client2.meshId, client2.meshSlug, {
|
|
49011
49066
|
name: fileName,
|
|
49012
49067
|
tags,
|
|
49013
49068
|
persistent: true
|
|
@@ -49021,10 +49076,10 @@ ${lines.join(`
|
|
|
49021
49076
|
const { id, save_to } = args ?? {};
|
|
49022
49077
|
if (!id || !save_to)
|
|
49023
49078
|
return text("get_file: `id` and `save_to` required", true);
|
|
49024
|
-
const
|
|
49025
|
-
if (!
|
|
49079
|
+
const client2 = allClients()[0];
|
|
49080
|
+
if (!client2)
|
|
49026
49081
|
return text("get_file: not connected", true);
|
|
49027
|
-
const result = await
|
|
49082
|
+
const result = await client2.getFile(id);
|
|
49028
49083
|
if (!result)
|
|
49029
49084
|
return text(`get_file: file ${id} not found`, true);
|
|
49030
49085
|
if (result.encrypted) {
|
|
@@ -49032,8 +49087,8 @@ ${lines.join(`
|
|
|
49032
49087
|
return text("get_file: encrypted file — no decryption key available for your session", true);
|
|
49033
49088
|
const { openSealedKey: openSealedKey2, decryptFile: decryptFile2 } = await Promise.resolve().then(() => (init_file_crypto(), exports_file_crypto));
|
|
49034
49089
|
const { ensureSodium: ensureSodium2 } = await Promise.resolve().then(() => (init_keypair(), exports_keypair));
|
|
49035
|
-
const myPubkey =
|
|
49036
|
-
const mySecret =
|
|
49090
|
+
const myPubkey = client2.getSessionPubkey();
|
|
49091
|
+
const mySecret = client2.getSessionSecretKey();
|
|
49037
49092
|
if (!myPubkey || !mySecret) {
|
|
49038
49093
|
return text("get_file: no session keypair — cannot decrypt", true);
|
|
49039
49094
|
}
|
|
@@ -49068,10 +49123,10 @@ ${lines.join(`
|
|
|
49068
49123
|
}
|
|
49069
49124
|
case "list_files": {
|
|
49070
49125
|
const { query, from } = args ?? {};
|
|
49071
|
-
const
|
|
49072
|
-
if (!
|
|
49126
|
+
const client2 = allClients()[0];
|
|
49127
|
+
if (!client2)
|
|
49073
49128
|
return text("list_files: not connected", true);
|
|
49074
|
-
const files = await
|
|
49129
|
+
const files = await client2.listFiles(query, from);
|
|
49075
49130
|
if (files.length === 0)
|
|
49076
49131
|
return text("No files found.");
|
|
49077
49132
|
const lines = files.map((f) => `- **${f.name}** (${f.id.slice(0, 8)}…, ${f.size} bytes) by ${f.uploadedBy}${f.tags.length ? ` [${f.tags.join(", ")}]` : ""}`);
|
|
@@ -49082,10 +49137,10 @@ ${lines.join(`
|
|
|
49082
49137
|
const { id } = args ?? {};
|
|
49083
49138
|
if (!id)
|
|
49084
49139
|
return text("file_status: `id` required", true);
|
|
49085
|
-
const
|
|
49086
|
-
if (!
|
|
49140
|
+
const client2 = allClients()[0];
|
|
49141
|
+
if (!client2)
|
|
49087
49142
|
return text("file_status: not connected", true);
|
|
49088
|
-
const accesses = await
|
|
49143
|
+
const accesses = await client2.fileStatus(id);
|
|
49089
49144
|
if (accesses.length === 0)
|
|
49090
49145
|
return text("No one has accessed this file yet.");
|
|
49091
49146
|
const lines = accesses.map((a) => `- ${a.peerName} at ${a.accessedAt}`);
|
|
@@ -49097,30 +49152,30 @@ ${lines.join(`
|
|
|
49097
49152
|
const { id } = args ?? {};
|
|
49098
49153
|
if (!id)
|
|
49099
49154
|
return text("delete_file: `id` required", true);
|
|
49100
|
-
const
|
|
49101
|
-
if (!
|
|
49155
|
+
const client2 = allClients()[0];
|
|
49156
|
+
if (!client2)
|
|
49102
49157
|
return text("delete_file: not connected", true);
|
|
49103
|
-
await
|
|
49158
|
+
await client2.deleteFile(id);
|
|
49104
49159
|
return text(`Deleted: ${id}`);
|
|
49105
49160
|
}
|
|
49106
49161
|
case "vector_store": {
|
|
49107
49162
|
const { collection, text: storeText, metadata } = args ?? {};
|
|
49108
49163
|
if (!collection || !storeText)
|
|
49109
49164
|
return text("vector_store: `collection` and `text` required", true);
|
|
49110
|
-
const
|
|
49111
|
-
if (!
|
|
49165
|
+
const client2 = allClients()[0];
|
|
49166
|
+
if (!client2)
|
|
49112
49167
|
return text("vector_store: not connected", true);
|
|
49113
|
-
const id = await
|
|
49168
|
+
const id = await client2.vectorStore(collection, storeText, metadata);
|
|
49114
49169
|
return text(`Stored in ${collection}${id ? ` (${id})` : ""}`);
|
|
49115
49170
|
}
|
|
49116
49171
|
case "vector_search": {
|
|
49117
49172
|
const { collection, query, limit } = args ?? {};
|
|
49118
49173
|
if (!collection || !query)
|
|
49119
49174
|
return text("vector_search: `collection` and `query` required", true);
|
|
49120
|
-
const
|
|
49121
|
-
if (!
|
|
49175
|
+
const client2 = allClients()[0];
|
|
49176
|
+
if (!client2)
|
|
49122
49177
|
return text("vector_search: not connected", true);
|
|
49123
|
-
const results = await
|
|
49178
|
+
const results = await client2.vectorSearch(collection, query, limit);
|
|
49124
49179
|
if (results.length === 0)
|
|
49125
49180
|
return text(`No results in ${collection} for "${query}".`);
|
|
49126
49181
|
const lines = results.map((r) => `- [${r.id.slice(0, 8)}…] (score: ${r.score.toFixed(3)}) ${r.text.slice(0, 120)}${r.text.length > 120 ? "…" : ""}`);
|
|
@@ -49132,17 +49187,17 @@ ${lines.join(`
|
|
|
49132
49187
|
const { collection, id } = args ?? {};
|
|
49133
49188
|
if (!collection || !id)
|
|
49134
49189
|
return text("vector_delete: `collection` and `id` required", true);
|
|
49135
|
-
const
|
|
49136
|
-
if (!
|
|
49190
|
+
const client2 = allClients()[0];
|
|
49191
|
+
if (!client2)
|
|
49137
49192
|
return text("vector_delete: not connected", true);
|
|
49138
|
-
await
|
|
49193
|
+
await client2.vectorDelete(collection, id);
|
|
49139
49194
|
return text(`Deleted ${id} from ${collection}`);
|
|
49140
49195
|
}
|
|
49141
49196
|
case "list_collections": {
|
|
49142
|
-
const
|
|
49143
|
-
if (!
|
|
49197
|
+
const client2 = allClients()[0];
|
|
49198
|
+
if (!client2)
|
|
49144
49199
|
return text("list_collections: not connected", true);
|
|
49145
|
-
const collections = await
|
|
49200
|
+
const collections = await client2.listCollections();
|
|
49146
49201
|
if (collections.length === 0)
|
|
49147
49202
|
return text("No vector collections.");
|
|
49148
49203
|
return text(`Collections:
|
|
@@ -49153,10 +49208,10 @@ ${collections.map((c) => `- ${c}`).join(`
|
|
|
49153
49208
|
const { cypher } = args ?? {};
|
|
49154
49209
|
if (!cypher)
|
|
49155
49210
|
return text("graph_query: `cypher` required", true);
|
|
49156
|
-
const
|
|
49157
|
-
if (!
|
|
49211
|
+
const client2 = allClients()[0];
|
|
49212
|
+
if (!client2)
|
|
49158
49213
|
return text("graph_query: not connected", true);
|
|
49159
|
-
const rows = await
|
|
49214
|
+
const rows = await client2.graphQuery(cypher);
|
|
49160
49215
|
if (rows.length === 0)
|
|
49161
49216
|
return text("No results.");
|
|
49162
49217
|
return text(JSON.stringify(rows, null, 2));
|
|
@@ -49165,30 +49220,30 @@ ${collections.map((c) => `- ${c}`).join(`
|
|
|
49165
49220
|
const { cypher } = args ?? {};
|
|
49166
49221
|
if (!cypher)
|
|
49167
49222
|
return text("graph_execute: `cypher` required", true);
|
|
49168
|
-
const
|
|
49169
|
-
if (!
|
|
49223
|
+
const client2 = allClients()[0];
|
|
49224
|
+
if (!client2)
|
|
49170
49225
|
return text("graph_execute: not connected", true);
|
|
49171
|
-
const rows = await
|
|
49226
|
+
const rows = await client2.graphExecute(cypher);
|
|
49172
49227
|
return text(rows.length > 0 ? JSON.stringify(rows, null, 2) : "Executed successfully.");
|
|
49173
49228
|
}
|
|
49174
49229
|
case "share_context": {
|
|
49175
49230
|
const { summary, files_read, key_findings, tags } = args ?? {};
|
|
49176
49231
|
if (!summary)
|
|
49177
49232
|
return text("share_context: `summary` required", true);
|
|
49178
|
-
const
|
|
49179
|
-
if (!
|
|
49233
|
+
const client2 = allClients()[0];
|
|
49234
|
+
if (!client2)
|
|
49180
49235
|
return text("share_context: not connected", true);
|
|
49181
|
-
await
|
|
49236
|
+
await client2.shareContext(summary, files_read, key_findings, tags);
|
|
49182
49237
|
return text(`Context shared: "${summary.slice(0, 80)}${summary.length > 80 ? "…" : ""}"`);
|
|
49183
49238
|
}
|
|
49184
49239
|
case "get_context": {
|
|
49185
49240
|
const { query } = args ?? {};
|
|
49186
49241
|
if (!query)
|
|
49187
49242
|
return text("get_context: `query` required", true);
|
|
49188
|
-
const
|
|
49189
|
-
if (!
|
|
49243
|
+
const client2 = allClients()[0];
|
|
49244
|
+
if (!client2)
|
|
49190
49245
|
return text("get_context: not connected", true);
|
|
49191
|
-
const contexts = await
|
|
49246
|
+
const contexts = await client2.getContext(query);
|
|
49192
49247
|
if (contexts.length === 0)
|
|
49193
49248
|
return text(`No context found for "${query}".`);
|
|
49194
49249
|
const lines = contexts.map((c) => {
|
|
@@ -49203,10 +49258,10 @@ ${lines.join(`
|
|
|
49203
49258
|
`)}`);
|
|
49204
49259
|
}
|
|
49205
49260
|
case "list_contexts": {
|
|
49206
|
-
const
|
|
49207
|
-
if (!
|
|
49261
|
+
const client2 = allClients()[0];
|
|
49262
|
+
if (!client2)
|
|
49208
49263
|
return text("list_contexts: not connected", true);
|
|
49209
|
-
const contexts = await
|
|
49264
|
+
const contexts = await client2.listContexts();
|
|
49210
49265
|
if (contexts.length === 0)
|
|
49211
49266
|
return text("No peer contexts shared yet.");
|
|
49212
49267
|
const lines = contexts.map((c) => `- **${c.peerName}**: ${c.summary}${c.tags.length ? ` [${c.tags.join(", ")}]` : ""}`);
|
|
@@ -49218,38 +49273,38 @@ ${lines.join(`
|
|
|
49218
49273
|
const { title, assignee, priority, tags } = args ?? {};
|
|
49219
49274
|
if (!title)
|
|
49220
49275
|
return text("create_task: `title` required", true);
|
|
49221
|
-
const
|
|
49222
|
-
if (!
|
|
49276
|
+
const client2 = allClients()[0];
|
|
49277
|
+
if (!client2)
|
|
49223
49278
|
return text("create_task: not connected", true);
|
|
49224
|
-
const id = await
|
|
49279
|
+
const id = await client2.createTask(title, assignee, priority, tags);
|
|
49225
49280
|
return text(`Task created${id ? ` (${id})` : ""}: "${title}"${assignee ? ` → ${assignee}` : ""}`);
|
|
49226
49281
|
}
|
|
49227
49282
|
case "claim_task": {
|
|
49228
49283
|
const { id } = args ?? {};
|
|
49229
49284
|
if (!id)
|
|
49230
49285
|
return text("claim_task: `id` required", true);
|
|
49231
|
-
const
|
|
49232
|
-
if (!
|
|
49286
|
+
const client2 = allClients()[0];
|
|
49287
|
+
if (!client2)
|
|
49233
49288
|
return text("claim_task: not connected", true);
|
|
49234
|
-
await
|
|
49289
|
+
await client2.claimTask(id);
|
|
49235
49290
|
return text(`Claimed task: ${id}`);
|
|
49236
49291
|
}
|
|
49237
49292
|
case "complete_task": {
|
|
49238
49293
|
const { id, result } = args ?? {};
|
|
49239
49294
|
if (!id)
|
|
49240
49295
|
return text("complete_task: `id` required", true);
|
|
49241
|
-
const
|
|
49242
|
-
if (!
|
|
49296
|
+
const client2 = allClients()[0];
|
|
49297
|
+
if (!client2)
|
|
49243
49298
|
return text("complete_task: not connected", true);
|
|
49244
|
-
await
|
|
49299
|
+
await client2.completeTask(id, result);
|
|
49245
49300
|
return text(`Completed task: ${id}${result ? ` — ${result}` : ""}`);
|
|
49246
49301
|
}
|
|
49247
49302
|
case "list_tasks": {
|
|
49248
49303
|
const { status, assignee } = args ?? {};
|
|
49249
|
-
const
|
|
49250
|
-
if (!
|
|
49304
|
+
const client2 = allClients()[0];
|
|
49305
|
+
if (!client2)
|
|
49251
49306
|
return text("list_tasks: not connected", true);
|
|
49252
|
-
const tasks = await
|
|
49307
|
+
const tasks = await client2.listTasks(status, assignee);
|
|
49253
49308
|
if (tasks.length === 0)
|
|
49254
49309
|
return text("No tasks found.");
|
|
49255
49310
|
const lines = tasks.map((t) => `- [${t.id.slice(0, 8)}…] **${t.title}** (${t.status}, ${t.priority}) ${t.assignee ? `→ ${t.assignee}` : "unassigned"} (by ${t.createdBy})`);
|
|
@@ -49261,10 +49316,10 @@ ${lines.join(`
|
|
|
49261
49316
|
const { sql: querySql } = args ?? {};
|
|
49262
49317
|
if (!querySql)
|
|
49263
49318
|
return text("mesh_query: `sql` required", true);
|
|
49264
|
-
const
|
|
49265
|
-
if (!
|
|
49319
|
+
const client2 = allClients()[0];
|
|
49320
|
+
if (!client2)
|
|
49266
49321
|
return text("mesh_query: not connected", true);
|
|
49267
|
-
const result = await
|
|
49322
|
+
const result = await client2.meshQuery(querySql);
|
|
49268
49323
|
if (!result)
|
|
49269
49324
|
return text("mesh_query: query failed or timed out", true);
|
|
49270
49325
|
if (result.rows.length === 0)
|
|
@@ -49282,17 +49337,17 @@ ${rows.join(`
|
|
|
49282
49337
|
const { sql: execSql } = args ?? {};
|
|
49283
49338
|
if (!execSql)
|
|
49284
49339
|
return text("mesh_execute: `sql` required", true);
|
|
49285
|
-
const
|
|
49286
|
-
if (!
|
|
49340
|
+
const client2 = allClients()[0];
|
|
49341
|
+
if (!client2)
|
|
49287
49342
|
return text("mesh_execute: not connected", true);
|
|
49288
|
-
await
|
|
49343
|
+
await client2.meshExecute(execSql);
|
|
49289
49344
|
return text(`Executed.`);
|
|
49290
49345
|
}
|
|
49291
49346
|
case "mesh_schema": {
|
|
49292
|
-
const
|
|
49293
|
-
if (!
|
|
49347
|
+
const client2 = allClients()[0];
|
|
49348
|
+
if (!client2)
|
|
49294
49349
|
return text("mesh_schema: not connected", true);
|
|
49295
|
-
const tables = await
|
|
49350
|
+
const tables = await client2.meshSchema();
|
|
49296
49351
|
if (!tables || tables.length === 0)
|
|
49297
49352
|
return text("No tables in mesh database.");
|
|
49298
49353
|
const lines = tables.map((t) => `**${t.name}**: ${t.columns.map((c) => `${c.name} (${c.type}${c.nullable ? ", nullable" : ""})`).join(", ")}`);
|
|
@@ -49303,37 +49358,37 @@ ${rows.join(`
|
|
|
49303
49358
|
const { name: streamName } = args ?? {};
|
|
49304
49359
|
if (!streamName)
|
|
49305
49360
|
return text("create_stream: `name` required", true);
|
|
49306
|
-
const
|
|
49307
|
-
if (!
|
|
49361
|
+
const client2 = allClients()[0];
|
|
49362
|
+
if (!client2)
|
|
49308
49363
|
return text("create_stream: not connected", true);
|
|
49309
|
-
const streamId = await
|
|
49364
|
+
const streamId = await client2.createStream(streamName);
|
|
49310
49365
|
return text(`Stream created: ${streamName}${streamId ? ` (${streamId})` : ""}`);
|
|
49311
49366
|
}
|
|
49312
49367
|
case "publish": {
|
|
49313
49368
|
const { stream: pubStream, data: pubData } = args ?? {};
|
|
49314
49369
|
if (!pubStream)
|
|
49315
49370
|
return text("publish: `stream` required", true);
|
|
49316
|
-
const
|
|
49317
|
-
if (!
|
|
49371
|
+
const client2 = allClients()[0];
|
|
49372
|
+
if (!client2)
|
|
49318
49373
|
return text("publish: not connected", true);
|
|
49319
|
-
await
|
|
49374
|
+
await client2.publish(pubStream, pubData);
|
|
49320
49375
|
return text(`Published to ${pubStream}.`);
|
|
49321
49376
|
}
|
|
49322
49377
|
case "subscribe": {
|
|
49323
49378
|
const { stream: subStream } = args ?? {};
|
|
49324
49379
|
if (!subStream)
|
|
49325
49380
|
return text("subscribe: `stream` required", true);
|
|
49326
|
-
const
|
|
49327
|
-
if (!
|
|
49381
|
+
const client2 = allClients()[0];
|
|
49382
|
+
if (!client2)
|
|
49328
49383
|
return text("subscribe: not connected", true);
|
|
49329
|
-
await
|
|
49384
|
+
await client2.subscribe(subStream);
|
|
49330
49385
|
return text(`Subscribed to ${subStream}. Data pushes will arrive as channel notifications.`);
|
|
49331
49386
|
}
|
|
49332
49387
|
case "list_streams": {
|
|
49333
|
-
const
|
|
49334
|
-
if (!
|
|
49388
|
+
const client2 = allClients()[0];
|
|
49389
|
+
if (!client2)
|
|
49335
49390
|
return text("list_streams: not connected", true);
|
|
49336
|
-
const streams = await
|
|
49391
|
+
const streams = await client2.listStreams();
|
|
49337
49392
|
if (streams.length === 0)
|
|
49338
49393
|
return text("No active streams.");
|
|
49339
49394
|
const lines = streams.map((s) => `- **${s.name}** (${s.id.slice(0, 8)}…) by ${s.createdBy}, ${s.subscriberCount} subscriber(s)`);
|
|
@@ -49341,10 +49396,10 @@ ${rows.join(`
|
|
|
49341
49396
|
`));
|
|
49342
49397
|
}
|
|
49343
49398
|
case "mesh_info": {
|
|
49344
|
-
const
|
|
49345
|
-
if (!
|
|
49399
|
+
const client2 = allClients()[0];
|
|
49400
|
+
if (!client2)
|
|
49346
49401
|
return text("mesh_info: not connected", true);
|
|
49347
|
-
const info = await
|
|
49402
|
+
const info = await client2.meshInfo();
|
|
49348
49403
|
if (!info)
|
|
49349
49404
|
return text("mesh_info: timed out", true);
|
|
49350
49405
|
const lines = [
|
|
@@ -49366,21 +49421,21 @@ ${rows.join(`
|
|
|
49366
49421
|
case "ping_mesh": {
|
|
49367
49422
|
const { priorities: pingPriorities } = args ?? {};
|
|
49368
49423
|
const toTest = pingPriorities ?? ["now", "next"];
|
|
49369
|
-
const
|
|
49370
|
-
if (!
|
|
49424
|
+
const client2 = allClients()[0];
|
|
49425
|
+
if (!client2)
|
|
49371
49426
|
return text("ping_mesh: not connected", true);
|
|
49372
49427
|
const results = [];
|
|
49373
|
-
results.push(`WS status: ${
|
|
49374
|
-
results.push(`Mesh: ${
|
|
49375
|
-
const peers = await
|
|
49428
|
+
results.push(`WS status: ${client2.status}`);
|
|
49429
|
+
results.push(`Mesh: ${client2.meshSlug}`);
|
|
49430
|
+
const peers = await client2.listPeers();
|
|
49376
49431
|
const selfPeer = peers.find((p) => p.displayName === myName);
|
|
49377
49432
|
results.push(`Your status: ${selfPeer?.status ?? "not found in peer list"}`);
|
|
49378
49433
|
results.push(`Peers online: ${peers.length}`);
|
|
49379
|
-
results.push(`Push buffer: ${
|
|
49434
|
+
results.push(`Push buffer: ${client2.pushHistory.length} buffered`);
|
|
49380
49435
|
for (const prio of toTest) {
|
|
49381
49436
|
const sendTime = Date.now();
|
|
49382
49437
|
const target = peers.find((p) => p.displayName !== myName);
|
|
49383
|
-
const sendResult = await
|
|
49438
|
+
const sendResult = await client2.send(target?.pubkey ?? "*", `__ping__ ${prio} from ${myName} at ${new Date().toISOString()}`, prio);
|
|
49384
49439
|
const ackTime = Date.now();
|
|
49385
49440
|
if (!sendResult.ok) {
|
|
49386
49441
|
results.push(`[${prio}] SEND FAILED: ${sendResult.error}`);
|
|
@@ -49403,14 +49458,14 @@ ${rows.join(`
|
|
|
49403
49458
|
const { fileId, to: grantTo } = args ?? {};
|
|
49404
49459
|
if (!fileId || !grantTo)
|
|
49405
49460
|
return text("grant_file_access: `fileId` and `to` required", true);
|
|
49406
|
-
const
|
|
49407
|
-
if (!
|
|
49461
|
+
const client2 = allClients()[0];
|
|
49462
|
+
if (!client2)
|
|
49408
49463
|
return text("grant_file_access: not connected", true);
|
|
49409
|
-
const peers = await
|
|
49464
|
+
const peers = await client2.listPeers();
|
|
49410
49465
|
const targetPeer = peers.find((p) => p.pubkey === grantTo || p.displayName === grantTo);
|
|
49411
49466
|
if (!targetPeer)
|
|
49412
49467
|
return text(`grant_file_access: peer not found: ${grantTo}`, true);
|
|
49413
|
-
const result = await
|
|
49468
|
+
const result = await client2.getFile(fileId);
|
|
49414
49469
|
if (!result)
|
|
49415
49470
|
return text("grant_file_access: file not found", true);
|
|
49416
49471
|
if (!result.encrypted)
|
|
@@ -49418,15 +49473,15 @@ ${rows.join(`
|
|
|
49418
49473
|
if (!result.sealedKey)
|
|
49419
49474
|
return text("grant_file_access: no key available (are you the owner?)", true);
|
|
49420
49475
|
const { openSealedKey: openSealedKey2, sealKeyForPeer: sealKeyForPeer2 } = await Promise.resolve().then(() => (init_file_crypto(), exports_file_crypto));
|
|
49421
|
-
const myPubkey =
|
|
49422
|
-
const mySecret =
|
|
49476
|
+
const myPubkey = client2.getSessionPubkey();
|
|
49477
|
+
const mySecret = client2.getSessionSecretKey();
|
|
49423
49478
|
if (!myPubkey || !mySecret)
|
|
49424
49479
|
return text("grant_file_access: no session keypair", true);
|
|
49425
49480
|
const kf = await openSealedKey2(result.sealedKey, myPubkey, mySecret);
|
|
49426
49481
|
if (!kf)
|
|
49427
49482
|
return text("grant_file_access: cannot decrypt your own key", true);
|
|
49428
49483
|
const sealedForPeer = await sealKeyForPeer2(kf, targetPeer.pubkey);
|
|
49429
|
-
const ok = await
|
|
49484
|
+
const ok = await client2.grantFileAccess(fileId, targetPeer.pubkey, sealedForPeer);
|
|
49430
49485
|
if (!ok)
|
|
49431
49486
|
return text("grant_file_access: broker did not confirm", true);
|
|
49432
49487
|
return text(`Access granted: ${targetPeer.displayName} can now download file ${fileId}`);
|
|
@@ -49438,12 +49493,12 @@ ${rows.join(`
|
|
|
49438
49493
|
await startClients(config2);
|
|
49439
49494
|
const transport = new StdioServerTransport;
|
|
49440
49495
|
await server.connect(transport);
|
|
49441
|
-
for (const
|
|
49442
|
-
|
|
49496
|
+
for (const client2 of allClients()) {
|
|
49497
|
+
client2.onPush(async (msg) => {
|
|
49443
49498
|
if (messageMode === "off")
|
|
49444
49499
|
return;
|
|
49445
49500
|
const fromPubkey = msg.senderPubkey || "";
|
|
49446
|
-
const fromName = fromPubkey ? await resolvePeerName(
|
|
49501
|
+
const fromName = fromPubkey ? await resolvePeerName(client2, fromPubkey) : "unknown";
|
|
49447
49502
|
if (messageMode === "inbox") {
|
|
49448
49503
|
try {
|
|
49449
49504
|
await server.notification({
|
|
@@ -49465,8 +49520,8 @@ ${rows.join(`
|
|
|
49465
49520
|
meta: {
|
|
49466
49521
|
from_id: fromPubkey,
|
|
49467
49522
|
from_name: fromName,
|
|
49468
|
-
mesh_slug:
|
|
49469
|
-
mesh_id:
|
|
49523
|
+
mesh_slug: client2.meshSlug,
|
|
49524
|
+
mesh_id: client2.meshId,
|
|
49470
49525
|
priority: msg.priority,
|
|
49471
49526
|
sent_at: msg.createdAt,
|
|
49472
49527
|
delivered_at: msg.receivedAt,
|
|
@@ -49481,7 +49536,7 @@ ${rows.join(`
|
|
|
49481
49536
|
`);
|
|
49482
49537
|
}
|
|
49483
49538
|
});
|
|
49484
|
-
|
|
49539
|
+
client2.onStreamData(async (evt) => {
|
|
49485
49540
|
try {
|
|
49486
49541
|
await server.notification({
|
|
49487
49542
|
method: "notifications/claude/channel",
|
|
@@ -49496,7 +49551,7 @@ ${rows.join(`
|
|
|
49496
49551
|
});
|
|
49497
49552
|
} catch {}
|
|
49498
49553
|
});
|
|
49499
|
-
|
|
49554
|
+
client2.onStateChange(async (change) => {
|
|
49500
49555
|
try {
|
|
49501
49556
|
await server.notification({
|
|
49502
49557
|
method: "notifications/claude/channel",
|
|
@@ -49513,17 +49568,17 @@ ${rows.join(`
|
|
|
49513
49568
|
});
|
|
49514
49569
|
}
|
|
49515
49570
|
setTimeout(async () => {
|
|
49516
|
-
const
|
|
49517
|
-
if (!
|
|
49571
|
+
const client2 = allClients()[0];
|
|
49572
|
+
if (!client2 || client2.status !== "open")
|
|
49518
49573
|
return;
|
|
49519
49574
|
try {
|
|
49520
|
-
const peers = await
|
|
49575
|
+
const peers = await client2.listPeers();
|
|
49521
49576
|
const peerNames = peers.filter((p) => p.displayName !== myName).map((p) => p.displayName).join(", ") || "none";
|
|
49522
49577
|
await server.notification({
|
|
49523
49578
|
method: "notifications/claude/channel",
|
|
49524
49579
|
params: {
|
|
49525
|
-
content: `[system] Connected as ${myName} to mesh ${
|
|
49526
|
-
meta: { kind: "welcome", mesh_slug:
|
|
49580
|
+
content: `[system] Connected as ${myName} to mesh ${client2.meshSlug}. ${peers.length} peer(s) online: ${peerNames}. Call mesh_info for full details or set_summary to announce yourself.`,
|
|
49581
|
+
meta: { kind: "welcome", mesh_slug: client2.meshSlug }
|
|
49527
49582
|
}
|
|
49528
49583
|
});
|
|
49529
49584
|
} catch {}
|
|
@@ -50498,7 +50553,7 @@ init_config();
|
|
|
50498
50553
|
// package.json
|
|
50499
50554
|
var package_default = {
|
|
50500
50555
|
name: "claudemesh-cli",
|
|
50501
|
-
version: "0.6.
|
|
50556
|
+
version: "0.6.7",
|
|
50502
50557
|
description: "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.",
|
|
50503
50558
|
keywords: [
|
|
50504
50559
|
"claude-code",
|
|
@@ -50931,13 +50986,13 @@ Joined: ${config2.meshes.map((m) => m.slug).join(", ")}`);
|
|
|
50931
50986
|
process.exit(1);
|
|
50932
50987
|
}
|
|
50933
50988
|
const displayName = opts.displayName ?? config2.displayName ?? `${hostname3()}-${process.pid}`;
|
|
50934
|
-
const
|
|
50989
|
+
const client2 = new BrokerClient(mesh, { displayName });
|
|
50935
50990
|
try {
|
|
50936
|
-
await
|
|
50937
|
-
const result = await fn(
|
|
50991
|
+
await client2.connect();
|
|
50992
|
+
const result = await fn(client2, mesh);
|
|
50938
50993
|
return result;
|
|
50939
50994
|
} finally {
|
|
50940
|
-
|
|
50995
|
+
client2.close();
|
|
50941
50996
|
}
|
|
50942
50997
|
}
|
|
50943
50998
|
|
|
@@ -50948,8 +51003,8 @@ async function runPeers(flags) {
|
|
|
50948
51003
|
const bold2 = (s) => useColor ? `\x1B[1m${s}\x1B[22m` : s;
|
|
50949
51004
|
const green = (s) => useColor ? `\x1B[32m${s}\x1B[39m` : s;
|
|
50950
51005
|
const yellow = (s) => useColor ? `\x1B[33m${s}\x1B[39m` : s;
|
|
50951
|
-
await withMesh({ meshSlug: flags.mesh ?? null }, async (
|
|
50952
|
-
const peers = await
|
|
51006
|
+
await withMesh({ meshSlug: flags.mesh ?? null }, async (client2, mesh) => {
|
|
51007
|
+
const peers = await client2.listPeers();
|
|
50953
51008
|
if (flags.json) {
|
|
50954
51009
|
console.log(JSON.stringify(peers, null, 2));
|
|
50955
51010
|
return;
|
|
@@ -50974,10 +51029,10 @@ async function runPeers(flags) {
|
|
|
50974
51029
|
// src/commands/send.ts
|
|
50975
51030
|
async function runSend(flags, to, message) {
|
|
50976
51031
|
const priority = flags.priority === "now" ? "now" : flags.priority === "low" ? "low" : "next";
|
|
50977
|
-
await withMesh({ meshSlug: flags.mesh ?? null }, async (
|
|
51032
|
+
await withMesh({ meshSlug: flags.mesh ?? null }, async (client2) => {
|
|
50978
51033
|
let targetSpec = to;
|
|
50979
51034
|
if (!to.startsWith("@") && to !== "*" && !/^[0-9a-f]{64}$/i.test(to)) {
|
|
50980
|
-
const peers = await
|
|
51035
|
+
const peers = await client2.listPeers();
|
|
50981
51036
|
const match = peers.find((p) => p.displayName.toLowerCase() === to.toLowerCase());
|
|
50982
51037
|
if (!match) {
|
|
50983
51038
|
const names = peers.map((p) => p.displayName).join(", ");
|
|
@@ -50986,7 +51041,7 @@ async function runSend(flags, to, message) {
|
|
|
50986
51041
|
}
|
|
50987
51042
|
targetSpec = match.pubkey;
|
|
50988
51043
|
}
|
|
50989
|
-
const result = await
|
|
51044
|
+
const result = await client2.send(targetSpec, message, priority);
|
|
50990
51045
|
if (result.ok) {
|
|
50991
51046
|
console.log(`✓ Sent to ${to}${result.messageId ? ` (${result.messageId.slice(0, 8)})` : ""}`);
|
|
50992
51047
|
} else {
|
|
@@ -51012,9 +51067,9 @@ async function runInbox(flags) {
|
|
|
51012
51067
|
const dim = (s) => useColor ? `\x1B[2m${s}\x1B[22m` : s;
|
|
51013
51068
|
const bold2 = (s) => useColor ? `\x1B[1m${s}\x1B[22m` : s;
|
|
51014
51069
|
const waitMs = (flags.wait ?? 1) * 1000;
|
|
51015
|
-
await withMesh({ meshSlug: flags.mesh ?? null }, async (
|
|
51070
|
+
await withMesh({ meshSlug: flags.mesh ?? null }, async (client2, mesh) => {
|
|
51016
51071
|
await new Promise((resolve2) => setTimeout(resolve2, waitMs));
|
|
51017
|
-
const messages =
|
|
51072
|
+
const messages = client2.drainPushBuffer();
|
|
51018
51073
|
if (flags.json) {
|
|
51019
51074
|
console.log(JSON.stringify(messages, null, 2));
|
|
51020
51075
|
return;
|
|
@@ -51036,8 +51091,8 @@ async function runInbox(flags) {
|
|
|
51036
51091
|
async function runStateGet(flags, key) {
|
|
51037
51092
|
const useColor = !process.env.NO_COLOR && process.env.TERM !== "dumb" && process.stdout.isTTY;
|
|
51038
51093
|
const dim = (s) => useColor ? `\x1B[2m${s}\x1B[22m` : s;
|
|
51039
|
-
await withMesh({ meshSlug: flags.mesh ?? null }, async (
|
|
51040
|
-
const entry = await
|
|
51094
|
+
await withMesh({ meshSlug: flags.mesh ?? null }, async (client2) => {
|
|
51095
|
+
const entry = await client2.getState(key);
|
|
51041
51096
|
if (!entry) {
|
|
51042
51097
|
console.log(dim(`(not set)`));
|
|
51043
51098
|
return;
|
|
@@ -51058,8 +51113,8 @@ async function runStateSet(flags, key, value) {
|
|
|
51058
51113
|
} catch {
|
|
51059
51114
|
parsed = value;
|
|
51060
51115
|
}
|
|
51061
|
-
await withMesh({ meshSlug: flags.mesh ?? null }, async (
|
|
51062
|
-
await
|
|
51116
|
+
await withMesh({ meshSlug: flags.mesh ?? null }, async (client2) => {
|
|
51117
|
+
await client2.setState(key, parsed);
|
|
51063
51118
|
console.log(`✓ ${key} = ${JSON.stringify(parsed)}`);
|
|
51064
51119
|
});
|
|
51065
51120
|
}
|
|
@@ -51067,8 +51122,8 @@ async function runStateList(flags) {
|
|
|
51067
51122
|
const useColor = !process.env.NO_COLOR && process.env.TERM !== "dumb" && process.stdout.isTTY;
|
|
51068
51123
|
const dim = (s) => useColor ? `\x1B[2m${s}\x1B[22m` : s;
|
|
51069
51124
|
const bold2 = (s) => useColor ? `\x1B[1m${s}\x1B[22m` : s;
|
|
51070
|
-
await withMesh({ meshSlug: flags.mesh ?? null }, async (
|
|
51071
|
-
const entries = await
|
|
51125
|
+
await withMesh({ meshSlug: flags.mesh ?? null }, async (client2, mesh) => {
|
|
51126
|
+
const entries = await client2.listState();
|
|
51072
51127
|
if (flags.json) {
|
|
51073
51128
|
console.log(JSON.stringify(entries, null, 2));
|
|
51074
51129
|
return;
|
|
@@ -51085,6 +51140,214 @@ async function runStateList(flags) {
|
|
|
51085
51140
|
});
|
|
51086
51141
|
}
|
|
51087
51142
|
|
|
51143
|
+
// src/commands/memory.ts
|
|
51144
|
+
async function runRemember(flags, content) {
|
|
51145
|
+
const tags = flags.tags ? flags.tags.split(",").map((t) => t.trim()).filter(Boolean) : undefined;
|
|
51146
|
+
await withMesh({ meshSlug: flags.mesh ?? null }, async (client2) => {
|
|
51147
|
+
const id = await client2.remember(content, tags);
|
|
51148
|
+
if (flags.json) {
|
|
51149
|
+
console.log(JSON.stringify({ id, content, tags }));
|
|
51150
|
+
return;
|
|
51151
|
+
}
|
|
51152
|
+
if (id) {
|
|
51153
|
+
console.log(`✓ Remembered (${id.slice(0, 8)})`);
|
|
51154
|
+
} else {
|
|
51155
|
+
console.error("✗ Failed to store memory");
|
|
51156
|
+
process.exit(1);
|
|
51157
|
+
}
|
|
51158
|
+
});
|
|
51159
|
+
}
|
|
51160
|
+
async function runRecall(flags, query) {
|
|
51161
|
+
const useColor = !process.env.NO_COLOR && process.env.TERM !== "dumb" && process.stdout.isTTY;
|
|
51162
|
+
const dim = (s) => useColor ? `\x1B[2m${s}\x1B[22m` : s;
|
|
51163
|
+
const bold2 = (s) => useColor ? `\x1B[1m${s}\x1B[22m` : s;
|
|
51164
|
+
await withMesh({ meshSlug: flags.mesh ?? null }, async (client2) => {
|
|
51165
|
+
const memories = await client2.recall(query);
|
|
51166
|
+
if (flags.json) {
|
|
51167
|
+
console.log(JSON.stringify(memories, null, 2));
|
|
51168
|
+
return;
|
|
51169
|
+
}
|
|
51170
|
+
if (memories.length === 0) {
|
|
51171
|
+
console.log(dim("No memories found."));
|
|
51172
|
+
return;
|
|
51173
|
+
}
|
|
51174
|
+
for (const m of memories) {
|
|
51175
|
+
const tags = m.tags.length ? dim(` [${m.tags.join(", ")}]`) : "";
|
|
51176
|
+
console.log(`${bold2(m.id.slice(0, 8))}${tags}`);
|
|
51177
|
+
console.log(` ${m.content}`);
|
|
51178
|
+
console.log(dim(` ${m.rememberedBy} · ${new Date(m.rememberedAt).toLocaleString()}`));
|
|
51179
|
+
console.log("");
|
|
51180
|
+
}
|
|
51181
|
+
});
|
|
51182
|
+
}
|
|
51183
|
+
|
|
51184
|
+
// src/commands/info.ts
|
|
51185
|
+
init_config();
|
|
51186
|
+
async function runInfo(flags) {
|
|
51187
|
+
const useColor = !process.env.NO_COLOR && process.env.TERM !== "dumb" && process.stdout.isTTY;
|
|
51188
|
+
const dim = (s) => useColor ? `\x1B[2m${s}\x1B[22m` : s;
|
|
51189
|
+
const bold2 = (s) => useColor ? `\x1B[1m${s}\x1B[22m` : s;
|
|
51190
|
+
const config2 = loadConfig();
|
|
51191
|
+
await withMesh({ meshSlug: flags.mesh ?? null }, async (client2, mesh) => {
|
|
51192
|
+
const [brokerInfo, peers, state] = await Promise.all([
|
|
51193
|
+
client2.meshInfo(),
|
|
51194
|
+
client2.listPeers(),
|
|
51195
|
+
client2.listState()
|
|
51196
|
+
]);
|
|
51197
|
+
const output = {
|
|
51198
|
+
slug: mesh.slug,
|
|
51199
|
+
meshId: mesh.meshId,
|
|
51200
|
+
memberId: mesh.memberId,
|
|
51201
|
+
brokerUrl: mesh.brokerUrl,
|
|
51202
|
+
displayName: config2.displayName ?? null,
|
|
51203
|
+
peerCount: peers.length,
|
|
51204
|
+
stateCount: state.length,
|
|
51205
|
+
...brokerInfo ?? {}
|
|
51206
|
+
};
|
|
51207
|
+
if (flags.json) {
|
|
51208
|
+
console.log(JSON.stringify(output, null, 2));
|
|
51209
|
+
return;
|
|
51210
|
+
}
|
|
51211
|
+
console.log(bold2(mesh.slug) + dim(` · ${mesh.brokerUrl}`));
|
|
51212
|
+
console.log(dim(` mesh: ${mesh.meshId}`));
|
|
51213
|
+
console.log(dim(` member: ${mesh.memberId}`));
|
|
51214
|
+
console.log(` peers: ${peers.length} connected`);
|
|
51215
|
+
console.log(` state: ${state.length} keys`);
|
|
51216
|
+
if (brokerInfo && typeof brokerInfo === "object") {
|
|
51217
|
+
for (const [k, v] of Object.entries(brokerInfo)) {
|
|
51218
|
+
if (["slug", "meshId", "brokerUrl"].includes(k))
|
|
51219
|
+
continue;
|
|
51220
|
+
console.log(dim(` ${k}: ${JSON.stringify(v)}`));
|
|
51221
|
+
}
|
|
51222
|
+
}
|
|
51223
|
+
});
|
|
51224
|
+
}
|
|
51225
|
+
|
|
51226
|
+
// src/commands/remind.ts
|
|
51227
|
+
function parseDuration(raw) {
|
|
51228
|
+
const m = raw.trim().match(/^(\d+(?:\.\d+)?)\s*(s|sec|m|min|h|hr|d|day)?$/i);
|
|
51229
|
+
if (!m)
|
|
51230
|
+
return null;
|
|
51231
|
+
const n = parseFloat(m[1]);
|
|
51232
|
+
const unit = (m[2] ?? "s").toLowerCase();
|
|
51233
|
+
if (unit.startsWith("d"))
|
|
51234
|
+
return n * 86400000;
|
|
51235
|
+
if (unit.startsWith("h"))
|
|
51236
|
+
return n * 3600000;
|
|
51237
|
+
if (unit.startsWith("m"))
|
|
51238
|
+
return n * 60000;
|
|
51239
|
+
return n * 1000;
|
|
51240
|
+
}
|
|
51241
|
+
function parseDeliverAt(flags) {
|
|
51242
|
+
if (flags.in) {
|
|
51243
|
+
const ms = parseDuration(flags.in);
|
|
51244
|
+
if (ms === null)
|
|
51245
|
+
return null;
|
|
51246
|
+
return Date.now() + ms;
|
|
51247
|
+
}
|
|
51248
|
+
if (flags.at) {
|
|
51249
|
+
const hm = flags.at.match(/^(\d{1,2}):(\d{2})$/);
|
|
51250
|
+
if (hm) {
|
|
51251
|
+
const now = new Date;
|
|
51252
|
+
const target = new Date(now);
|
|
51253
|
+
target.setHours(parseInt(hm[1], 10), parseInt(hm[2], 10), 0, 0);
|
|
51254
|
+
if (target <= now)
|
|
51255
|
+
target.setDate(target.getDate() + 1);
|
|
51256
|
+
return target.getTime();
|
|
51257
|
+
}
|
|
51258
|
+
const ts = Date.parse(flags.at);
|
|
51259
|
+
return isNaN(ts) ? null : ts;
|
|
51260
|
+
}
|
|
51261
|
+
return null;
|
|
51262
|
+
}
|
|
51263
|
+
async function runRemind(flags, positional) {
|
|
51264
|
+
const useColor = !process.env.NO_COLOR && process.env.TERM !== "dumb" && process.stdout.isTTY;
|
|
51265
|
+
const dim = (s) => useColor ? `\x1B[2m${s}\x1B[22m` : s;
|
|
51266
|
+
const bold2 = (s) => useColor ? `\x1B[1m${s}\x1B[22m` : s;
|
|
51267
|
+
const action = positional[0];
|
|
51268
|
+
if (action === "list") {
|
|
51269
|
+
await withMesh({ meshSlug: flags.mesh ?? null }, async (client2) => {
|
|
51270
|
+
const scheduled = await client2.listScheduled();
|
|
51271
|
+
if (flags.json) {
|
|
51272
|
+
console.log(JSON.stringify(scheduled, null, 2));
|
|
51273
|
+
return;
|
|
51274
|
+
}
|
|
51275
|
+
if (scheduled.length === 0) {
|
|
51276
|
+
console.log(dim("No pending reminders."));
|
|
51277
|
+
return;
|
|
51278
|
+
}
|
|
51279
|
+
for (const m of scheduled) {
|
|
51280
|
+
const when = new Date(m.deliverAt).toLocaleString();
|
|
51281
|
+
const to = m.to === client2.getSessionPubkey() ? dim("(self)") : m.to;
|
|
51282
|
+
console.log(` ${bold2(m.id.slice(0, 8))} → ${to} at ${when}`);
|
|
51283
|
+
console.log(` ${dim(m.message.slice(0, 80))}`);
|
|
51284
|
+
console.log("");
|
|
51285
|
+
}
|
|
51286
|
+
});
|
|
51287
|
+
return;
|
|
51288
|
+
}
|
|
51289
|
+
if (action === "cancel") {
|
|
51290
|
+
const id = positional[1];
|
|
51291
|
+
if (!id) {
|
|
51292
|
+
console.error("Usage: claudemesh remind cancel <id>");
|
|
51293
|
+
process.exit(1);
|
|
51294
|
+
}
|
|
51295
|
+
await withMesh({ meshSlug: flags.mesh ?? null }, async (client2) => {
|
|
51296
|
+
const ok = await client2.cancelScheduled(id);
|
|
51297
|
+
if (ok)
|
|
51298
|
+
console.log(`✓ Cancelled ${id}`);
|
|
51299
|
+
else {
|
|
51300
|
+
console.error(`✗ Not found or already fired: ${id}`);
|
|
51301
|
+
process.exit(1);
|
|
51302
|
+
}
|
|
51303
|
+
});
|
|
51304
|
+
return;
|
|
51305
|
+
}
|
|
51306
|
+
const message = action ?? positional.join(" ");
|
|
51307
|
+
if (!message) {
|
|
51308
|
+
console.error("Usage: claudemesh remind <message> --in <duration>");
|
|
51309
|
+
console.error(" claudemesh remind <message> --at <time>");
|
|
51310
|
+
console.error(" claudemesh remind list");
|
|
51311
|
+
console.error(" claudemesh remind cancel <id>");
|
|
51312
|
+
process.exit(1);
|
|
51313
|
+
}
|
|
51314
|
+
const deliverAt = parseDeliverAt(flags);
|
|
51315
|
+
if (deliverAt === null) {
|
|
51316
|
+
console.error('Specify when: --in <duration> (e.g. "2h", "30m") or --at <time> (e.g. "15:00")');
|
|
51317
|
+
process.exit(1);
|
|
51318
|
+
}
|
|
51319
|
+
await withMesh({ meshSlug: flags.mesh ?? null }, async (client2) => {
|
|
51320
|
+
let targetSpec;
|
|
51321
|
+
if (flags.to && flags.to !== "self") {
|
|
51322
|
+
if (flags.to.startsWith("@") || flags.to === "*" || /^[0-9a-f]{64}$/i.test(flags.to)) {
|
|
51323
|
+
targetSpec = flags.to;
|
|
51324
|
+
} else {
|
|
51325
|
+
const peers = await client2.listPeers();
|
|
51326
|
+
const match = peers.find((p) => p.displayName.toLowerCase() === flags.to.toLowerCase());
|
|
51327
|
+
if (!match) {
|
|
51328
|
+
console.error(`Peer "${flags.to}" not found. Online: ${peers.map((p) => p.displayName).join(", ") || "(none)"}`);
|
|
51329
|
+
process.exit(1);
|
|
51330
|
+
}
|
|
51331
|
+
targetSpec = match.pubkey;
|
|
51332
|
+
}
|
|
51333
|
+
} else {
|
|
51334
|
+
targetSpec = client2.getSessionPubkey() ?? "*";
|
|
51335
|
+
}
|
|
51336
|
+
const result = await client2.scheduleMessage(targetSpec, message, deliverAt);
|
|
51337
|
+
if (!result) {
|
|
51338
|
+
console.error("✗ Broker did not acknowledge — check connection");
|
|
51339
|
+
process.exit(1);
|
|
51340
|
+
}
|
|
51341
|
+
if (flags.json) {
|
|
51342
|
+
console.log(JSON.stringify(result));
|
|
51343
|
+
return;
|
|
51344
|
+
}
|
|
51345
|
+
const when = new Date(result.deliverAt).toLocaleString();
|
|
51346
|
+
const toLabel = !flags.to || flags.to === "self" ? "yourself" : flags.to;
|
|
51347
|
+
console.log(`✓ Reminder set (${result.scheduledId.slice(0, 8)}): "${message}" → ${toLabel} at ${when}`);
|
|
51348
|
+
});
|
|
51349
|
+
}
|
|
51350
|
+
|
|
51088
51351
|
// src/index.ts
|
|
51089
51352
|
var launch = defineCommand({
|
|
51090
51353
|
meta: {
|
|
@@ -51270,6 +51533,55 @@ var main = defineCommand({
|
|
|
51270
51533
|
}
|
|
51271
51534
|
}
|
|
51272
51535
|
}),
|
|
51536
|
+
info: defineCommand({
|
|
51537
|
+
meta: { name: "info", description: "Show mesh overview: slug, broker, peer count, state keys" },
|
|
51538
|
+
args: {
|
|
51539
|
+
mesh: { type: "string", description: "Mesh slug (auto-selected if only one joined)" },
|
|
51540
|
+
json: { type: "boolean", description: "Output as JSON", default: false }
|
|
51541
|
+
},
|
|
51542
|
+
async run({ args }) {
|
|
51543
|
+
await runInfo(args);
|
|
51544
|
+
}
|
|
51545
|
+
}),
|
|
51546
|
+
remember: defineCommand({
|
|
51547
|
+
meta: { name: "remember", description: "Store a memory in the mesh (accessible to all peers)" },
|
|
51548
|
+
args: {
|
|
51549
|
+
content: { type: "positional", description: "Text to remember", required: true },
|
|
51550
|
+
mesh: { type: "string", description: "Mesh slug (auto-selected if only one joined)" },
|
|
51551
|
+
tags: { type: "string", description: "Comma-separated tags (e.g. task,context)" },
|
|
51552
|
+
json: { type: "boolean", description: "Output as JSON", default: false }
|
|
51553
|
+
},
|
|
51554
|
+
async run({ args }) {
|
|
51555
|
+
await runRemember(args, args.content);
|
|
51556
|
+
}
|
|
51557
|
+
}),
|
|
51558
|
+
recall: defineCommand({
|
|
51559
|
+
meta: { name: "recall", description: "Search mesh memory by keyword or phrase" },
|
|
51560
|
+
args: {
|
|
51561
|
+
query: { type: "positional", description: "Search query", required: true },
|
|
51562
|
+
mesh: { type: "string", description: "Mesh slug (auto-selected if only one joined)" },
|
|
51563
|
+
json: { type: "boolean", description: "Output as JSON", default: false }
|
|
51564
|
+
},
|
|
51565
|
+
async run({ args }) {
|
|
51566
|
+
await runRecall(args, args.query);
|
|
51567
|
+
}
|
|
51568
|
+
}),
|
|
51569
|
+
remind: defineCommand({
|
|
51570
|
+
meta: { name: "remind", description: "Schedule a reminder or delayed message via the broker" },
|
|
51571
|
+
args: {
|
|
51572
|
+
message: { type: "positional", description: "Message text, or: list | cancel <id>", required: false },
|
|
51573
|
+
extra: { type: "positional", description: "Additional positional args", required: false },
|
|
51574
|
+
in: { type: "string", description: 'Deliver after duration: "2h", "30m", "90s"' },
|
|
51575
|
+
at: { type: "string", description: 'Deliver at time: "15:00" or ISO timestamp' },
|
|
51576
|
+
to: { type: "string", description: "Recipient (default: self). Name, @group, pubkey, or *" },
|
|
51577
|
+
mesh: { type: "string", description: "Mesh slug (auto-selected if only one joined)" },
|
|
51578
|
+
json: { type: "boolean", description: "Output as JSON", default: false }
|
|
51579
|
+
},
|
|
51580
|
+
async run({ args, rawArgs }) {
|
|
51581
|
+
const positionals = rawArgs.filter((a) => !a.startsWith("-"));
|
|
51582
|
+
await runRemind(args, positionals);
|
|
51583
|
+
}
|
|
51584
|
+
}),
|
|
51273
51585
|
status: defineCommand({
|
|
51274
51586
|
meta: { name: "status", description: "Check broker reachability for each joined mesh" },
|
|
51275
51587
|
async run() {
|