claude-multi-session 2.3.2 → 2.4.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/package.json +1 -1
- package/src/mcp-server.js +85 -4
- package/src/prompts.js +30 -21
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-multi-session",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "Multi-session orchestrator for Claude Code CLI — spawn, control, pause, resume, and send multiple inputs to Claude Code sessions programmatically",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
package/src/mcp-server.js
CHANGED
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
* - tools/call → execute a tool and return result
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
|
+
const fs = require('fs');
|
|
29
|
+
const path = require('path');
|
|
28
30
|
const readline = require('readline');
|
|
29
31
|
const SessionManager = require('./manager');
|
|
30
32
|
const Delegate = require('./delegate');
|
|
@@ -47,6 +49,9 @@ const DecisionJournal = require('./decision-journal');
|
|
|
47
49
|
const PatternRegistry = require('./pattern-registry');
|
|
48
50
|
const StaleDetector = require('./stale-detector');
|
|
49
51
|
|
|
52
|
+
// Capture version at load time — used to detect stale server processes
|
|
53
|
+
const LOADED_VERSION = require('../package.json').version;
|
|
54
|
+
|
|
50
55
|
// =============================================================================
|
|
51
56
|
// Server State — persists across all tool calls
|
|
52
57
|
// =============================================================================
|
|
@@ -390,6 +395,18 @@ const TOOLS = [
|
|
|
390
395
|
},
|
|
391
396
|
},
|
|
392
397
|
|
|
398
|
+
// ── Server Version ─────────────────────────────────────────────────────
|
|
399
|
+
{
|
|
400
|
+
name: 'server_version',
|
|
401
|
+
description:
|
|
402
|
+
'Check the running MCP server version and detect staleness. ' +
|
|
403
|
+
'Call this if tools seem missing or behave unexpectedly.',
|
|
404
|
+
inputSchema: {
|
|
405
|
+
type: 'object',
|
|
406
|
+
properties: {},
|
|
407
|
+
},
|
|
408
|
+
},
|
|
409
|
+
|
|
393
410
|
// ══════════════════════════════════════════════════════════════════════════
|
|
394
411
|
// TEAM HUB v2 — 32 new tools for team collaboration
|
|
395
412
|
// ══════════════════════════════════════════════════════════════════════════
|
|
@@ -555,7 +572,9 @@ const TOOLS = [
|
|
|
555
572
|
{
|
|
556
573
|
name: 'artifact_get',
|
|
557
574
|
description:
|
|
558
|
-
'Read an artifact (latest version or specific version).'
|
|
575
|
+
'Read an artifact (latest version or specific version). ' +
|
|
576
|
+
'IMPORTANT: Pass your session name as the "reader" parameter to track artifact consumption. ' +
|
|
577
|
+
'The orchestrator uses this to verify workers actually read shared data.',
|
|
559
578
|
inputSchema: {
|
|
560
579
|
type: 'object',
|
|
561
580
|
properties: {
|
|
@@ -1139,6 +1158,10 @@ async function executeTool(toolName, args) {
|
|
|
1139
1158
|
case 'abort_task':
|
|
1140
1159
|
return handleAbort(args);
|
|
1141
1160
|
|
|
1161
|
+
// ── Server Version ──────────────────────────────────────────────
|
|
1162
|
+
case 'server_version':
|
|
1163
|
+
return handleServerVersion(args);
|
|
1164
|
+
|
|
1142
1165
|
// ── Orchestrator Guide ────────────────────────────────────────────
|
|
1143
1166
|
case 'get_orchestrator_guide':
|
|
1144
1167
|
return handleGetOrchestratorGuide(args);
|
|
@@ -1597,6 +1620,32 @@ function handleGetOrchestratorGuide(args) {
|
|
|
1597
1620
|
return textResult(guide);
|
|
1598
1621
|
}
|
|
1599
1622
|
|
|
1623
|
+
/**
|
|
1624
|
+
* Check the running MCP server version and detect staleness.
|
|
1625
|
+
* Compares the version loaded into memory at startup against the
|
|
1626
|
+
* version currently installed on disk (package.json).
|
|
1627
|
+
*/
|
|
1628
|
+
function handleServerVersion() {
|
|
1629
|
+
let installedVersion = LOADED_VERSION;
|
|
1630
|
+
try {
|
|
1631
|
+
const pkgPath = path.join(__dirname, '..', 'package.json');
|
|
1632
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
1633
|
+
installedVersion = pkg.version;
|
|
1634
|
+
} catch (e) {
|
|
1635
|
+
// If we can't read package.json at runtime, use loaded version
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
const stale = LOADED_VERSION !== installedVersion;
|
|
1639
|
+
return textResult(JSON.stringify({
|
|
1640
|
+
running: LOADED_VERSION,
|
|
1641
|
+
installed: installedVersion,
|
|
1642
|
+
stale,
|
|
1643
|
+
message: stale
|
|
1644
|
+
? `Server is stale: running v${LOADED_VERSION} but v${installedVersion} is installed. Restart Claude Code to load new tools.`
|
|
1645
|
+
: `Server is up to date (v${LOADED_VERSION}).`
|
|
1646
|
+
}, null, 2));
|
|
1647
|
+
}
|
|
1648
|
+
|
|
1600
1649
|
// =============================================================================
|
|
1601
1650
|
// Team Hub Handlers — Layer 1, 2, 3
|
|
1602
1651
|
// =============================================================================
|
|
@@ -1889,7 +1938,8 @@ function handleArtifactGet(args) {
|
|
|
1889
1938
|
artifactStore.trackRead(args.artifactId, args.reader, artifact.version);
|
|
1890
1939
|
}
|
|
1891
1940
|
|
|
1892
|
-
|
|
1941
|
+
// Build the response
|
|
1942
|
+
const response = {
|
|
1893
1943
|
artifactId: artifact.artifactId,
|
|
1894
1944
|
version: artifact.version,
|
|
1895
1945
|
type: artifact.type,
|
|
@@ -1901,7 +1951,14 @@ function handleArtifactGet(args) {
|
|
|
1901
1951
|
lineage: artifact.lineage,
|
|
1902
1952
|
team: teamName,
|
|
1903
1953
|
readBy: artifactStore.getReads(args.artifactId),
|
|
1904
|
-
}
|
|
1954
|
+
};
|
|
1955
|
+
|
|
1956
|
+
// Add nudge if reader param was not provided
|
|
1957
|
+
if (!args.reader) {
|
|
1958
|
+
response._hint = 'Tip: Pass your session name as the "reader" parameter to track artifact consumption. Example: artifact_get({ artifactId: "...", reader: "your-session-name" })';
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1961
|
+
return textResult(JSON.stringify(response, null, 2));
|
|
1905
1962
|
} catch (err) {
|
|
1906
1963
|
return errorResult(err.message);
|
|
1907
1964
|
}
|
|
@@ -2497,6 +2554,28 @@ function errorResult(message) {
|
|
|
2497
2554
|
return { content: [{ type: 'text', text: `Error: ${message}` }], isError: true };
|
|
2498
2555
|
}
|
|
2499
2556
|
|
|
2557
|
+
/**
|
|
2558
|
+
* Append a staleness warning to tool results if the server version is outdated.
|
|
2559
|
+
* Reads package.json from disk on each call to detect post-install version drift.
|
|
2560
|
+
* @param {Object} result - The tool result object
|
|
2561
|
+
* @returns {Object} The result, possibly with a staleness warning appended
|
|
2562
|
+
*/
|
|
2563
|
+
function appendStalenessWarning(result) {
|
|
2564
|
+
try {
|
|
2565
|
+
const pkgPath = path.join(__dirname, '..', 'package.json');
|
|
2566
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
2567
|
+
if (pkg.version !== LOADED_VERSION) {
|
|
2568
|
+
const warning = `\n\n⚠️ STALE SERVER: Running v${LOADED_VERSION} but v${pkg.version} is installed. Restart Claude Code to load updated tools.`;
|
|
2569
|
+
if (result && result.content && result.content[0] && result.content[0].text) {
|
|
2570
|
+
result.content[0].text += warning;
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2573
|
+
} catch (e) {
|
|
2574
|
+
// Silently ignore — staleness check is best-effort
|
|
2575
|
+
}
|
|
2576
|
+
return result;
|
|
2577
|
+
}
|
|
2578
|
+
|
|
2500
2579
|
// =============================================================================
|
|
2501
2580
|
// MCP Protocol Handler — JSON-RPC 2.0 over stdio
|
|
2502
2581
|
// =============================================================================
|
|
@@ -2566,7 +2645,9 @@ async function handleMessage(message) {
|
|
|
2566
2645
|
break;
|
|
2567
2646
|
}
|
|
2568
2647
|
try {
|
|
2569
|
-
|
|
2648
|
+
let result = await executeTool(params.name, params.arguments || {});
|
|
2649
|
+
// Append staleness warning if server version is outdated
|
|
2650
|
+
result = appendStalenessWarning(result);
|
|
2570
2651
|
sendResponse(id, result);
|
|
2571
2652
|
} catch (err) {
|
|
2572
2653
|
sendResponse(id, errorResult(err.message));
|
package/src/prompts.js
CHANGED
|
@@ -83,6 +83,8 @@ Follow the conventions STRICTLY. If NO convention artifact exists AND your work
|
|
|
83
83
|
- Use \`team_ask\` to ask the relevant teammate about their format BEFORE writing code
|
|
84
84
|
- NEVER guess or assume format — mismatches cause test failures
|
|
85
85
|
|
|
86
|
+
Note: team_ask is a **fallback mechanism** for when information wasn't available upfront. If your orchestrator provided thorough prompts with all needed context and conventions, you may never need team_ask — this is the ideal case.
|
|
87
|
+
|
|
86
88
|
### Step 2: UPDATE YOUR STATUS
|
|
87
89
|
Call \`mcp__multi-session__team_update_status\` to set yourself as "active" with your current task.
|
|
88
90
|
|
|
@@ -120,7 +122,7 @@ mcp__multi-session__team_broadcast({ from: "${name}", content: "Completed: <what
|
|
|
120
122
|
| \`team_check_inbox\` | BEFORE starting work, AFTER major steps |
|
|
121
123
|
| \`team_send_message\` | Direct message to a specific teammate |
|
|
122
124
|
| \`team_broadcast\` | Announce something to ALL teammates |
|
|
123
|
-
| \`team_ask\` | Ask a teammate a question and WAIT for reply |
|
|
125
|
+
| \`team_ask\` | Ask a teammate a question and WAIT for reply (fallback — use when info wasn't provided upfront) |
|
|
124
126
|
| \`team_reply\` | Reply to a question you received (IMMEDIATELY) |
|
|
125
127
|
| \`team_update_status\` | Update what you're working on |
|
|
126
128
|
|
|
@@ -474,8 +476,9 @@ IMPORTANT: You are the ORCHESTRATOR. Your job is to PLAN, SPAWN, and MONITOR —
|
|
|
474
476
|
|
|
475
477
|
=== CRITICAL: ANTI-PATTERN — DO NOT DO THIS ===
|
|
476
478
|
- Do NOT spawn a session, read its output, then manually relay that output to another session
|
|
477
|
-
- Do NOT fix bugs found by one session yourself
|
|
479
|
+
- Do NOT fix bugs found by one session yourself UNLESS the fix is ≤ 3 lines AND the worker session has completed. For trivial fixes, you may fix directly but MUST broadcast the change and re-publish any affected artifacts
|
|
478
480
|
- Do NOT act as a message router between sessions — they can talk directly
|
|
481
|
+
- Note: team_ask is a **fallback** for unexpected ambiguity. In well-orchestrated projects where you provide all context upfront in worker prompts, team_ask may never be called — this is the ideal case and means your prompts were thorough enough.
|
|
479
482
|
- Do NOT do implementation work that should be delegated
|
|
480
483
|
- Do NOT fix code yourself when a worker's tests fail — send corrections to the worker that wrote the failing code
|
|
481
484
|
- Do NOT assume workers will agree on response formats — define shared conventions before spawning
|
|
@@ -548,6 +551,11 @@ team_spawn({ name: "test-worker", ... })
|
|
|
548
551
|
|
|
549
552
|
NEVER skip verification. NEVER rely on a worker's self-reported completion — verify the artifact exists yourself.
|
|
550
553
|
|
|
554
|
+
=== PHASE COUNTING RULE ===
|
|
555
|
+
At the start of planning, count and list your phases explicitly:
|
|
556
|
+
"Phase 1: [description], Phase 2: [description], ..."
|
|
557
|
+
This creates a self-check — you can verify you ran the verification checklist between each pair.
|
|
558
|
+
|
|
551
559
|
### Phase 2: Spawn Workers (use team_spawn, NOT delegate_task)
|
|
552
560
|
Spawn all independent workers at once. Example:
|
|
553
561
|
|
|
@@ -596,18 +604,16 @@ mcp__multi-session__contract_create({
|
|
|
596
604
|
})
|
|
597
605
|
\`\`\`
|
|
598
606
|
|
|
599
|
-
### Phase 4:
|
|
600
|
-
|
|
601
|
-
\`\`\`
|
|
602
|
-
mcp__multi-session__team_roster() — See who's active/idle/blocked
|
|
603
|
-
mcp__multi-session__contract_list() — See contract statuses
|
|
604
|
-
mcp__multi-session__artifact_list() — See published outputs
|
|
605
|
-
\`\`\`
|
|
607
|
+
### Phase 4: Post-Phase Verification (MANDATORY)
|
|
608
|
+
After ALL workers in a phase complete, and BEFORE spawning the next phase, you MUST run this verification checklist:
|
|
606
609
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
610
|
+
1. \`artifact_list()\` — confirm all expected artifacts from this phase exist
|
|
611
|
+
2. \`artifact_get()\` on each critical artifact — verify the content is valid and complete
|
|
612
|
+
3. \`team_roster()\` — confirm all phase workers show 'idle' or 'done' status
|
|
613
|
+
|
|
614
|
+
Only proceed to the next phase when ALL checks pass.
|
|
615
|
+
|
|
616
|
+
IMPORTANT: Count your phases at the start of planning. If you have N phases, you MUST perform this verification checklist exactly N-1 times (between every adjacent pair of phases). Skipping verification for later phases is the #1 cause of test failures in multi-session projects.
|
|
611
617
|
|
|
612
618
|
### Phase 5: Collect Results
|
|
613
619
|
When all workers are done:
|
|
@@ -856,7 +862,7 @@ IMPORTANT: You are the ORCHESTRATOR. Your job is to PLAN, SPAWN, and MONITOR —
|
|
|
856
862
|
|
|
857
863
|
4.5. **Phase Gate** — Before spawning workers that depend on previous workers' output, VERIFY the dependency artifact exists by calling \`artifact_list()\` and \`artifact_get()\`. Never trust self-reported completion — verify the artifact.
|
|
858
864
|
|
|
859
|
-
5. **
|
|
865
|
+
5. **Post-Phase Verification** — After each phase completes, run the verification checklist: \`artifact_list()\` to confirm artifacts exist, \`artifact_get()\` to verify content, \`team_roster()\` to confirm workers are idle. Only proceed when all checks pass. If you have N phases, verify N-1 times.
|
|
860
866
|
|
|
861
867
|
6. **Collect** — When all workers are idle, check \`artifact_list\` for published outputs and summarize results for the user.
|
|
862
868
|
|
|
@@ -941,17 +947,20 @@ WHY: Specific file, exact error, expected behavior, and how to verify.
|
|
|
941
947
|
`;
|
|
942
948
|
|
|
943
949
|
const ORCHESTRATOR_MONITORING = `
|
|
944
|
-
##
|
|
950
|
+
## Post-Phase Verification (MANDATORY)
|
|
945
951
|
|
|
946
|
-
|
|
952
|
+
After ALL workers in a phase complete, and BEFORE spawning the next phase, you MUST run this verification checklist. Do NOT fall back to filesystem checks (Glob, Read) to verify worker output — use these tools:
|
|
947
953
|
|
|
954
|
+
### Verification Checklist (run between EVERY pair of phases)
|
|
948
955
|
\`\`\`
|
|
949
|
-
mcp__multi-
|
|
950
|
-
mcp__multi-
|
|
951
|
-
mcp__multi-
|
|
956
|
+
mcp__multi-session__artifact_list() — Confirm all expected artifacts from this phase exist
|
|
957
|
+
mcp__multi-session__artifact_get() — Verify each critical artifact has valid, complete content
|
|
958
|
+
mcp__multi-session__team_roster() — Confirm all phase workers show 'idle' or 'done' status
|
|
952
959
|
\`\`\`
|
|
953
960
|
|
|
954
|
-
|
|
961
|
+
Only proceed to the next phase when ALL checks pass.
|
|
962
|
+
|
|
963
|
+
### Dependency Verification
|
|
955
964
|
Between spawn phases, use these to verify dependencies:
|
|
956
965
|
\`\`\`
|
|
957
966
|
mcp__multi-session__artifact_get({ artifactId: "db-schema" }) — Verify artifact content
|
|
@@ -984,7 +993,7 @@ When a worker is BLOCKED:
|
|
|
984
993
|
|
|
985
994
|
NEVER do these:
|
|
986
995
|
- Do NOT read the worker's full output to understand the problem — their status message should tell you
|
|
987
|
-
- Do NOT implement
|
|
996
|
+
- Do NOT implement fixes > 3 lines yourself — tell the worker to fix it or spawn a fix-worker. For trivial fixes (≤ 3 lines) where the worker is already done, you may fix directly but MUST broadcast the change and re-publish affected artifacts
|
|
988
997
|
- Do NOT act as a message router between workers — they can use \`team_ask\` directly
|
|
989
998
|
|
|
990
999
|
=== ANTI-PATTERN — DO NOT DO THIS ===
|