@studiomopoke/crosschat 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +62 -0
- package/README.md +279 -0
- package/bin/cli.cjs +631 -0
- package/crosschat.md +196 -0
- package/dashboard/dist/assets/index-Blgmbgo_.css +1 -0
- package/dashboard/dist/assets/index-DzcjxzDR.js +49 -0
- package/dashboard/dist/index.html +13 -0
- package/dist/dashboard/dashboard-listener.d.ts +22 -0
- package/dist/dashboard/dashboard-listener.d.ts.map +1 -0
- package/dist/dashboard/dashboard-listener.js +124 -0
- package/dist/dashboard/dashboard-listener.js.map +1 -0
- package/dist/dashboard/http-server.d.ts +25 -0
- package/dist/dashboard/http-server.d.ts.map +1 -0
- package/dist/dashboard/http-server.js +281 -0
- package/dist/dashboard/http-server.js.map +1 -0
- package/dist/dashboard/message-bridge.d.ts +19 -0
- package/dist/dashboard/message-bridge.d.ts.map +1 -0
- package/dist/dashboard/message-bridge.js +48 -0
- package/dist/dashboard/message-bridge.js.map +1 -0
- package/dist/hub/agent-connection.d.ts +101 -0
- package/dist/hub/agent-connection.d.ts.map +1 -0
- package/dist/hub/agent-connection.js +383 -0
- package/dist/hub/agent-connection.js.map +1 -0
- package/dist/hub/hub-main.d.ts +2 -0
- package/dist/hub/hub-main.d.ts.map +1 -0
- package/dist/hub/hub-main.js +16 -0
- package/dist/hub/hub-main.js.map +1 -0
- package/dist/hub/hub-server.d.ts +8 -0
- package/dist/hub/hub-server.d.ts.map +1 -0
- package/dist/hub/hub-server.js +1500 -0
- package/dist/hub/hub-server.js.map +1 -0
- package/dist/hub/protocol.d.ts +221 -0
- package/dist/hub/protocol.d.ts.map +1 -0
- package/dist/hub/protocol.js +20 -0
- package/dist/hub/protocol.js.map +1 -0
- package/dist/hub/task-manager.d.ts +68 -0
- package/dist/hub/task-manager.d.ts.map +1 -0
- package/dist/hub/task-manager.js +250 -0
- package/dist/hub/task-manager.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/lifecycle.d.ts +2 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +234 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/prompts.d.ts +3 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +48 -0
- package/dist/prompts.js.map +1 -0
- package/dist/registry/cleanup.d.ts +2 -0
- package/dist/registry/cleanup.d.ts.map +1 -0
- package/dist/registry/cleanup.js +60 -0
- package/dist/registry/cleanup.js.map +1 -0
- package/dist/registry/registry.d.ts +11 -0
- package/dist/registry/registry.d.ts.map +1 -0
- package/dist/registry/registry.js +82 -0
- package/dist/registry/registry.js.map +1 -0
- package/dist/server.d.ts +9 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +91 -0
- package/dist/server.js.map +1 -0
- package/dist/stores/message-store.d.ts +21 -0
- package/dist/stores/message-store.d.ts.map +1 -0
- package/dist/stores/message-store.js +83 -0
- package/dist/stores/message-store.js.map +1 -0
- package/dist/stores/task-store.d.ts +15 -0
- package/dist/stores/task-store.d.ts.map +1 -0
- package/dist/stores/task-store.js +57 -0
- package/dist/stores/task-store.js.map +1 -0
- package/dist/tools/accept-claim.d.ts +4 -0
- package/dist/tools/accept-claim.d.ts.map +1 -0
- package/dist/tools/accept-claim.js +27 -0
- package/dist/tools/accept-claim.js.map +1 -0
- package/dist/tools/chat-send.d.ts +4 -0
- package/dist/tools/chat-send.d.ts.map +1 -0
- package/dist/tools/chat-send.js +19 -0
- package/dist/tools/chat-send.js.map +1 -0
- package/dist/tools/claim-task.d.ts +4 -0
- package/dist/tools/claim-task.d.ts.map +1 -0
- package/dist/tools/claim-task.js +26 -0
- package/dist/tools/claim-task.js.map +1 -0
- package/dist/tools/clear-session.d.ts +5 -0
- package/dist/tools/clear-session.d.ts.map +1 -0
- package/dist/tools/clear-session.js +41 -0
- package/dist/tools/clear-session.js.map +1 -0
- package/dist/tools/complete-task.d.ts +4 -0
- package/dist/tools/complete-task.d.ts.map +1 -0
- package/dist/tools/complete-task.js +29 -0
- package/dist/tools/complete-task.js.map +1 -0
- package/dist/tools/create-room.d.ts +4 -0
- package/dist/tools/create-room.d.ts.map +1 -0
- package/dist/tools/create-room.js +28 -0
- package/dist/tools/create-room.js.map +1 -0
- package/dist/tools/delegate-task.d.ts +4 -0
- package/dist/tools/delegate-task.d.ts.map +1 -0
- package/dist/tools/delegate-task.js +32 -0
- package/dist/tools/delegate-task.js.map +1 -0
- package/dist/tools/get-messages.d.ts +4 -0
- package/dist/tools/get-messages.d.ts.map +1 -0
- package/dist/tools/get-messages.js +35 -0
- package/dist/tools/get-messages.js.map +1 -0
- package/dist/tools/get-room-digest.d.ts +4 -0
- package/dist/tools/get-room-digest.d.ts.map +1 -0
- package/dist/tools/get-room-digest.js +63 -0
- package/dist/tools/get-room-digest.js.map +1 -0
- package/dist/tools/get-task-status.d.ts +4 -0
- package/dist/tools/get-task-status.d.ts.map +1 -0
- package/dist/tools/get-task-status.js +26 -0
- package/dist/tools/get-task-status.js.map +1 -0
- package/dist/tools/join-room.d.ts +4 -0
- package/dist/tools/join-room.d.ts.map +1 -0
- package/dist/tools/join-room.js +26 -0
- package/dist/tools/join-room.js.map +1 -0
- package/dist/tools/list-peers.d.ts +4 -0
- package/dist/tools/list-peers.d.ts.map +1 -0
- package/dist/tools/list-peers.js +26 -0
- package/dist/tools/list-peers.js.map +1 -0
- package/dist/tools/list-tasks.d.ts +4 -0
- package/dist/tools/list-tasks.d.ts.map +1 -0
- package/dist/tools/list-tasks.js +28 -0
- package/dist/tools/list-tasks.js.map +1 -0
- package/dist/tools/send-message.d.ts +4 -0
- package/dist/tools/send-message.d.ts.map +1 -0
- package/dist/tools/send-message.js +28 -0
- package/dist/tools/send-message.js.map +1 -0
- package/dist/tools/set-status.d.ts +4 -0
- package/dist/tools/set-status.d.ts.map +1 -0
- package/dist/tools/set-status.js +28 -0
- package/dist/tools/set-status.js.map +1 -0
- package/dist/tools/update-task.d.ts +4 -0
- package/dist/tools/update-task.d.ts.map +1 -0
- package/dist/tools/update-task.js +28 -0
- package/dist/tools/update-task.js.map +1 -0
- package/dist/tools/wait-for-messages.d.ts +4 -0
- package/dist/tools/wait-for-messages.d.ts.map +1 -0
- package/dist/tools/wait-for-messages.js +84 -0
- package/dist/tools/wait-for-messages.js.map +1 -0
- package/dist/transport/peer-protocol.d.ts +7 -0
- package/dist/transport/peer-protocol.d.ts.map +1 -0
- package/dist/transport/peer-protocol.js +30 -0
- package/dist/transport/peer-protocol.js.map +1 -0
- package/dist/transport/uds-client.d.ts +3 -0
- package/dist/transport/uds-client.d.ts.map +1 -0
- package/dist/transport/uds-client.js +57 -0
- package/dist/transport/uds-client.js.map +1 -0
- package/dist/transport/uds-server.d.ts +12 -0
- package/dist/transport/uds-server.d.ts.map +1 -0
- package/dist/transport/uds-server.js +87 -0
- package/dist/transport/uds-server.js.map +1 -0
- package/dist/types.d.ts +18 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/util/id.d.ts +2 -0
- package/dist/util/id.d.ts.map +1 -0
- package/dist/util/id.js +5 -0
- package/dist/util/id.js.map +1 -0
- package/dist/util/logger.d.ts +3 -0
- package/dist/util/logger.d.ts.map +1 -0
- package/dist/util/logger.js +13 -0
- package/dist/util/logger.js.map +1 -0
- package/dist/util/pid.d.ts +2 -0
- package/dist/util/pid.d.ts.map +1 -0
- package/dist/util/pid.js +10 -0
- package/dist/util/pid.js.map +1 -0
- package/hooks/permission-hook.sh +116 -0
- package/package.json +59 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { isProcessAlive } from '../util/pid.js';
|
|
4
|
+
import { log, logError } from '../util/logger.js';
|
|
5
|
+
import { getPeersDir, getSocketPath } from './registry.js';
|
|
6
|
+
export async function pruneStaleEntries(ownPeerId) {
|
|
7
|
+
const peersDir = getPeersDir();
|
|
8
|
+
let files;
|
|
9
|
+
try {
|
|
10
|
+
files = await fs.readdir(peersDir);
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
for (const file of files) {
|
|
16
|
+
if (!file.endsWith('.json'))
|
|
17
|
+
continue;
|
|
18
|
+
const filePath = path.join(peersDir, file);
|
|
19
|
+
let entry;
|
|
20
|
+
try {
|
|
21
|
+
const data = await fs.readFile(filePath, 'utf-8');
|
|
22
|
+
entry = JSON.parse(data);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
// Malformed file — remove it
|
|
26
|
+
log(`Removing malformed registry file: ${file}`);
|
|
27
|
+
await safeUnlink(filePath);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
// Don't prune ourselves
|
|
31
|
+
if (ownPeerId && entry.peerId === ownPeerId)
|
|
32
|
+
continue;
|
|
33
|
+
// Check if peer is still alive
|
|
34
|
+
if (!isProcessAlive(entry.pid)) {
|
|
35
|
+
log(`Pruning stale peer: ${entry.name} (${entry.peerId}, pid ${entry.pid})`);
|
|
36
|
+
await safeUnlink(filePath);
|
|
37
|
+
await safeUnlink(getSocketPath(entry.peerId));
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
// Check if socket file exists
|
|
41
|
+
try {
|
|
42
|
+
await fs.access(entry.socketPath);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
log(`Pruning peer with missing socket: ${entry.name} (${entry.peerId})`);
|
|
46
|
+
await safeUnlink(filePath);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async function safeUnlink(filePath) {
|
|
51
|
+
try {
|
|
52
|
+
await fs.unlink(filePath);
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
if (err.code !== 'ENOENT') {
|
|
56
|
+
logError(`Failed to unlink ${filePath}`, err);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=cleanup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup.js","sourceRoot":"","sources":["../../src/registry/cleanup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG3D,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,SAAkB;IACxD,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,IAAI,KAAe,CAAC;IACpB,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,SAAS;QACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAE3C,IAAI,KAAwB,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAClD,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAsB,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,6BAA6B;YAC7B,GAAG,CAAC,qCAAqC,IAAI,EAAE,CAAC,CAAC;YACjD,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;YAC3B,SAAS;QACX,CAAC;QAED,wBAAwB;QACxB,IAAI,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;YAAE,SAAS;QAEtD,+BAA+B;QAC/B,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,GAAG,CAAC,uBAAuB,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,SAAS,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;YAC7E,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;YAC3B,MAAM,UAAU,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YAC9C,SAAS;QACX,CAAC;QAED,8BAA8B;QAC9B,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,CAAC,qCAAqC,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;YACzE,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;AACH,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,QAAgB;IACxC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,QAAQ,CAAC,oBAAoB,QAAQ,EAAE,EAAE,GAAG,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PeerRegistryEntry } from '../types.js';
|
|
2
|
+
export declare function getPeersDir(): string;
|
|
3
|
+
export declare function getSocketsDir(): string;
|
|
4
|
+
export declare function getSocketPath(peerId: string): string;
|
|
5
|
+
export declare function ensureDirectories(): Promise<void>;
|
|
6
|
+
export declare function writeRegistryEntry(entry: PeerRegistryEntry): Promise<void>;
|
|
7
|
+
export declare function removeRegistryEntry(peerId: string): Promise<void>;
|
|
8
|
+
export declare function removeSocketFile(peerId: string): Promise<void>;
|
|
9
|
+
export declare function readRegistryEntry(peerId: string): Promise<PeerRegistryEntry | null>;
|
|
10
|
+
export declare function listRegistryEntries(): Promise<PeerRegistryEntry[]>;
|
|
11
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/registry/registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAOrD,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAGvD;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAMhF;AAED,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASvE;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASpE;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAQzF;AAED,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAmBxE"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import { log, logError } from '../util/logger.js';
|
|
5
|
+
const CROSSCHAT_DIR = path.join(os.homedir(), '.crosschat');
|
|
6
|
+
const PEERS_DIR = path.join(CROSSCHAT_DIR, 'peers');
|
|
7
|
+
const SOCKETS_DIR = path.join(CROSSCHAT_DIR, 'sockets');
|
|
8
|
+
export function getPeersDir() {
|
|
9
|
+
return PEERS_DIR;
|
|
10
|
+
}
|
|
11
|
+
export function getSocketsDir() {
|
|
12
|
+
return SOCKETS_DIR;
|
|
13
|
+
}
|
|
14
|
+
export function getSocketPath(peerId) {
|
|
15
|
+
return path.join(SOCKETS_DIR, `${peerId}.sock`);
|
|
16
|
+
}
|
|
17
|
+
export async function ensureDirectories() {
|
|
18
|
+
await fs.mkdir(PEERS_DIR, { recursive: true });
|
|
19
|
+
await fs.mkdir(SOCKETS_DIR, { recursive: true });
|
|
20
|
+
}
|
|
21
|
+
export async function writeRegistryEntry(entry) {
|
|
22
|
+
const filePath = path.join(PEERS_DIR, `${entry.peerId}.json`);
|
|
23
|
+
const tmpPath = `${filePath}.tmp`;
|
|
24
|
+
await fs.writeFile(tmpPath, JSON.stringify(entry, null, 2), 'utf-8');
|
|
25
|
+
await fs.rename(tmpPath, filePath);
|
|
26
|
+
log(`Registered peer: ${entry.name} (${entry.peerId})`);
|
|
27
|
+
}
|
|
28
|
+
export async function removeRegistryEntry(peerId) {
|
|
29
|
+
const filePath = path.join(PEERS_DIR, `${peerId}.json`);
|
|
30
|
+
try {
|
|
31
|
+
await fs.unlink(filePath);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
if (err.code !== 'ENOENT') {
|
|
35
|
+
logError('Failed to remove registry entry', err);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export async function removeSocketFile(peerId) {
|
|
40
|
+
const sockPath = getSocketPath(peerId);
|
|
41
|
+
try {
|
|
42
|
+
await fs.unlink(sockPath);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
if (err.code !== 'ENOENT') {
|
|
46
|
+
logError('Failed to remove socket file', err);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export async function readRegistryEntry(peerId) {
|
|
51
|
+
const filePath = path.join(PEERS_DIR, `${peerId}.json`);
|
|
52
|
+
try {
|
|
53
|
+
const data = await fs.readFile(filePath, 'utf-8');
|
|
54
|
+
return JSON.parse(data);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export async function listRegistryEntries() {
|
|
61
|
+
const entries = [];
|
|
62
|
+
let files;
|
|
63
|
+
try {
|
|
64
|
+
files = await fs.readdir(PEERS_DIR);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return entries;
|
|
68
|
+
}
|
|
69
|
+
for (const file of files) {
|
|
70
|
+
if (!file.endsWith('.json'))
|
|
71
|
+
continue;
|
|
72
|
+
try {
|
|
73
|
+
const data = await fs.readFile(path.join(PEERS_DIR, file), 'utf-8');
|
|
74
|
+
entries.push(JSON.parse(data));
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// Skip malformed entries — cleanup will handle them
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return entries;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/registry/registry.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { MessageStore } from './stores/message-store.js';
|
|
3
|
+
import type { AgentConnection } from './hub/agent-connection.js';
|
|
4
|
+
export declare function createMcpServer(peerId: string, peerName: string, messageStore: MessageStore, agentConnection: AgentConnection, dashboardInfo: {
|
|
5
|
+
port: number;
|
|
6
|
+
} | {
|
|
7
|
+
error: string;
|
|
8
|
+
}): McpServer;
|
|
9
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AA8CjE,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,YAAY,EAC1B,eAAe,EAAE,eAAe,EAChC,aAAa,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAClD,SAAS,CAsDX"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
+
const require = createRequire(import.meta.url);
|
|
4
|
+
const pkg = require('../package.json');
|
|
5
|
+
import { registerSendMessage } from './tools/send-message.js';
|
|
6
|
+
import { registerGetMessages } from './tools/get-messages.js';
|
|
7
|
+
import { registerWaitForMessages } from './tools/wait-for-messages.js';
|
|
8
|
+
import { registerListPeers } from './tools/list-peers.js';
|
|
9
|
+
import { registerSetStatus } from './tools/set-status.js';
|
|
10
|
+
import { registerJoinRoom } from './tools/join-room.js';
|
|
11
|
+
import { registerCreateRoom } from './tools/create-room.js';
|
|
12
|
+
import { registerDelegateTask } from './tools/delegate-task.js';
|
|
13
|
+
import { registerClaimTask } from './tools/claim-task.js';
|
|
14
|
+
import { registerAcceptClaim } from './tools/accept-claim.js';
|
|
15
|
+
import { registerUpdateTask } from './tools/update-task.js';
|
|
16
|
+
import { registerCompleteTask } from './tools/complete-task.js';
|
|
17
|
+
import { registerListTasks } from './tools/list-tasks.js';
|
|
18
|
+
import { registerGetTaskStatus } from './tools/get-task-status.js';
|
|
19
|
+
import { registerClearSession } from './tools/clear-session.js';
|
|
20
|
+
import { registerGetRoomDigest } from './tools/get-room-digest.js';
|
|
21
|
+
import { registerPrompts } from './prompts.js';
|
|
22
|
+
const SERVER_INSTRUCTIONS = `\
|
|
23
|
+
CrossChat connects you to other Claude Code instances on this machine through a central hub server. \
|
|
24
|
+
All communication happens through rooms — you are in one room at a time (default: "general").
|
|
25
|
+
|
|
26
|
+
Your identity: **{peerName}** (peer ID: {peerId}). You are automatically registered and discoverable.
|
|
27
|
+
|
|
28
|
+
## @mentions
|
|
29
|
+
\`@agent-name\` delivers only to that agent. \`@here\` broadcasts to everyone. No mention = broadcast to all.
|
|
30
|
+
|
|
31
|
+
## Task lifecycle
|
|
32
|
+
Tasks follow: **delegate -> claim -> accept -> update -> complete**
|
|
33
|
+
|
|
34
|
+
## Dashboard
|
|
35
|
+
{dashboardInfo}
|
|
36
|
+
|
|
37
|
+
## Key rules
|
|
38
|
+
- Use \`list_peers\` to discover peer IDs — never guess UUIDs.
|
|
39
|
+
- All messaging is room-based — no direct P2P messaging.
|
|
40
|
+
- Check a peer's status before delegating — don't send work to busy peers.
|
|
41
|
+
- Set yourself to "busy" when working on a task, "available" when done.
|
|
42
|
+
- Tasks are persistent and survive hub restarts. Messages are ephemeral.
|
|
43
|
+
- Rooms are capped at 200 messages. Old messages are digested automatically via the task system.
|
|
44
|
+
- Use \`get_room_digest\` when joining a room to catch up on prior discussion.
|
|
45
|
+
- Tag messages with \`importance\`: "important", "comment" (default), or "chitchat".
|
|
46
|
+
|
|
47
|
+
For full usage instructions, the user should run the /crosschat command.`;
|
|
48
|
+
export function createMcpServer(peerId, peerName, messageStore, agentConnection, dashboardInfo) {
|
|
49
|
+
let dashboardInfoStr;
|
|
50
|
+
if ('port' in dashboardInfo) {
|
|
51
|
+
dashboardInfoStr = `Running at http://localhost:${dashboardInfo.port}`;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
dashboardInfoStr = `Failed to start: ${dashboardInfo.error}`;
|
|
55
|
+
}
|
|
56
|
+
const instructions = SERVER_INSTRUCTIONS
|
|
57
|
+
.replace('{peerName}', peerName)
|
|
58
|
+
.replace('{peerId}', peerId)
|
|
59
|
+
.replace('{dashboardInfo}', dashboardInfoStr);
|
|
60
|
+
const server = new McpServer({
|
|
61
|
+
name: 'crosschat',
|
|
62
|
+
version: pkg.version,
|
|
63
|
+
description: 'Inter-instance communication for Claude Code and other LLM agents on a single device.',
|
|
64
|
+
}, { instructions });
|
|
65
|
+
// --- Messaging tools ---
|
|
66
|
+
registerSendMessage(server, agentConnection);
|
|
67
|
+
registerGetMessages(server, messageStore);
|
|
68
|
+
registerWaitForMessages(server, messageStore);
|
|
69
|
+
// --- Peer tools ---
|
|
70
|
+
registerListPeers(server, agentConnection);
|
|
71
|
+
registerSetStatus(server, agentConnection);
|
|
72
|
+
// --- Room tools ---
|
|
73
|
+
registerJoinRoom(server, agentConnection);
|
|
74
|
+
registerCreateRoom(server, agentConnection);
|
|
75
|
+
// --- Session tools ---
|
|
76
|
+
registerClearSession(server, agentConnection, messageStore);
|
|
77
|
+
// --- Digest tools ---
|
|
78
|
+
registerGetRoomDigest(server, agentConnection);
|
|
79
|
+
// --- Task tools ---
|
|
80
|
+
registerDelegateTask(server, agentConnection);
|
|
81
|
+
registerClaimTask(server, agentConnection);
|
|
82
|
+
registerAcceptClaim(server, agentConnection);
|
|
83
|
+
registerUpdateTask(server, agentConnection);
|
|
84
|
+
registerCompleteTask(server, agentConnection);
|
|
85
|
+
registerListTasks(server, agentConnection);
|
|
86
|
+
registerGetTaskStatus(server, agentConnection);
|
|
87
|
+
// --- Prompts ---
|
|
88
|
+
registerPrompts(server, peerId, peerName);
|
|
89
|
+
return server;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;AAG9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;yEAyB6C,CAAC;AAE1E,MAAM,UAAU,eAAe,CAC7B,MAAc,EACd,QAAgB,EAChB,YAA0B,EAC1B,eAAgC,EAChC,aAAmD;IAEnD,IAAI,gBAAwB,CAAC;IAC7B,IAAI,MAAM,IAAI,aAAa,EAAE,CAAC;QAC5B,gBAAgB,GAAG,+BAA+B,aAAa,CAAC,IAAI,EAAE,CAAC;IACzE,CAAC;SAAM,CAAC;QACN,gBAAgB,GAAG,oBAAoB,aAAa,CAAC,KAAK,EAAE,CAAC;IAC/D,CAAC;IAED,MAAM,YAAY,GAAG,mBAAmB;SACrC,OAAO,CAAC,YAAY,EAAE,QAAQ,CAAC;SAC/B,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC;SAC3B,OAAO,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,CAAC;IAEhD,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,WAAW,EAAE,uFAAuF;KACrG,EACD,EAAE,YAAY,EAAE,CACjB,CAAC;IAEF,0BAA0B;IAC1B,mBAAmB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC7C,mBAAmB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC1C,uBAAuB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAE9C,qBAAqB;IACrB,iBAAiB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC3C,iBAAiB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAE3C,qBAAqB;IACrB,gBAAgB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC1C,kBAAkB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAE5C,wBAAwB;IACxB,oBAAoB,CAAC,MAAM,EAAE,eAAe,EAAE,YAAY,CAAC,CAAC;IAE5D,uBAAuB;IACvB,qBAAqB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAE/C,qBAAqB;IACrB,oBAAoB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC9C,iBAAiB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC3C,mBAAmB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC7C,kBAAkB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC5C,oBAAoB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC9C,iBAAiB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC3C,qBAAqB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAE/C,kBAAkB;IAClB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAE1C,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { PeerMessage } from '../types.js';
|
|
2
|
+
type MessageListener = (message: PeerMessage) => void;
|
|
3
|
+
export declare class MessageStore {
|
|
4
|
+
private messages;
|
|
5
|
+
private waiters;
|
|
6
|
+
private listeners;
|
|
7
|
+
add(message: PeerMessage): void;
|
|
8
|
+
onMessage(listener: MessageListener): () => void;
|
|
9
|
+
waitForNext(timeoutMs: number): Promise<PeerMessage | null>;
|
|
10
|
+
getAll(opts?: {
|
|
11
|
+
fromPeerId?: string;
|
|
12
|
+
afterMessageId?: string;
|
|
13
|
+
limit?: number;
|
|
14
|
+
unreadOnly?: boolean;
|
|
15
|
+
}): PeerMessage[];
|
|
16
|
+
markAsRead(messageIds: string[]): void;
|
|
17
|
+
markAllAsRead(): void;
|
|
18
|
+
clear(): number;
|
|
19
|
+
}
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=message-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-store.d.ts","sourceRoot":"","sources":["../../src/stores/message-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,KAAK,eAAe,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;AAItD,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,SAAS,CAAyB;IAE1C,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAmB/B,SAAS,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,IAAI;IAQhD,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAiB3D,MAAM,CAAC,IAAI,CAAC,EAAE;QACZ,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,GAAG,WAAW,EAAE;IAyBjB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI;IAStC,aAAa,IAAI,IAAI;IAMrB,KAAK,IAAI,MAAM;CAKhB"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
const MESSAGE_CAP = 200;
|
|
2
|
+
export class MessageStore {
|
|
3
|
+
messages = [];
|
|
4
|
+
waiters = [];
|
|
5
|
+
listeners = [];
|
|
6
|
+
add(message) {
|
|
7
|
+
this.messages.push(message);
|
|
8
|
+
// Enforce client-side cap — drop oldest messages when exceeded
|
|
9
|
+
if (this.messages.length > MESSAGE_CAP) {
|
|
10
|
+
this.messages = this.messages.slice(this.messages.length - MESSAGE_CAP);
|
|
11
|
+
}
|
|
12
|
+
// Wake up anyone waiting
|
|
13
|
+
const toNotify = this.waiters.splice(0);
|
|
14
|
+
for (const resolve of toNotify) {
|
|
15
|
+
resolve(message);
|
|
16
|
+
}
|
|
17
|
+
// Notify persistent listeners (for dashboard bridge)
|
|
18
|
+
for (const listener of this.listeners) {
|
|
19
|
+
listener(message);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
onMessage(listener) {
|
|
23
|
+
this.listeners.push(listener);
|
|
24
|
+
return () => {
|
|
25
|
+
const idx = this.listeners.indexOf(listener);
|
|
26
|
+
if (idx !== -1)
|
|
27
|
+
this.listeners.splice(idx, 1);
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
waitForNext(timeoutMs) {
|
|
31
|
+
return new Promise((resolve) => {
|
|
32
|
+
const timer = setTimeout(() => {
|
|
33
|
+
const idx = this.waiters.indexOf(onMessage);
|
|
34
|
+
if (idx !== -1)
|
|
35
|
+
this.waiters.splice(idx, 1);
|
|
36
|
+
resolve(null);
|
|
37
|
+
}, timeoutMs);
|
|
38
|
+
const onMessage = (msg) => {
|
|
39
|
+
clearTimeout(timer);
|
|
40
|
+
resolve(msg);
|
|
41
|
+
};
|
|
42
|
+
this.waiters.push(onMessage);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
getAll(opts) {
|
|
46
|
+
let result = [...this.messages];
|
|
47
|
+
if (opts?.fromPeerId) {
|
|
48
|
+
result = result.filter((m) => m.fromPeerId === opts.fromPeerId);
|
|
49
|
+
}
|
|
50
|
+
if (opts?.afterMessageId) {
|
|
51
|
+
const idx = result.findIndex((m) => m.messageId === opts.afterMessageId);
|
|
52
|
+
if (idx !== -1) {
|
|
53
|
+
result = result.slice(idx + 1);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (opts?.unreadOnly) {
|
|
57
|
+
result = result.filter((m) => !m.read);
|
|
58
|
+
}
|
|
59
|
+
if (opts?.limit && opts.limit > 0) {
|
|
60
|
+
result = result.slice(0, opts.limit);
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
markAsRead(messageIds) {
|
|
65
|
+
const idSet = new Set(messageIds);
|
|
66
|
+
for (const msg of this.messages) {
|
|
67
|
+
if (idSet.has(msg.messageId)) {
|
|
68
|
+
msg.read = true;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
markAllAsRead() {
|
|
73
|
+
for (const msg of this.messages) {
|
|
74
|
+
msg.read = true;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
clear() {
|
|
78
|
+
const count = this.messages.length;
|
|
79
|
+
this.messages = [];
|
|
80
|
+
return count;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=message-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-store.js","sourceRoot":"","sources":["../../src/stores/message-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { DelegatedTask, InboundTask, TaskStatus } from '../types.js';
|
|
2
|
+
export declare class TaskStore {
|
|
3
|
+
private delegated;
|
|
4
|
+
private inbound;
|
|
5
|
+
addDelegated(task: DelegatedTask): void;
|
|
6
|
+
getDelegated(taskId: string): DelegatedTask | undefined;
|
|
7
|
+
updateDelegatedStatus(taskId: string, status: TaskStatus, result?: string, error?: string): boolean;
|
|
8
|
+
listDelegated(): DelegatedTask[];
|
|
9
|
+
addInbound(task: InboundTask): void;
|
|
10
|
+
getInbound(taskId: string): InboundTask | undefined;
|
|
11
|
+
updateInboundStatus(taskId: string, status: TaskStatus): boolean;
|
|
12
|
+
listInbound(): InboundTask[];
|
|
13
|
+
sweepTimedOutTasks(): void;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=task-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-store.d.ts","sourceRoot":"","sources":["../../src/stores/task-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1E,qBAAa,SAAS;IACpB,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,OAAO,CAAuC;IAItD,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAIvC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAIvD,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO;IAUnG,aAAa,IAAI,aAAa,EAAE;IAMhC,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IAInC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAInD,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO;IAOhE,WAAW,IAAI,WAAW,EAAE;IAM5B,kBAAkB,IAAI,IAAI;CAY3B"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export class TaskStore {
|
|
2
|
+
delegated = new Map();
|
|
3
|
+
inbound = new Map();
|
|
4
|
+
// === Delegated (outbound) tasks ===
|
|
5
|
+
addDelegated(task) {
|
|
6
|
+
this.delegated.set(task.taskId, task);
|
|
7
|
+
}
|
|
8
|
+
getDelegated(taskId) {
|
|
9
|
+
return this.delegated.get(taskId);
|
|
10
|
+
}
|
|
11
|
+
updateDelegatedStatus(taskId, status, result, error) {
|
|
12
|
+
const task = this.delegated.get(taskId);
|
|
13
|
+
if (!task)
|
|
14
|
+
return false;
|
|
15
|
+
task.status = status;
|
|
16
|
+
task.updatedAt = new Date().toISOString();
|
|
17
|
+
if (result !== undefined)
|
|
18
|
+
task.result = result;
|
|
19
|
+
if (error !== undefined)
|
|
20
|
+
task.error = error;
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
listDelegated() {
|
|
24
|
+
return Array.from(this.delegated.values());
|
|
25
|
+
}
|
|
26
|
+
// === Inbound tasks ===
|
|
27
|
+
addInbound(task) {
|
|
28
|
+
this.inbound.set(task.taskId, task);
|
|
29
|
+
}
|
|
30
|
+
getInbound(taskId) {
|
|
31
|
+
return this.inbound.get(taskId);
|
|
32
|
+
}
|
|
33
|
+
updateInboundStatus(taskId, status) {
|
|
34
|
+
const task = this.inbound.get(taskId);
|
|
35
|
+
if (!task)
|
|
36
|
+
return false;
|
|
37
|
+
task.status = status;
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
listInbound() {
|
|
41
|
+
return Array.from(this.inbound.values());
|
|
42
|
+
}
|
|
43
|
+
// === Timeout sweep ===
|
|
44
|
+
sweepTimedOutTasks() {
|
|
45
|
+
const now = Date.now();
|
|
46
|
+
for (const task of this.delegated.values()) {
|
|
47
|
+
if (task.status === 'pending' || task.status === 'in_progress') {
|
|
48
|
+
const createdAt = new Date(task.createdAt).getTime();
|
|
49
|
+
if (now - createdAt > task.timeoutMs) {
|
|
50
|
+
task.status = 'timed_out';
|
|
51
|
+
task.updatedAt = new Date().toISOString();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=task-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-store.js","sourceRoot":"","sources":["../../src/stores/task-store.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,SAAS;IACZ,SAAS,GAA+B,IAAI,GAAG,EAAE,CAAC;IAClD,OAAO,GAA6B,IAAI,GAAG,EAAE,CAAC;IAEtD,qCAAqC;IAErC,YAAY,CAAC,IAAmB;QAC9B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACxC,CAAC;IAED,YAAY,CAAC,MAAc;QACzB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAED,qBAAqB,CAAC,MAAc,EAAE,MAAkB,EAAE,MAAe,EAAE,KAAc;QACvF,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC1C,IAAI,MAAM,KAAK,SAAS;YAAE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAC/C,IAAI,KAAK,KAAK,SAAS;YAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,aAAa;QACX,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,wBAAwB;IAExB,UAAU,CAAC,IAAiB;QAC1B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,UAAU,CAAC,MAAc;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAED,mBAAmB,CAAC,MAAc,EAAE,MAAkB;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,WAAW;QACT,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,wBAAwB;IAExB,kBAAkB;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;YAC3C,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,aAAa,EAAE,CAAC;gBAC/D,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;gBACrD,IAAI,GAAG,GAAG,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;oBACrC,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC;oBAC1B,IAAI,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;gBAC5C,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { AgentConnection } from '../hub/agent-connection.js';
|
|
3
|
+
export declare function registerAcceptClaim(server: McpServer, agentConnection: AgentConnection): void;
|
|
4
|
+
//# sourceMappingURL=accept-claim.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accept-claim.d.ts","sourceRoot":"","sources":["../../src/tools/accept-claim.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAElE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,eAAe,GAAG,IAAI,CA6B7F"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export function registerAcceptClaim(server, agentConnection) {
|
|
3
|
+
server.tool('accept_claim', 'Accept an agent\'s claim on a task you created. The agent will be notified and can begin working.', {
|
|
4
|
+
taskId: z.string().describe('The ID of the task whose claim to accept'),
|
|
5
|
+
claimantId: z.string().describe('The peer ID of the agent whose claim to accept'),
|
|
6
|
+
}, async ({ taskId, claimantId }) => {
|
|
7
|
+
try {
|
|
8
|
+
await agentConnection.acceptClaim(taskId, claimantId);
|
|
9
|
+
return {
|
|
10
|
+
content: [
|
|
11
|
+
{
|
|
12
|
+
type: 'text',
|
|
13
|
+
text: JSON.stringify({ accepted: true, taskId, claimantId }),
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
catch (err) {
|
|
19
|
+
const message = err instanceof Error ? err.message : 'Unknown error';
|
|
20
|
+
return {
|
|
21
|
+
content: [{ type: 'text', text: JSON.stringify({ error: `Failed to accept claim: ${message}` }) }],
|
|
22
|
+
isError: true,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=accept-claim.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accept-claim.js","sourceRoot":"","sources":["../../src/tools/accept-claim.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,mBAAmB,CAAC,MAAiB,EAAE,eAAgC;IACrF,MAAM,CAAC,IAAI,CACT,cAAc,EACd,mGAAmG,EACnG;QACE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;QACvE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gDAAgD,CAAC;KAClF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE;QAC/B,IAAI,CAAC;YACH,MAAM,eAAe,CAAC,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YAEtD,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;qBAC7D;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YACrE,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,2BAA2B,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;gBAC3G,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { DashboardServer } from '../dashboard/http-server.js';
|
|
3
|
+
export declare function registerChatSend(server: McpServer, dashboard: DashboardServer, peerName: string): void;
|
|
4
|
+
//# sourceMappingURL=chat-send.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-send.d.ts","sourceRoot":"","sources":["../../src/tools/chat-send.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAqBtG"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export function registerChatSend(server, dashboard, peerName) {
|
|
3
|
+
server.tool('chat_send_message', 'Post a message directly to the CrossChat dashboard UI. This is visible to users watching the dashboard in their browser. Use this for human-readable status updates, summaries, or to participate in dashboard conversations. Messages sent via send_message between peers are already mirrored to the dashboard automatically — use this tool when you want to post something specifically for the dashboard audience.', {
|
|
4
|
+
roomId: z.string().optional().describe('The room ID to post to (default: "general"). Use "crosschat" for the auto-mirrored activity feed.'),
|
|
5
|
+
text: z.string().describe('The message text to post'),
|
|
6
|
+
username: z.string().optional().describe('Override the username (default: your peer name)'),
|
|
7
|
+
}, async ({ roomId, text, username }) => {
|
|
8
|
+
const room = roomId || 'general';
|
|
9
|
+
const name = username || peerName;
|
|
10
|
+
dashboard.postToRoom(room, name, text);
|
|
11
|
+
return {
|
|
12
|
+
content: [{
|
|
13
|
+
type: 'text',
|
|
14
|
+
text: JSON.stringify({ posted: true, roomId: room, username: name }),
|
|
15
|
+
}],
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=chat-send.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-send.js","sourceRoot":"","sources":["../../src/tools/chat-send.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,SAA0B,EAAE,QAAgB;IAC9F,MAAM,CAAC,IAAI,CACT,mBAAmB,EACnB,yZAAyZ,EACzZ;QACE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mGAAmG,CAAC;QAC3I,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;QACrD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iDAAiD,CAAC;KAC5F,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;QACnC,MAAM,IAAI,GAAG,MAAM,IAAI,SAAS,CAAC;QACjC,MAAM,IAAI,GAAG,QAAQ,IAAI,QAAQ,CAAC;QAClC,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACvC,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;iBACrE,CAAC;SACH,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { AgentConnection } from '../hub/agent-connection.js';
|
|
3
|
+
export declare function registerClaimTask(server: McpServer, agentConnection: AgentConnection): void;
|
|
4
|
+
//# sourceMappingURL=claim-task.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claim-task.d.ts","sourceRoot":"","sources":["../../src/tools/claim-task.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAElE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,eAAe,GAAG,IAAI,CA4B3F"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export function registerClaimTask(server, agentConnection) {
|
|
3
|
+
server.tool('claim_task', 'Claim an open task. The task creator will be notified of your bid and must accept it before you can start working.', {
|
|
4
|
+
taskId: z.string().describe('The ID of the task to claim (from list_tasks or a task announcement in the room)'),
|
|
5
|
+
}, async ({ taskId }) => {
|
|
6
|
+
try {
|
|
7
|
+
await agentConnection.claimTask(taskId);
|
|
8
|
+
return {
|
|
9
|
+
content: [
|
|
10
|
+
{
|
|
11
|
+
type: 'text',
|
|
12
|
+
text: JSON.stringify({ claimed: true, taskId }),
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
const message = err instanceof Error ? err.message : 'Unknown error';
|
|
19
|
+
return {
|
|
20
|
+
content: [{ type: 'text', text: JSON.stringify({ error: `Failed to claim task: ${message}` }) }],
|
|
21
|
+
isError: true,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=claim-task.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claim-task.js","sourceRoot":"","sources":["../../src/tools/claim-task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,iBAAiB,CAAC,MAAiB,EAAE,eAAgC;IACnF,MAAM,CAAC,IAAI,CACT,YAAY,EACZ,oHAAoH,EACpH;QACE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kFAAkF,CAAC;KAChH,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACnB,IAAI,CAAC;YACH,MAAM,eAAe,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAExC,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;qBAChD;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YACrE,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,yBAAyB,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;gBACzG,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { AgentConnection } from '../hub/agent-connection.js';
|
|
3
|
+
import type { MessageStore } from '../stores/message-store.js';
|
|
4
|
+
export declare function registerClearSession(server: McpServer, agentConnection: AgentConnection, messageStore: MessageStore): void;
|
|
5
|
+
//# sourceMappingURL=clear-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clear-session.d.ts","sourceRoot":"","sources":["../../src/tools/clear-session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE/D,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,eAAe,EAAE,eAAe,EAChC,YAAY,EAAE,YAAY,GACzB,IAAI,CA4CN"}
|