@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,250 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import { generateId } from '../util/id.js';
|
|
5
|
+
import { log, logError } from '../util/logger.js';
|
|
6
|
+
// ── TaskManager ─────────────────────────────────────────────────────
|
|
7
|
+
export class TaskManager {
|
|
8
|
+
tasks = new Map();
|
|
9
|
+
tasksDir;
|
|
10
|
+
constructor(tasksDir) {
|
|
11
|
+
this.tasksDir = tasksDir ?? path.join(os.homedir(), '.crosschat', 'tasks');
|
|
12
|
+
}
|
|
13
|
+
// ── Initialization ──────────────────────────────────────────────
|
|
14
|
+
async init() {
|
|
15
|
+
await fs.mkdir(this.tasksDir, { recursive: true });
|
|
16
|
+
await this.loadFromDisk();
|
|
17
|
+
log(`TaskManager initialized with ${this.tasks.size} task(s) from ${this.tasksDir}`);
|
|
18
|
+
}
|
|
19
|
+
// ── CRUD operations ─────────────────────────────────────────────
|
|
20
|
+
async create(params) {
|
|
21
|
+
const now = new Date().toISOString();
|
|
22
|
+
const task = {
|
|
23
|
+
taskId: generateId(),
|
|
24
|
+
roomId: params.roomId,
|
|
25
|
+
creatorId: params.creatorId,
|
|
26
|
+
creatorName: params.creatorName,
|
|
27
|
+
description: params.description,
|
|
28
|
+
context: params.context,
|
|
29
|
+
filter: params.filter,
|
|
30
|
+
status: 'open',
|
|
31
|
+
createdAt: now,
|
|
32
|
+
updatedAt: now,
|
|
33
|
+
notes: [],
|
|
34
|
+
};
|
|
35
|
+
this.tasks.set(task.taskId, task);
|
|
36
|
+
await this.persist(task);
|
|
37
|
+
log(`Task created: ${task.taskId} by ${task.creatorName}`);
|
|
38
|
+
return task;
|
|
39
|
+
}
|
|
40
|
+
async claim(taskId, claimantId, claimantName) {
|
|
41
|
+
const task = this.requireTask(taskId);
|
|
42
|
+
if (task.status !== 'open') {
|
|
43
|
+
throw new Error(`Cannot claim task ${taskId}: task status is '${task.status}', must be 'open'`);
|
|
44
|
+
}
|
|
45
|
+
if (task.creatorId === claimantId) {
|
|
46
|
+
throw new Error(`Cannot claim task ${taskId}: creator cannot claim their own task`);
|
|
47
|
+
}
|
|
48
|
+
task.claimantId = claimantId;
|
|
49
|
+
task.claimantName = claimantName;
|
|
50
|
+
task.status = 'claimed';
|
|
51
|
+
task.updatedAt = new Date().toISOString();
|
|
52
|
+
await this.persist(task);
|
|
53
|
+
log(`Task ${taskId} claimed by ${claimantName} (${claimantId})`);
|
|
54
|
+
return task;
|
|
55
|
+
}
|
|
56
|
+
async acceptClaim(taskId, creatorId) {
|
|
57
|
+
const task = this.requireTask(taskId);
|
|
58
|
+
if (task.creatorId !== creatorId) {
|
|
59
|
+
throw new Error(`Cannot accept claim on task ${taskId}: only the creator can accept claims`);
|
|
60
|
+
}
|
|
61
|
+
if (task.status !== 'claimed') {
|
|
62
|
+
throw new Error(`Cannot accept claim on task ${taskId}: task status is '${task.status}', must be 'claimed'`);
|
|
63
|
+
}
|
|
64
|
+
task.status = 'in_progress';
|
|
65
|
+
task.updatedAt = new Date().toISOString();
|
|
66
|
+
await this.persist(task);
|
|
67
|
+
log(`Task ${taskId} claim accepted, now in_progress`);
|
|
68
|
+
return task;
|
|
69
|
+
}
|
|
70
|
+
async update(taskId, authorId, authorName, content, status) {
|
|
71
|
+
const task = this.requireTask(taskId);
|
|
72
|
+
this.validateParticipant(task, authorId);
|
|
73
|
+
if (task.status === 'completed' || task.status === 'failed' || task.status === 'archived') {
|
|
74
|
+
throw new Error(`Cannot update task ${taskId}: task status is '${task.status}' (terminal state)`);
|
|
75
|
+
}
|
|
76
|
+
const note = {
|
|
77
|
+
noteId: generateId(),
|
|
78
|
+
authorId,
|
|
79
|
+
authorName,
|
|
80
|
+
content,
|
|
81
|
+
timestamp: new Date().toISOString(),
|
|
82
|
+
};
|
|
83
|
+
task.notes.push(note);
|
|
84
|
+
if (status !== undefined) {
|
|
85
|
+
this.validateStatusTransition(task.status, status, taskId);
|
|
86
|
+
task.status = status;
|
|
87
|
+
}
|
|
88
|
+
task.updatedAt = new Date().toISOString();
|
|
89
|
+
await this.persist(task);
|
|
90
|
+
log(`Task ${taskId} updated by ${authorName}, note ${note.noteId} added`);
|
|
91
|
+
return task;
|
|
92
|
+
}
|
|
93
|
+
async complete(taskId, authorId, authorName, result, status, error) {
|
|
94
|
+
const task = this.requireTask(taskId);
|
|
95
|
+
if (task.claimantId !== authorId) {
|
|
96
|
+
throw new Error(`Cannot complete task ${taskId}: only the claimant can complete it`);
|
|
97
|
+
}
|
|
98
|
+
if (task.status !== 'in_progress' && task.status !== 'claimed') {
|
|
99
|
+
throw new Error(`Cannot complete task ${taskId}: task status is '${task.status}', must be 'in_progress' or 'claimed'`);
|
|
100
|
+
}
|
|
101
|
+
const noteContent = status === 'completed'
|
|
102
|
+
? `Task completed: ${result}`
|
|
103
|
+
: `Task failed: ${error ?? result}`;
|
|
104
|
+
const note = {
|
|
105
|
+
noteId: generateId(),
|
|
106
|
+
authorId,
|
|
107
|
+
authorName,
|
|
108
|
+
content: noteContent,
|
|
109
|
+
timestamp: new Date().toISOString(),
|
|
110
|
+
};
|
|
111
|
+
task.notes.push(note);
|
|
112
|
+
task.status = status;
|
|
113
|
+
task.result = result;
|
|
114
|
+
if (error !== undefined) {
|
|
115
|
+
task.error = error;
|
|
116
|
+
}
|
|
117
|
+
task.updatedAt = new Date().toISOString();
|
|
118
|
+
await this.persist(task);
|
|
119
|
+
log(`Task ${taskId} ${status} by ${authorName}`);
|
|
120
|
+
return task;
|
|
121
|
+
}
|
|
122
|
+
async archive(taskId) {
|
|
123
|
+
const task = this.requireTask(taskId);
|
|
124
|
+
if (task.status === 'archived') {
|
|
125
|
+
throw new Error(`Task ${taskId} is already archived`);
|
|
126
|
+
}
|
|
127
|
+
task.status = 'archived';
|
|
128
|
+
task.updatedAt = new Date().toISOString();
|
|
129
|
+
await this.persist(task);
|
|
130
|
+
log(`Task ${taskId} archived`);
|
|
131
|
+
return task;
|
|
132
|
+
}
|
|
133
|
+
/** Archive all completed/failed tasks in a room. Returns count of tasks archived. */
|
|
134
|
+
async archiveTerminal(roomId) {
|
|
135
|
+
let count = 0;
|
|
136
|
+
for (const task of this.tasks.values()) {
|
|
137
|
+
if (roomId && task.roomId !== roomId)
|
|
138
|
+
continue;
|
|
139
|
+
if (task.status === 'completed' || task.status === 'failed') {
|
|
140
|
+
task.status = 'archived';
|
|
141
|
+
task.updatedAt = new Date().toISOString();
|
|
142
|
+
await this.persist(task);
|
|
143
|
+
count++;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (count > 0)
|
|
147
|
+
log(`Archived ${count} terminal task(s)${roomId ? ` in room ${roomId}` : ''}`);
|
|
148
|
+
return count;
|
|
149
|
+
}
|
|
150
|
+
get(taskId) {
|
|
151
|
+
return this.tasks.get(taskId);
|
|
152
|
+
}
|
|
153
|
+
list(filter) {
|
|
154
|
+
let result = Array.from(this.tasks.values());
|
|
155
|
+
if (filter?.status) {
|
|
156
|
+
result = result.filter((t) => t.status === filter.status);
|
|
157
|
+
}
|
|
158
|
+
if (filter?.roomId) {
|
|
159
|
+
result = result.filter((t) => t.roomId === filter.roomId);
|
|
160
|
+
}
|
|
161
|
+
if (filter?.assignedTo) {
|
|
162
|
+
result = result.filter((t) => t.claimantId === filter.assignedTo);
|
|
163
|
+
}
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
// ── Filter matching ─────────────────────────────────────────────
|
|
167
|
+
matchesFilter(task, agent) {
|
|
168
|
+
const f = task.filter;
|
|
169
|
+
if (!f)
|
|
170
|
+
return true;
|
|
171
|
+
if (f.agentId && f.agentId !== agent.peerId)
|
|
172
|
+
return false;
|
|
173
|
+
if (f.workingDirReq && f.workingDirReq !== agent.cwd)
|
|
174
|
+
return false;
|
|
175
|
+
if (f.gitProject && f.gitProject !== agent.gitProject)
|
|
176
|
+
return false;
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
// ── Persistence ─────────────────────────────────────────────────
|
|
180
|
+
async persist(task) {
|
|
181
|
+
const filePath = path.join(this.tasksDir, `${task.taskId}.json`);
|
|
182
|
+
const tmpPath = `${filePath}.tmp`;
|
|
183
|
+
try {
|
|
184
|
+
await fs.writeFile(tmpPath, JSON.stringify(task, null, 2), 'utf-8');
|
|
185
|
+
await fs.rename(tmpPath, filePath);
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
logError(`Failed to persist task ${task.taskId}`, err);
|
|
189
|
+
// Clean up tmp file on failure
|
|
190
|
+
try {
|
|
191
|
+
await fs.unlink(tmpPath);
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
// ignore cleanup errors
|
|
195
|
+
}
|
|
196
|
+
throw err;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
async loadFromDisk() {
|
|
200
|
+
let entries;
|
|
201
|
+
try {
|
|
202
|
+
const dirEntries = await fs.readdir(this.tasksDir);
|
|
203
|
+
entries = dirEntries.filter((e) => e.endsWith('.json'));
|
|
204
|
+
}
|
|
205
|
+
catch (err) {
|
|
206
|
+
logError('Failed to read tasks directory', err);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
for (const entry of entries) {
|
|
210
|
+
const filePath = path.join(this.tasksDir, entry);
|
|
211
|
+
try {
|
|
212
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
213
|
+
const task = JSON.parse(content);
|
|
214
|
+
if (task.taskId) {
|
|
215
|
+
this.tasks.set(task.taskId, task);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
catch (err) {
|
|
219
|
+
logError(`Failed to load task file ${entry}`, err);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// ── Validation helpers ──────────────────────────────────────────
|
|
224
|
+
requireTask(taskId) {
|
|
225
|
+
const task = this.tasks.get(taskId);
|
|
226
|
+
if (!task) {
|
|
227
|
+
throw new Error(`Task not found: ${taskId}`);
|
|
228
|
+
}
|
|
229
|
+
return task;
|
|
230
|
+
}
|
|
231
|
+
validateParticipant(task, authorId) {
|
|
232
|
+
if (authorId !== task.creatorId && authorId !== task.claimantId) {
|
|
233
|
+
throw new Error(`Agent ${authorId} is not a participant of task ${task.taskId} (neither creator nor claimant)`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
validateStatusTransition(current, next, taskId) {
|
|
237
|
+
const allowed = {
|
|
238
|
+
open: ['claimed', 'archived'],
|
|
239
|
+
claimed: ['in_progress', 'open', 'completed', 'failed', 'archived'],
|
|
240
|
+
in_progress: ['completed', 'failed', 'archived'],
|
|
241
|
+
completed: ['archived'],
|
|
242
|
+
failed: ['archived'],
|
|
243
|
+
archived: [],
|
|
244
|
+
};
|
|
245
|
+
if (!allowed[current].includes(next)) {
|
|
246
|
+
throw new Error(`Invalid status transition for task ${taskId}: '${current}' -> '${next}'`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=task-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-manager.js","sourceRoot":"","sources":["../../src/hub/task-manager.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC1B,QAAQ,CAAC,uCAAuC,EAAE,GAAG,CAAC,CAAC;IACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"AAoIA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAsIjD"}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
7
|
+
import { generateId } from './util/id.js';
|
|
8
|
+
import { log, logError } from './util/logger.js';
|
|
9
|
+
import { isProcessAlive } from './util/pid.js';
|
|
10
|
+
import { MessageStore } from './stores/message-store.js';
|
|
11
|
+
import { AgentConnection } from './hub/agent-connection.js';
|
|
12
|
+
import { createMcpServer } from './server.js';
|
|
13
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
const CROSSCHAT_DIR = path.join(os.homedir(), '.crosschat');
|
|
15
|
+
const DASHBOARD_LOCK_FILE = path.join(CROSSCHAT_DIR, 'dashboard.lock');
|
|
16
|
+
const SESSIONS_DIR = path.join(CROSSCHAT_DIR, 'sessions');
|
|
17
|
+
const HUB_MAIN_PATH = path.join(__dirname, '..', 'dist', 'hub', 'hub-main.js');
|
|
18
|
+
// When running from dist directly, hub-main.js is a sibling directory
|
|
19
|
+
const HUB_MAIN_PATH_ALT = path.join(__dirname, 'hub', 'hub-main.js');
|
|
20
|
+
const LOCK_POLL_INTERVAL_MS = 500;
|
|
21
|
+
const LOCK_POLL_TIMEOUT_MS = 5_000;
|
|
22
|
+
/**
|
|
23
|
+
* Read and validate the dashboard lock file.
|
|
24
|
+
* Returns the lock data if the file exists and the process is alive,
|
|
25
|
+
* otherwise cleans up the stale lock and returns null.
|
|
26
|
+
*/
|
|
27
|
+
async function readDashboardLock() {
|
|
28
|
+
try {
|
|
29
|
+
const data = await fs.readFile(DASHBOARD_LOCK_FILE, 'utf-8');
|
|
30
|
+
const lock = JSON.parse(data);
|
|
31
|
+
if (isProcessAlive(lock.pid)) {
|
|
32
|
+
return lock;
|
|
33
|
+
}
|
|
34
|
+
// Stale lock — remove it
|
|
35
|
+
await fs.unlink(DASHBOARD_LOCK_FILE).catch(() => { });
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Resolve the path to hub-main.js, checking both possible locations
|
|
44
|
+
* (project root dist/ and co-located dist/).
|
|
45
|
+
*/
|
|
46
|
+
async function resolveHubMainPath() {
|
|
47
|
+
// Try the co-located path first (when running from dist/)
|
|
48
|
+
try {
|
|
49
|
+
await fs.access(HUB_MAIN_PATH_ALT);
|
|
50
|
+
return HUB_MAIN_PATH_ALT;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// Fall through
|
|
54
|
+
}
|
|
55
|
+
// Try the project-root path (when running from src/ during dev)
|
|
56
|
+
try {
|
|
57
|
+
await fs.access(HUB_MAIN_PATH);
|
|
58
|
+
return HUB_MAIN_PATH;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Fall through
|
|
62
|
+
}
|
|
63
|
+
// Default to the co-located path and let spawn fail with a clear error
|
|
64
|
+
return HUB_MAIN_PATH_ALT;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Spawn the hub server as a detached child process.
|
|
68
|
+
* The hub writes its own lock file once ready.
|
|
69
|
+
*/
|
|
70
|
+
async function spawnHub() {
|
|
71
|
+
const hubPath = await resolveHubMainPath();
|
|
72
|
+
log(`Spawning hub: node ${hubPath}`);
|
|
73
|
+
const child = spawn(process.execPath, [hubPath], {
|
|
74
|
+
detached: true,
|
|
75
|
+
stdio: 'ignore',
|
|
76
|
+
env: { ...process.env },
|
|
77
|
+
});
|
|
78
|
+
child.unref();
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Wait for the hub lock file to appear with a valid port.
|
|
82
|
+
* Polls every LOCK_POLL_INTERVAL_MS up to LOCK_POLL_TIMEOUT_MS.
|
|
83
|
+
*/
|
|
84
|
+
async function waitForHubLock() {
|
|
85
|
+
const deadline = Date.now() + LOCK_POLL_TIMEOUT_MS;
|
|
86
|
+
while (Date.now() < deadline) {
|
|
87
|
+
const lock = await readDashboardLock();
|
|
88
|
+
if (lock) {
|
|
89
|
+
return lock;
|
|
90
|
+
}
|
|
91
|
+
await new Promise((resolve) => setTimeout(resolve, LOCK_POLL_INTERVAL_MS));
|
|
92
|
+
}
|
|
93
|
+
throw new Error(`Hub did not write lock file within ${LOCK_POLL_TIMEOUT_MS}ms. ` +
|
|
94
|
+
`Check ~/.crosschat/ for errors.`);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Ensure the hub is running and return its port.
|
|
98
|
+
* If no live hub is detected, spawns one and waits for it to be ready.
|
|
99
|
+
*/
|
|
100
|
+
async function ensureHub() {
|
|
101
|
+
// Check for an existing running hub
|
|
102
|
+
const existingLock = await readDashboardLock();
|
|
103
|
+
if (existingLock) {
|
|
104
|
+
log(`Hub already running on port ${existingLock.port} (pid ${existingLock.pid})`);
|
|
105
|
+
return existingLock;
|
|
106
|
+
}
|
|
107
|
+
// No hub running — spawn one
|
|
108
|
+
await spawnHub();
|
|
109
|
+
const lock = await waitForHubLock();
|
|
110
|
+
log(`Hub started on port ${lock.port} (pid ${lock.pid})`);
|
|
111
|
+
return lock;
|
|
112
|
+
}
|
|
113
|
+
export async function startServer() {
|
|
114
|
+
const peerId = generateId();
|
|
115
|
+
const cwd = process.env.CROSSCHAT_CWD || process.cwd();
|
|
116
|
+
const dirName = cwd.split('/').filter(Boolean).pop() || 'unknown';
|
|
117
|
+
const peerName = process.env.CROSSCHAT_NAME || `${dirName}-${peerId.slice(0, 4)}`;
|
|
118
|
+
log(`Starting CrossChat agent: ${peerName} (${peerId})`);
|
|
119
|
+
// 1. Ensure the hub is running and get its port
|
|
120
|
+
let dashboardInfo;
|
|
121
|
+
let hubPort;
|
|
122
|
+
try {
|
|
123
|
+
const hubLock = await ensureHub();
|
|
124
|
+
hubPort = hubLock.port;
|
|
125
|
+
dashboardInfo = { port: hubPort };
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
129
|
+
logError('Failed to start/find hub', err);
|
|
130
|
+
throw new Error(`Cannot start CrossChat: hub unavailable — ${errorMsg}`);
|
|
131
|
+
}
|
|
132
|
+
// 2. Create the agent connection to the hub
|
|
133
|
+
const agentConnection = new AgentConnection(hubPort, peerId, peerName, cwd);
|
|
134
|
+
// 3. Create the local message store (bridges hub messages for MCP tool access)
|
|
135
|
+
const messageStore = new MessageStore();
|
|
136
|
+
// 4. Bridge hub room messages into the local MessageStore
|
|
137
|
+
agentConnection.onMessage((msg) => {
|
|
138
|
+
// Skip messages from ourselves to avoid echo
|
|
139
|
+
if (msg.fromPeerId === peerId)
|
|
140
|
+
return;
|
|
141
|
+
const peerMessage = {
|
|
142
|
+
messageId: msg.messageId,
|
|
143
|
+
fromPeerId: msg.fromPeerId,
|
|
144
|
+
fromName: msg.fromName,
|
|
145
|
+
content: msg.content,
|
|
146
|
+
metadata: msg.metadata,
|
|
147
|
+
sentAt: msg.timestamp,
|
|
148
|
+
receivedAt: new Date().toISOString(),
|
|
149
|
+
read: false,
|
|
150
|
+
type: 'message',
|
|
151
|
+
mentions: msg.mentions,
|
|
152
|
+
mentionType: msg.mentionType,
|
|
153
|
+
importance: msg.importance,
|
|
154
|
+
};
|
|
155
|
+
messageStore.add(peerMessage);
|
|
156
|
+
});
|
|
157
|
+
// 5. Bridge task events into the MessageStore as informational messages
|
|
158
|
+
agentConnection.onTaskEvent((evt) => {
|
|
159
|
+
let content;
|
|
160
|
+
let type = 'message';
|
|
161
|
+
switch (evt.type) {
|
|
162
|
+
case 'task.created':
|
|
163
|
+
content = `[TASK CREATED] ${evt.task.description} (taskId: ${evt.task.taskId})`;
|
|
164
|
+
type = 'task_delegated';
|
|
165
|
+
break;
|
|
166
|
+
case 'task.claimed':
|
|
167
|
+
content = `[TASK CLAIMED] Task ${evt.taskId} claimed by ${evt.claimantName} (${evt.claimantId})`;
|
|
168
|
+
break;
|
|
169
|
+
case 'task.claimAccepted':
|
|
170
|
+
content = `[TASK ACCEPTED] You have been assigned task ${evt.taskId}`;
|
|
171
|
+
break;
|
|
172
|
+
case 'task.updated':
|
|
173
|
+
content = `[TASK UPDATED] Task ${evt.taskId}: ${evt.note.content.slice(0, 200)}`;
|
|
174
|
+
break;
|
|
175
|
+
case 'task.completed':
|
|
176
|
+
content = `[TASK ${evt.status === 'completed' ? 'COMPLETED' : 'FAILED'}] Task ${evt.taskId}${evt.result ? `: ${evt.result.slice(0, 200)}` : ''}`;
|
|
177
|
+
type = 'task_result';
|
|
178
|
+
break;
|
|
179
|
+
default:
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const taskMessage = {
|
|
183
|
+
messageId: generateId(),
|
|
184
|
+
fromPeerId: 'hub',
|
|
185
|
+
fromName: 'CrossChat Hub',
|
|
186
|
+
content,
|
|
187
|
+
sentAt: new Date().toISOString(),
|
|
188
|
+
receivedAt: new Date().toISOString(),
|
|
189
|
+
read: false,
|
|
190
|
+
type,
|
|
191
|
+
};
|
|
192
|
+
messageStore.add(taskMessage);
|
|
193
|
+
});
|
|
194
|
+
// 6. Connect to the hub
|
|
195
|
+
agentConnection.connect();
|
|
196
|
+
// 6b. Write session marker so the permission hook can detect this instance.
|
|
197
|
+
// Key by parent PID (Claude Code's PID) — the hook uses $PPID which matches.
|
|
198
|
+
const sessionFile = path.join(SESSIONS_DIR, `${process.ppid}`);
|
|
199
|
+
try {
|
|
200
|
+
await fs.mkdir(SESSIONS_DIR, { recursive: true });
|
|
201
|
+
await fs.writeFile(sessionFile, JSON.stringify({
|
|
202
|
+
name: peerName,
|
|
203
|
+
peerId,
|
|
204
|
+
connectedAt: new Date().toISOString(),
|
|
205
|
+
}));
|
|
206
|
+
}
|
|
207
|
+
catch (err) {
|
|
208
|
+
logError('Failed to write session marker', err);
|
|
209
|
+
}
|
|
210
|
+
// 7. Create and connect the MCP server
|
|
211
|
+
const mcpServer = createMcpServer(peerId, peerName, messageStore, agentConnection, dashboardInfo);
|
|
212
|
+
const transport = new StdioServerTransport();
|
|
213
|
+
await mcpServer.connect(transport);
|
|
214
|
+
// 8. Shutdown handler
|
|
215
|
+
let shuttingDown = false;
|
|
216
|
+
const shutdown = async () => {
|
|
217
|
+
if (shuttingDown)
|
|
218
|
+
return;
|
|
219
|
+
shuttingDown = true;
|
|
220
|
+
log('Shutting down...');
|
|
221
|
+
agentConnection.disconnect();
|
|
222
|
+
await mcpServer.close();
|
|
223
|
+
// Clean up session marker
|
|
224
|
+
await fs.unlink(sessionFile).catch(() => { });
|
|
225
|
+
log('Shutdown complete');
|
|
226
|
+
process.exit(0);
|
|
227
|
+
};
|
|
228
|
+
process.on('SIGINT', shutdown);
|
|
229
|
+
process.on('SIGTERM', shutdown);
|
|
230
|
+
process.on('SIGHUP', shutdown);
|
|
231
|
+
process.stdin.on('end', shutdown);
|
|
232
|
+
log(`CrossChat agent ready: ${peerName} (${peerId})`);
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CA4DzF"}
|
package/dist/prompts.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export function registerPrompts(server, peerId, peerName) {
|
|
2
|
+
server.prompt('check-inbox', 'Check for new messages and delegated tasks from other CrossChat peers.', () => ({
|
|
3
|
+
messages: [
|
|
4
|
+
{
|
|
5
|
+
role: 'user',
|
|
6
|
+
content: {
|
|
7
|
+
type: 'text',
|
|
8
|
+
text: `Check your CrossChat inbox for any new messages or delegated tasks. Use get_messages with unreadOnly=true. For each message:
|
|
9
|
+
- If it's a regular message, summarize who sent it and what they said.
|
|
10
|
+
- If it's a delegated task (content starts with [TASK DELEGATED]), describe the task and ask me if I'd like you to work on it.
|
|
11
|
+
If there are no new messages, just say the inbox is empty.`,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
}));
|
|
16
|
+
server.prompt('discover-peers', 'Find all active CrossChat instances and what they\'re working on.', () => ({
|
|
17
|
+
messages: [
|
|
18
|
+
{
|
|
19
|
+
role: 'user',
|
|
20
|
+
content: {
|
|
21
|
+
type: 'text',
|
|
22
|
+
text: `Use list_peers with includeMetadata=true to discover all active CrossChat instances. For each peer, tell me:
|
|
23
|
+
- Their name and peer ID
|
|
24
|
+
- Their status (available or busy)
|
|
25
|
+
- What directory they're working in (from metadata.cwd)
|
|
26
|
+
If no peers are found, let me know I'm the only active instance.`,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
}));
|
|
31
|
+
server.prompt('my-identity', 'Show your CrossChat identity.', () => ({
|
|
32
|
+
messages: [
|
|
33
|
+
{
|
|
34
|
+
role: 'user',
|
|
35
|
+
content: {
|
|
36
|
+
type: 'text',
|
|
37
|
+
text: `Report your CrossChat identity. You are:
|
|
38
|
+
- Name: ${peerName}
|
|
39
|
+
- Peer ID: ${peerId}
|
|
40
|
+
- Working directory: ${process.env.CROSSCHAT_CWD || process.cwd()}
|
|
41
|
+
|
|
42
|
+
Tell me this info and explain that other peers can message me using my peer ID.`,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,eAAe,CAAC,MAAiB,EAAE,MAAc,EAAE,QAAgB;IACjF,MAAM,CAAC,MAAM,CACX,aAAa,EACb,wEAAwE,EACxE,GAAG,EAAE,CAAC,CAAC;QACL,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE;;;2DAGyC;iBAChD;aACF;SACF;KACF,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,MAAM,CACX,gBAAgB,EAChB,mEAAmE,EACnE,GAAG,EAAE,CAAC,CAAC;QACL,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE;;;;iEAI+C;iBACtD;aACF;SACF;KACF,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,MAAM,CACX,aAAa,EACb,+BAA+B,EAC/B,GAAG,EAAE,CAAC,CAAC;QACL,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE;UACR,QAAQ;aACL,MAAM;uBACI,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,EAAE;;gFAEe;iBACrE;aACF;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup.d.ts","sourceRoot":"","sources":["../../src/registry/cleanup.ts"],"names":[],"mappings":"AAOA,wBAAsB,iBAAiB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2CzE"}
|