session-collab-mcp 2.2.0 → 2.3.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/README.md +36 -7
- package/dist/{chunk-SOUW3JSS.js → chunk-TFGXE3EI.js} +142 -9
- package/dist/chunk-TFGXE3EI.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/http/cli.js +7 -1
- package/dist/http/cli.js.map +1 -1
- package/dist/http/client-cli.js +80 -6
- package/dist/http/client-cli.js.map +1 -1
- package/package.json +5 -3
- package/dist/chunk-SOUW3JSS.js.map +0 -1
package/README.md
CHANGED
|
@@ -64,6 +64,7 @@ session-collab-http --host 127.0.0.1 --port 8765
|
|
|
64
64
|
# CLI wrapper (convenience REST client)
|
|
65
65
|
session-collab health
|
|
66
66
|
session-collab tools
|
|
67
|
+
session-collab doctor
|
|
67
68
|
session-collab call --name collab_session_start --args '{"project_root":"/repo","name":"demo"}'
|
|
68
69
|
```
|
|
69
70
|
|
|
@@ -101,9 +102,11 @@ The MCP tools give you a stable collaboration workflow across providers:
|
|
|
101
102
|
|
|
102
103
|
1. Start a session with `collab_session_start`
|
|
103
104
|
2. Check files with `collab_claim(action="check")`
|
|
104
|
-
3. Reserve files with `collab_claim(action="create")
|
|
105
|
-
4.
|
|
106
|
-
5.
|
|
105
|
+
3. Reserve files with `collab_claim(action="create")`; conflicting claims are blocked by default
|
|
106
|
+
4. Update visible progress with `collab_session_update`
|
|
107
|
+
5. Save important context with `collab_memory_save`
|
|
108
|
+
6. Release claims with `collab_claim(action="release")`
|
|
109
|
+
7. End the session with `collab_session_end`
|
|
107
110
|
|
|
108
111
|
### Working Memory
|
|
109
112
|
|
|
@@ -145,13 +148,14 @@ Configure behavior with `collab_config`:
|
|
|
145
148
|
|
|
146
149
|
## MCP Tools Reference
|
|
147
150
|
|
|
148
|
-
### Session Management
|
|
151
|
+
### Session Management
|
|
149
152
|
|
|
150
153
|
| Tool | Purpose |
|
|
151
154
|
|------|---------|
|
|
152
155
|
| `collab_session_start` | Register a new session |
|
|
153
156
|
| `collab_session_end` | End session and release all claims |
|
|
154
|
-
| `collab_session_list` | List active sessions |
|
|
157
|
+
| `collab_session_list` | List active sessions with current task and active claim summaries |
|
|
158
|
+
| `collab_session_update` | Update heartbeat, current task, todos, and progress |
|
|
155
159
|
| `collab_config` | Configure session behavior |
|
|
156
160
|
| `collab_status` | Get session status summary |
|
|
157
161
|
|
|
@@ -159,7 +163,7 @@ Configure behavior with `collab_config`:
|
|
|
159
163
|
|
|
160
164
|
| Tool | Actions |
|
|
161
165
|
|------|---------|
|
|
162
|
-
| `collab_claim` | `create`, `check`, `release`, `list` (check: `exclude_self` defaults to true) |
|
|
166
|
+
| `collab_claim` | `create`, `check`, `release`, `list` (check: `exclude_self` defaults to true; create blocks conflicts unless `allow_conflicts=true`) |
|
|
163
167
|
|
|
164
168
|
### Working Memory (3 tools)
|
|
165
169
|
|
|
@@ -187,6 +191,7 @@ Configure behavior with `collab_config`:
|
|
|
187
191
|
|
|
188
192
|
- `POST /v1/sessions/start` → `collab_session_start`
|
|
189
193
|
- `POST /v1/sessions/end` → `collab_session_end`
|
|
194
|
+
- `POST /v1/sessions/update` → `collab_session_update`
|
|
190
195
|
- `GET /v1/sessions` → `collab_session_list`
|
|
191
196
|
- `POST /v1/config` → `collab_config`
|
|
192
197
|
- `GET /v1/status` → `collab_status`
|
|
@@ -217,11 +222,16 @@ Configure behavior with `collab_config`:
|
|
|
217
222
|
# Session A starts working
|
|
218
223
|
collab_session_start(project_root="/my/project", name="feature-auth")
|
|
219
224
|
collab_claim(session_id="session-a", action="create", files=["src/auth.ts"], intent="Adding JWT support")
|
|
225
|
+
collab_session_update(session_id="session-a", current_task="Adding JWT support")
|
|
220
226
|
|
|
221
227
|
# Session B checks before editing
|
|
222
228
|
collab_claim(session_id="session-b", action="check", files=["src/auth.ts"])
|
|
223
229
|
# Result: "CONFLICT: src/auth.ts is claimed by 'feature-auth'"
|
|
224
230
|
|
|
231
|
+
# create is also safe by default; use allow_conflicts=true only after coordination
|
|
232
|
+
collab_claim(session_id="session-b", action="create", files=["src/auth.ts"], intent="Coordinated auth work")
|
|
233
|
+
# Result: "Claim not created. 1 conflict(s) detected."
|
|
234
|
+
|
|
225
235
|
# If you want to include your own claims in the check
|
|
226
236
|
collab_claim(session_id="session-a", action="check", files=["src/auth.ts"], exclude_self=false)
|
|
227
237
|
|
|
@@ -334,6 +344,8 @@ npm run start:dev # Start in development mode
|
|
|
334
344
|
npm run typecheck # Run TypeScript type checking
|
|
335
345
|
npm run lint # Run ESLint
|
|
336
346
|
npm run test # Run tests with Vitest
|
|
347
|
+
npm run test:http # Run HTTP integration tests
|
|
348
|
+
npm run test:release # Run release gate: typecheck, lint, tests, HTTP tests, npm pack dry-run
|
|
337
349
|
```
|
|
338
350
|
|
|
339
351
|
### HTTP Integration Tests
|
|
@@ -341,7 +353,15 @@ npm run test # Run tests with Vitest
|
|
|
341
353
|
HTTP integration tests require a local listen port. Enable them with:
|
|
342
354
|
|
|
343
355
|
```bash
|
|
344
|
-
|
|
356
|
+
npm run test:http
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### HTTP CLI Doctor
|
|
360
|
+
|
|
361
|
+
When using the HTTP server, validate the running server with:
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
session-collab doctor --base-url http://127.0.0.1:8765
|
|
345
365
|
```
|
|
346
366
|
|
|
347
367
|
### Historical Notes
|
|
@@ -372,6 +392,15 @@ session-collab-mcp/
|
|
|
372
392
|
|
|
373
393
|
## Changelog
|
|
374
394
|
|
|
395
|
+
### v2.3.0
|
|
396
|
+
|
|
397
|
+
- Add `collab_session_update` for heartbeat, current task, todo, and progress reporting
|
|
398
|
+
- Enrich `collab_session_list` with current task and active claim summaries
|
|
399
|
+
- Make `collab_claim(action="create")` block conflicts by default; use `allow_conflicts=true` only after coordination
|
|
400
|
+
- Add `session-collab doctor` for HTTP server health and tool-surface checks
|
|
401
|
+
- Add `npm run test:http` and `npm run test:release` release gates
|
|
402
|
+
- Update dev test tooling to clear npm audit findings
|
|
403
|
+
|
|
375
404
|
### v2.1.0
|
|
376
405
|
|
|
377
406
|
- Add HTTP server + CLI wrapper for universal AI CLI usage
|
|
@@ -161,12 +161,13 @@ var SERVER_INSTRUCTIONS = `
|
|
|
161
161
|
|
|
162
162
|
Coordinate sessions and persist context across conversations.
|
|
163
163
|
|
|
164
|
-
##
|
|
164
|
+
## Core Tools
|
|
165
165
|
|
|
166
|
-
### Session
|
|
166
|
+
### Session
|
|
167
167
|
- \`collab_session_start\`: Start session with project_root
|
|
168
168
|
- \`collab_session_end\`: End session, release claims
|
|
169
|
-
- \`collab_session_list\`: List active sessions
|
|
169
|
+
- \`collab_session_list\`: List active sessions and their active claim summaries
|
|
170
|
+
- \`collab_session_update\`: Update heartbeat, current task, todos, and progress
|
|
170
171
|
- \`collab_config\`: Configure session behavior
|
|
171
172
|
- \`collab_status\`: Get session status and summary
|
|
172
173
|
|
|
@@ -187,10 +188,11 @@ Coordinate sessions and persist context across conversations.
|
|
|
187
188
|
|
|
188
189
|
1. **On start**: \`collab_session_start\` with project_root
|
|
189
190
|
2. **Before editing**: \`collab_claim\` action="check"
|
|
190
|
-
3. **For changes**: \`collab_claim\` action="create"
|
|
191
|
+
3. **For changes**: \`collab_claim\` action="create" (blocked by default if another active session conflicts)
|
|
191
192
|
4. **Save context**: \`collab_memory_save\` for important findings
|
|
192
|
-
5. **
|
|
193
|
-
6. **
|
|
193
|
+
5. **While working**: \`collab_session_update\` with current_task/todos
|
|
194
|
+
6. **When done**: \`collab_claim\` action="release"
|
|
195
|
+
7. **On end**: \`collab_session_end\`
|
|
194
196
|
|
|
195
197
|
## Memory Categories
|
|
196
198
|
|
|
@@ -4334,6 +4336,39 @@ async function listSessions(db, params = {}) {
|
|
|
4334
4336
|
const result = await db.prepare(query).bind(...bindings).all();
|
|
4335
4337
|
return result.results;
|
|
4336
4338
|
}
|
|
4339
|
+
async function updateSessionHeartbeat(db, id, statusUpdate) {
|
|
4340
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4341
|
+
let progress = null;
|
|
4342
|
+
let todosJson = null;
|
|
4343
|
+
if (statusUpdate?.todos) {
|
|
4344
|
+
const total = statusUpdate.todos.length;
|
|
4345
|
+
const completed = statusUpdate.todos.filter((t) => t.status === "completed").length;
|
|
4346
|
+
progress = {
|
|
4347
|
+
completed,
|
|
4348
|
+
total,
|
|
4349
|
+
percentage: total > 0 ? Math.round(completed / total * 100) : 0
|
|
4350
|
+
};
|
|
4351
|
+
todosJson = JSON.stringify(statusUpdate.todos);
|
|
4352
|
+
}
|
|
4353
|
+
let query = "UPDATE sessions SET last_heartbeat = ?";
|
|
4354
|
+
const bindings = [now];
|
|
4355
|
+
if (statusUpdate?.current_task !== void 0) {
|
|
4356
|
+
query += ", current_task = ?";
|
|
4357
|
+
bindings.push(statusUpdate.current_task);
|
|
4358
|
+
}
|
|
4359
|
+
if (progress) {
|
|
4360
|
+
query += ", progress = ?";
|
|
4361
|
+
bindings.push(JSON.stringify(progress));
|
|
4362
|
+
}
|
|
4363
|
+
if (todosJson) {
|
|
4364
|
+
query += ", todos = ?";
|
|
4365
|
+
bindings.push(todosJson);
|
|
4366
|
+
}
|
|
4367
|
+
query += " WHERE id = ? AND status = 'active'";
|
|
4368
|
+
bindings.push(id);
|
|
4369
|
+
const result = await db.prepare(query).bind(...bindings).run();
|
|
4370
|
+
return result.meta.changes > 0;
|
|
4371
|
+
}
|
|
4337
4372
|
async function endSession(db, id, release_claims = "abandon") {
|
|
4338
4373
|
const claimStatus = release_claims === "complete" ? "completed" : "abandoned";
|
|
4339
4374
|
await db.prepare("UPDATE claims SET status = ?, updated_at = ? WHERE session_id = ? AND status = 'active'").bind(claimStatus, (/* @__PURE__ */ new Date()).toISOString(), id).run();
|
|
@@ -4998,7 +5033,8 @@ var claimCreateSchema = external_exports.object({
|
|
|
4998
5033
|
symbols: symbolClaimsArraySchema.optional(),
|
|
4999
5034
|
intent: external_exports.string().min(1, "intent is required"),
|
|
5000
5035
|
scope: claimScopeSchema.optional(),
|
|
5001
|
-
priority: external_exports.number().min(0).max(100).optional()
|
|
5036
|
+
priority: external_exports.number().min(0).max(100).optional(),
|
|
5037
|
+
allow_conflicts: external_exports.boolean().optional()
|
|
5002
5038
|
}).refine(
|
|
5003
5039
|
(data) => data.files && data.files.length > 0 || data.symbols && data.symbols.length > 0,
|
|
5004
5040
|
{ message: "Either files or symbols must be provided" }
|
|
@@ -5104,6 +5140,14 @@ function validationError(message) {
|
|
|
5104
5140
|
}
|
|
5105
5141
|
|
|
5106
5142
|
// src/mcp/tools/session.ts
|
|
5143
|
+
function parseJsonField(value) {
|
|
5144
|
+
if (!value) return null;
|
|
5145
|
+
try {
|
|
5146
|
+
return JSON.parse(value);
|
|
5147
|
+
} catch {
|
|
5148
|
+
return null;
|
|
5149
|
+
}
|
|
5150
|
+
}
|
|
5107
5151
|
var sessionTools = [
|
|
5108
5152
|
{
|
|
5109
5153
|
name: "collab_session_start",
|
|
@@ -5159,6 +5203,39 @@ var sessionTools = [
|
|
|
5159
5203
|
}
|
|
5160
5204
|
}
|
|
5161
5205
|
},
|
|
5206
|
+
{
|
|
5207
|
+
name: "collab_session_update",
|
|
5208
|
+
description: "Update session heartbeat, current task, todos, and progress.",
|
|
5209
|
+
inputSchema: {
|
|
5210
|
+
type: "object",
|
|
5211
|
+
properties: {
|
|
5212
|
+
session_id: {
|
|
5213
|
+
type: "string",
|
|
5214
|
+
description: "Session ID to update"
|
|
5215
|
+
},
|
|
5216
|
+
current_task: {
|
|
5217
|
+
type: "string",
|
|
5218
|
+
description: "Current work summary"
|
|
5219
|
+
},
|
|
5220
|
+
todos: {
|
|
5221
|
+
type: "array",
|
|
5222
|
+
items: {
|
|
5223
|
+
type: "object",
|
|
5224
|
+
properties: {
|
|
5225
|
+
content: { type: "string" },
|
|
5226
|
+
status: {
|
|
5227
|
+
type: "string",
|
|
5228
|
+
enum: ["pending", "in_progress", "completed"]
|
|
5229
|
+
}
|
|
5230
|
+
},
|
|
5231
|
+
required: ["content", "status"]
|
|
5232
|
+
},
|
|
5233
|
+
description: "Current todo state for progress reporting"
|
|
5234
|
+
}
|
|
5235
|
+
},
|
|
5236
|
+
required: ["session_id"]
|
|
5237
|
+
}
|
|
5238
|
+
},
|
|
5162
5239
|
{
|
|
5163
5240
|
name: "collab_config",
|
|
5164
5241
|
description: "Configure session behavior.",
|
|
@@ -5308,7 +5385,17 @@ Decisions:
|
|
|
5308
5385
|
id: session.id,
|
|
5309
5386
|
name: session.name,
|
|
5310
5387
|
status: session.status,
|
|
5388
|
+
current_task: session.current_task,
|
|
5389
|
+
progress: parseJsonField(session.progress),
|
|
5390
|
+
todos: parseJsonField(session.todos),
|
|
5311
5391
|
active_claims: claims.length,
|
|
5392
|
+
claims: claims.map((c) => ({
|
|
5393
|
+
id: c.id,
|
|
5394
|
+
files: c.files,
|
|
5395
|
+
intent: c.intent,
|
|
5396
|
+
priority: getPriorityLevel(c.priority),
|
|
5397
|
+
created_at: c.created_at
|
|
5398
|
+
})),
|
|
5312
5399
|
last_heartbeat: session.last_heartbeat
|
|
5313
5400
|
};
|
|
5314
5401
|
})
|
|
@@ -5318,6 +5405,34 @@ Decisions:
|
|
|
5318
5405
|
total: sessionsWithClaims.length
|
|
5319
5406
|
});
|
|
5320
5407
|
}
|
|
5408
|
+
case "collab_session_update": {
|
|
5409
|
+
const validation = validateInput(statusUpdateSchema, args);
|
|
5410
|
+
if (!validation.success) {
|
|
5411
|
+
return validationError(validation.error);
|
|
5412
|
+
}
|
|
5413
|
+
const input = validation.data;
|
|
5414
|
+
const sessionResult = await validateActiveSession(db, input.session_id);
|
|
5415
|
+
if (!sessionResult.valid) {
|
|
5416
|
+
return sessionResult.error;
|
|
5417
|
+
}
|
|
5418
|
+
const updated = await updateSessionHeartbeat(db, input.session_id, {
|
|
5419
|
+
current_task: input.current_task,
|
|
5420
|
+
todos: input.todos
|
|
5421
|
+
});
|
|
5422
|
+
if (!updated) {
|
|
5423
|
+
return errorResponse(ERROR_CODES.SESSION_NOT_FOUND, "Session not found");
|
|
5424
|
+
}
|
|
5425
|
+
const session = await getSession(db, input.session_id);
|
|
5426
|
+
return successResponse({
|
|
5427
|
+
success: true,
|
|
5428
|
+
session_id: input.session_id,
|
|
5429
|
+
current_task: session?.current_task ?? null,
|
|
5430
|
+
progress: parseJsonField(session?.progress ?? null),
|
|
5431
|
+
todos: parseJsonField(session?.todos ?? null),
|
|
5432
|
+
last_heartbeat: session?.last_heartbeat ?? null,
|
|
5433
|
+
message: "Session updated."
|
|
5434
|
+
});
|
|
5435
|
+
}
|
|
5321
5436
|
case "collab_config": {
|
|
5322
5437
|
const validation = validateInput(configSchema, args);
|
|
5323
5438
|
if (!validation.success) {
|
|
@@ -5457,6 +5572,10 @@ var claimTools = [
|
|
|
5457
5572
|
type: "boolean",
|
|
5458
5573
|
description: "Force release even if not owner (for release action)"
|
|
5459
5574
|
},
|
|
5575
|
+
allow_conflicts: {
|
|
5576
|
+
type: "boolean",
|
|
5577
|
+
description: "Explicitly create a claim even when conflicts are detected (for create action)"
|
|
5578
|
+
},
|
|
5460
5579
|
summary: {
|
|
5461
5580
|
type: "string",
|
|
5462
5581
|
description: "Release summary (for release action)"
|
|
@@ -5492,6 +5611,21 @@ async function handleClaimTool(db, name, args) {
|
|
|
5492
5611
|
}
|
|
5493
5612
|
const symbolFiles = (input.symbols ?? []).map((symbol) => symbol.file);
|
|
5494
5613
|
const files = Array.from(/* @__PURE__ */ new Set([...input.files ?? [], ...symbolFiles]));
|
|
5614
|
+
const conflicts = await checkConflicts(db, files, input.session_id, input.symbols);
|
|
5615
|
+
if (conflicts.length > 0 && !input.allow_conflicts) {
|
|
5616
|
+
return successResponse({
|
|
5617
|
+
success: false,
|
|
5618
|
+
status: "blocked_by_conflicts",
|
|
5619
|
+
files,
|
|
5620
|
+
symbols: input.symbols ?? [],
|
|
5621
|
+
conflicts: conflicts.map((c) => ({
|
|
5622
|
+
session_name: c.session_name,
|
|
5623
|
+
file: c.file_path,
|
|
5624
|
+
intent: c.intent
|
|
5625
|
+
})),
|
|
5626
|
+
message: `Claim not created. ${conflicts.length} conflict(s) detected. Coordinate before proceeding.`
|
|
5627
|
+
});
|
|
5628
|
+
}
|
|
5495
5629
|
const { claim } = await createClaim(db, {
|
|
5496
5630
|
session_id: input.session_id,
|
|
5497
5631
|
files,
|
|
@@ -5516,7 +5650,6 @@ Files: ${files.join(", ")}`,
|
|
|
5516
5650
|
related_claim_id: claim.id,
|
|
5517
5651
|
metadata: { claim_id: claim.id, files }
|
|
5518
5652
|
});
|
|
5519
|
-
const conflicts = await checkConflicts(db, files, input.session_id, input.symbols);
|
|
5520
5653
|
if (conflicts.length > 0) {
|
|
5521
5654
|
return successResponse({
|
|
5522
5655
|
success: true,
|
|
@@ -6101,4 +6234,4 @@ export {
|
|
|
6101
6234
|
getMcpTools,
|
|
6102
6235
|
handleMcpRequest
|
|
6103
6236
|
};
|
|
6104
|
-
//# sourceMappingURL=chunk-
|
|
6237
|
+
//# sourceMappingURL=chunk-TFGXE3EI.js.map
|