claude-tempo 0.13.0 → 0.13.1

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.
@@ -661,7 +661,7 @@ async function up(opts) {
661
661
  }
662
662
  else {
663
663
  // Default conductor name so the Claude Code session name matches the ensemble role
664
- const sessionName = opts.name || 'conductor';
664
+ const sessionName = opts.name || lineup?.conductor?.name || 'conductor';
665
665
  // Resolve conductor agent type from lineup
666
666
  const conductorType = lineup?.conductor?.agent && lineup.conductor.agent !== 'default' && lineup.conductor.agent !== 'copilot'
667
667
  ? lineup.conductor.agent // custom agent path
@@ -50,6 +50,15 @@ function loadLineup(filePath) {
50
50
  }
51
51
  }
52
52
  }
53
+ // Validate conductor name if present
54
+ if (doc.conductor?.name != null) {
55
+ if (typeof doc.conductor.name !== 'string' || !doc.conductor.name) {
56
+ throw new Error(`Invalid lineup: conductor.name must be a non-empty string`);
57
+ }
58
+ if (!/^[a-zA-Z0-9_-]+$/.test(doc.conductor.name)) {
59
+ throw new Error(`Invalid lineup: conductor.name "${doc.conductor.name}" contains invalid characters`);
60
+ }
61
+ }
53
62
  return {
54
63
  name: doc.name,
55
64
  description: doc.description,
@@ -36,7 +36,10 @@ async function saveLineup(client, ensemble, filePath, name) {
36
36
  const agentType = meta.agentType || 'claude';
37
37
  const workDir = meta.workDir || undefined;
38
38
  if (isConductor) {
39
+ const conductorName = meta.playerId || undefined;
39
40
  conductor = {
41
+ // Only save name if it's not the default 'conductor'
42
+ ...(conductorName && conductorName !== 'conductor' ? { name: conductorName } : {}),
40
43
  agent: agentType === 'copilot' ? 'copilot' : undefined,
41
44
  };
42
45
  }
@@ -2,6 +2,7 @@ export interface EnsembleLineup {
2
2
  name: string;
3
3
  description?: string;
4
4
  conductor?: {
5
+ name?: string;
5
6
  type?: string;
6
7
  agent?: string;
7
8
  instructions?: string;
package/dist/server.js CHANGED
@@ -83,10 +83,11 @@ async function main() {
83
83
  const config = (0, config_1.getConfig)();
84
84
  const isConductor = process.env[config_1.ENV.CONDUCTOR] === 'true';
85
85
  const requestedName = process.env[config_1.ENV.PLAYER_NAME] || '';
86
- // Prevent non-conductor sessions from using "conductor" as a name,
86
+ // Conductors use their requested name or fall back to 'conductor'.
87
+ // Non-conductors are prevented from using "conductor" as a name,
87
88
  // which would collide with the conductor's deterministic workflow ID.
88
89
  let playerId = isConductor
89
- ? 'conductor'
90
+ ? (requestedName || 'conductor')
90
91
  : (requestedName && requestedName !== 'conductor' ? requestedName : '') || crypto.randomBytes(4).toString('hex');
91
92
  const getPlayerId = () => playerId;
92
93
  const setPlayerId = (id) => { playerId = id; };
@@ -239,7 +240,7 @@ async function main() {
239
240
  }
240
241
  }
241
242
  // Create MCP server
242
- const hasRequestedName = Boolean(requestedName && requestedName !== 'conductor');
243
+ const hasRequestedName = isConductor || Boolean(requestedName && requestedName !== 'conductor');
243
244
  const playerTypeLine = playerType
244
245
  ? `Your player type is "${playerType}"${playerTypeDescription ? ` (${playerTypeDescription})` : ''}. `
245
246
  : '';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-tempo",
3
- "version": "0.13.0",
3
+ "version": "0.13.1",
4
4
  "description": "MCP server for multi-session Claude Code coordination via Temporal",
5
5
  "keywords": [
6
6
  "mcp",