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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-multi-session",
3
- "version": "2.3.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
- return textResult(JSON.stringify({
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
- }, null, 2));
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
- const result = await executeTool(params.name, params.arguments || {});
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 tell that session to fix them
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: Monitor (Don't Micromanage)
600
- Check progress periodically:
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
- Only intervene when:
608
- - A session status shows "BLOCKED" for more than a reasonable time
609
- - A contract has failed
610
- - The user asks for a status update
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. **Monitor** — Check progress with \`team_roster()\`, \`contract_list()\`, \`artifact_list()\`. Only intervene when a worker is BLOCKED or FAILED.
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
- ## How to Monitor Without Micromanaging
950
+ ## Post-Phase Verification (MANDATORY)
945
951
 
946
- You MUST check progress using these tools after spawning workers do NOT fall back to filesystem checks (Glob, Read) to verify worker output:
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-session__team_roster() See who's active/idle/blocked
950
- mcp__multi-session__contract_list() See contract statuses
951
- mcp__multi-session__artifact_list() See published outputs
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
- ### Phase Gate Verification
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 the fix yourself — tell the worker to fix it
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 ===