claude-symphony 0.2.8 → 0.2.10

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/dist/cli/index.js CHANGED
@@ -1532,7 +1532,7 @@ import { fileURLToPath as fileURLToPath2 } from "url";
1532
1532
  import os from "os";
1533
1533
  import path5 from "path";
1534
1534
  import { existsSync as existsSync3 } from "fs";
1535
- var SESSION_NAME = "symphony-session";
1535
+ var SESSION_PREFIX = "symphony-session";
1536
1536
  var DEFAULT_RELAY_DIR = path5.join(os.homedir(), ".claude/memory-relay");
1537
1537
  var cachedConfig = null;
1538
1538
  function resolveBaseDir(scriptDir) {
@@ -1595,7 +1595,7 @@ async function checkDependencies2() {
1595
1595
  const [tmux, claude] = await Promise.all([commandExists("tmux"), commandExists("claude")]);
1596
1596
  return { tmux, claude };
1597
1597
  }
1598
- function sessionExists(sessionName = SESSION_NAME) {
1598
+ function sessionExists(sessionName = SESSION_PREFIX) {
1599
1599
  try {
1600
1600
  execSync(`tmux has-session -t "${sessionName}" 2>/dev/null`, { stdio: "pipe" });
1601
1601
  return true;
@@ -1603,31 +1603,43 @@ function sessionExists(sessionName = SESSION_NAME) {
1603
1603
  return false;
1604
1604
  }
1605
1605
  }
1606
- async function handleExistingSession(sessionName = SESSION_NAME) {
1606
+ function findNextAvailableSessionName() {
1607
+ if (!sessionExists(SESSION_PREFIX)) {
1608
+ return SESSION_PREFIX;
1609
+ }
1610
+ let n = 2;
1611
+ while (sessionExists(`${SESSION_PREFIX}-${n}`)) {
1612
+ n++;
1613
+ }
1614
+ return `${SESSION_PREFIX}-${n}`;
1615
+ }
1616
+ async function handleExistingSession(sessionName = SESSION_PREFIX) {
1607
1617
  console.log(chalk5.yellow(`Session '${sessionName}' already exists.`));
1608
1618
  console.log("");
1619
+ const nextName = findNextAvailableSessionName();
1609
1620
  const choice = await select2({
1610
1621
  message: "What would you like to do?",
1611
1622
  choices: [
1612
1623
  { name: "Attach to existing session", value: "attach" },
1624
+ { name: `Create new session (${nextName})`, value: "new" },
1613
1625
  { name: "Kill and recreate", value: "recreate" },
1614
1626
  { name: "Cancel", value: "cancel" }
1615
1627
  ]
1616
1628
  });
1617
1629
  return choice;
1618
1630
  }
1619
- function killSession(sessionName = SESSION_NAME) {
1631
+ function killSession(sessionName = SESSION_PREFIX) {
1620
1632
  try {
1621
1633
  execSync(`tmux kill-session -t "${sessionName}"`, { stdio: "pipe" });
1622
1634
  } catch {
1623
1635
  }
1624
1636
  }
1625
- function attachSession(sessionName = SESSION_NAME) {
1637
+ function attachSession(sessionName = SESSION_PREFIX) {
1626
1638
  console.log("Attaching to existing session...");
1627
1639
  spawnSync("tmux", ["attach-session", "-t", sessionName], { stdio: "inherit" });
1628
1640
  }
1629
1641
  function createTmuxSession(options) {
1630
- const sessionName = SESSION_NAME;
1642
+ const sessionName = options.sessionName ?? SESSION_PREFIX;
1631
1643
  try {
1632
1644
  execSync(
1633
1645
  `tmux new-session -d -s "${sessionName}" -c "${options.workDir}" -x 200 -y 50`,
@@ -1703,12 +1715,17 @@ async function startSession(options) {
1703
1715
  console.log("Please install Claude Code CLI first");
1704
1716
  process.exit(1);
1705
1717
  }
1718
+ let sessionName = SESSION_PREFIX;
1706
1719
  if (sessionExists()) {
1707
1720
  const choice = await handleExistingSession();
1708
1721
  switch (choice) {
1709
1722
  case "attach":
1710
1723
  attachSession();
1711
1724
  return;
1725
+ case "new":
1726
+ sessionName = findNextAvailableSessionName();
1727
+ console.log(`Creating parallel session: ${chalk5.green(sessionName)}`);
1728
+ break;
1712
1729
  case "recreate":
1713
1730
  console.log("Killing existing session...");
1714
1731
  killSession();
@@ -1719,19 +1736,19 @@ async function startSession(options) {
1719
1736
  }
1720
1737
  }
1721
1738
  console.log("");
1722
- console.log(`Creating new session: ${chalk5.green(SESSION_NAME)}`);
1739
+ console.log(`Creating new session: ${chalk5.green(sessionName)}`);
1723
1740
  console.log(`Working directory: ${chalk5.blue(options.workDir)}`);
1724
1741
  console.log(`Relay base: ${chalk5.blue(config.baseDir)}`);
1725
1742
  console.log("");
1726
- const created = createTmuxSession(options);
1743
+ const created = createTmuxSession({ ...options, sessionName });
1727
1744
  if (!created) {
1728
1745
  console.error(chalk5.red("Failed to create session"));
1729
1746
  process.exit(1);
1730
1747
  }
1731
1748
  console.log(chalk5.green("Session created successfully!"));
1732
1749
  showSessionLayout();
1733
- console.log(`Attaching to session ${chalk5.green(SESSION_NAME)}...`);
1734
- attachSession();
1750
+ console.log(`Attaching to session ${chalk5.green(sessionName)}...`);
1751
+ attachSession(sessionName);
1735
1752
  }
1736
1753
 
1737
1754
  // src/relay/orchestrator.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-symphony",
3
- "version": "0.2.8",
3
+ "version": "0.2.10",
4
4
  "description": "Multi-AI Orchestration Framework - Create new projects with 10-stage development workflow",
5
5
  "type": "module",
6
6
  "bin": {
@@ -154,8 +154,9 @@ if [[ -n "${HANDOFF_FILE}" ]] && [[ -f "${HANDOFF_FILE}" ]]; then
154
154
 
155
155
  show_relay_banner
156
156
 
157
- # Start Claude with instruction to read handoff
158
- exec $(get_claude_cmd) --resume "${HANDOFF_FILE}" 2>/dev/null || exec $(get_claude_cmd)
157
+ # Start Claude with system prompt to read handoff file and continue work
158
+ # Using --append-system-prompt to stay in interactive mode (not -p which exits after response)
159
+ exec $(get_claude_cmd) --append-system-prompt "IMPORTANT: A handoff file has been created at ${HANDOFF_FILE}. You MUST read this file immediately using the Read tool and continue the previous work described within it. This is a session continuation - start by reading the handoff file."
159
160
  else
160
161
  log_relay "Starting fresh Claude session with relay support"
161
162
  show_relay_banner
@@ -143,6 +143,10 @@ handle_relay_signal() {
143
143
  log "INFO" "New Claude session started successfully"
144
144
  send_ack "${source_pane}" "${new_pane}"
145
145
  archive_handoff "${handoff_path}"
146
+ # Terminate old pane after new session is stable
147
+ sleep 2
148
+ log "INFO" "Terminating old pane: ${source_pane}"
149
+ tmux kill-pane -t "${source_pane}" 2>/dev/null || true
146
150
  return 0
147
151
  else
148
152
  log "ERROR" "New pane ${new_pane} not found after creation"
@@ -23,8 +23,30 @@ ORCHESTRATOR_DIR="${RELAY_BASE}/orchestrator"
23
23
  ORCHESTRATOR_SCRIPT="${ORCHESTRATOR_DIR}/orchestrator.sh"
24
24
  WRAPPER_SCRIPT="${ORCHESTRATOR_DIR}/claude-wrapper.sh"
25
25
 
26
- # Session name - symphony branding
27
- SESSION_NAME="symphony-session"
26
+ # Session name prefix - symphony branding
27
+ SESSION_PREFIX="symphony-session"
28
+
29
+ # Function to find next available session name
30
+ # Returns: symphony-session, symphony-session-2, symphony-session-3, ...
31
+ find_next_session_name() {
32
+ local base="${SESSION_PREFIX}"
33
+
34
+ # Check if base session exists
35
+ if ! tmux has-session -t "${base}" 2>/dev/null; then
36
+ echo "${base}"
37
+ return
38
+ fi
39
+
40
+ # Find next available numbered session
41
+ local n=2
42
+ while tmux has-session -t "${base}-${n}" 2>/dev/null; do
43
+ ((n++))
44
+ done
45
+ echo "${base}-${n}"
46
+ }
47
+
48
+ # Default session name (will be updated if creating new parallel session)
49
+ SESSION_NAME="${SESSION_PREFIX}"
28
50
 
29
51
  # Colors
30
52
  RED='\033[0;31m'
@@ -74,24 +96,31 @@ for script in "${ORCHESTRATOR_SCRIPT}" "${WRAPPER_SCRIPT}"; do
74
96
  done
75
97
 
76
98
  # Check if session already exists
77
- if tmux has-session -t "${SESSION_NAME}" 2>/dev/null; then
78
- echo -e "${YELLOW}Session '${SESSION_NAME}' already exists.${NC}"
99
+ if tmux has-session -t "${SESSION_PREFIX}" 2>/dev/null; then
100
+ NEXT_SESSION_NAME=$(find_next_session_name)
101
+ echo -e "${YELLOW}Session '${SESSION_PREFIX}' already exists.${NC}"
79
102
  echo ""
80
103
  echo "Options:"
81
104
  echo " 1. Attach to existing session"
82
- echo " 2. Kill and recreate"
83
- echo " 3. Cancel"
105
+ echo " 2. Create new session (${NEXT_SESSION_NAME})"
106
+ echo " 3. Kill and recreate"
107
+ echo " 4. Cancel"
84
108
  echo ""
85
- read -p "Choice [1/2/3]: " choice
109
+ read -p "Choice [1/2/3/4]: " choice
86
110
 
87
111
  case "${choice}" in
88
112
  1)
89
113
  echo "Attaching to existing session..."
90
- exec tmux attach-session -t "${SESSION_NAME}"
114
+ exec tmux attach-session -t "${SESSION_PREFIX}"
91
115
  ;;
92
116
  2)
117
+ echo -e "Creating parallel session: ${GREEN}${NEXT_SESSION_NAME}${NC}"
118
+ SESSION_NAME="${NEXT_SESSION_NAME}"
119
+ ;;
120
+ 3)
93
121
  echo "Killing existing session..."
94
- tmux kill-session -t "${SESSION_NAME}"
122
+ tmux kill-session -t "${SESSION_PREFIX}"
123
+ SESSION_NAME="${SESSION_PREFIX}"
95
124
  ;;
96
125
  *)
97
126
  echo "Cancelled."