claude-symphony 0.2.7 → 0.2.9

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 CHANGED
@@ -18,6 +18,8 @@ claude-symphony is a 10-stage software development workflow pipeline that orches
18
18
  - **10-Stage Pipeline**: Complete development cycle from brainstorming to deployment
19
19
  - **Multi-AI Orchestration**: Intelligent collaboration between Gemini, Claude, and Codex
20
20
  - **Smart HANDOFF System**: Automatic context extraction and semantic compression
21
+ - **Context Manager**: Automatic context monitoring with snapshot/HANDOFF generation at thresholds
22
+ - **Memory Relay (Encore Mode)**: Infinite session orchestration - Claude never stops
21
23
  - **Auto-Checkpoint & Rollback**: Task-based triggers with partial rollback support
22
24
  - **Pipeline Forking**: Branch exploration for architecture alternatives
23
25
  - **Stage Personas**: Optimized AI behavior profiles per stage
@@ -52,6 +54,90 @@ cd my-project
52
54
  /brainstorm
53
55
  ```
54
56
 
57
+ ## Context Management
58
+
59
+ claude-symphony includes automatic context management to ensure continuous workflow even when Claude's context window fills up.
60
+
61
+ ### How It Works
62
+
63
+ ```
64
+ ┌─────────────────────────────────────────────────────────────┐
65
+ │ Context Thresholds (Remaining %) │
66
+ ├─────────────────────────────────────────────────────────────┤
67
+ │ 60% │ Warning │ Display warning banner │
68
+ │ 50% │ Action │ Auto-snapshot + recommend /compact │
69
+ │ 40% │ Critical │ Generate HANDOFF.md + /clear required │
70
+ └─────────────────────────────────────────────────────────────┘
71
+ ```
72
+
73
+ ### Encore Mode (Memory Relay)
74
+
75
+ Start with `claude-symphony-play` to enable automatic session handoff:
76
+
77
+ ```bash
78
+ # Install Memory Relay (one-time)
79
+ ./scripts/memory-relay/install.sh
80
+
81
+ # Start Encore Mode
82
+ claude-symphony-play
83
+
84
+ # With bypass mode
85
+ claude-symphony-play --bypass
86
+ ```
87
+
88
+ When context drops below 50%, the system automatically:
89
+ 1. Creates a snapshot in `state/context/`
90
+ 2. Generates `HANDOFF.md` with recovery instructions
91
+ 3. Signals Memory Relay to start a new session
92
+ 4. New session continues from where you left off
93
+
94
+ ### Manual Context Commands
95
+
96
+ ```bash
97
+ # Check context status
98
+ /context
99
+
100
+ # Save snapshot manually
101
+ /context --save
102
+
103
+ # List all snapshots
104
+ /context --list
105
+
106
+ # Trigger relay manually
107
+ /context --relay
108
+ ```
109
+
110
+ ### Context Automation Architecture
111
+
112
+ ```
113
+ ┌─────────────────────────────────────────────────────────────┐
114
+ │ statusline.sh (polls every 300ms) │
115
+ │ ↓ context ≤ 50% │
116
+ │ scripts/context-manager.sh --auto-compact │
117
+ │ ↓ │
118
+ │ ┌────────────────────────────────────────────────────────┐ │
119
+ │ │ 1. Auto-snapshot → state/context/auto-snapshot-*.md │ │
120
+ │ │ 2. HANDOFF.md → project root │ │
121
+ │ │ 3. Archive → state/handoffs/ │ │
122
+ │ │ 4. RELAY_READY signal → Memory Relay FIFO │ │
123
+ │ └────────────────────────────────────────────────────────┘ │
124
+ │ ↓ │
125
+ │ Memory Relay Orchestrator │
126
+ │ ↓ │
127
+ │ New Claude session starts with HANDOFF.md │
128
+ └─────────────────────────────────────────────────────────────┘
129
+ ```
130
+
131
+ ### Key Files
132
+
133
+ | File | Purpose |
134
+ |------|---------|
135
+ | `.claude/hooks/statusline.sh` | Real-time context monitoring |
136
+ | `.claude/hooks/stop.sh` | Auto-trigger after response |
137
+ | `scripts/context-manager.sh` | Snapshot/HANDOFF generation |
138
+ | `state/context/` | Auto-saved snapshots |
139
+ | `state/handoffs/` | HANDOFF archive |
140
+
55
141
  ## Commands
56
142
 
57
143
  ### CLI Commands
@@ -71,6 +157,7 @@ cd my-project
71
157
  | `/next` | Move to next stage |
72
158
  | `/handoff` | Create handoff document |
73
159
  | `/checkpoint` | Create checkpoint |
160
+ | `/context` | Context management (status, save, list, relay) |
74
161
 
75
162
  See [template/docs/commands.md](template/docs/commands.md) for the complete command reference.
76
163
 
@@ -111,8 +198,10 @@ claude-symphony/
111
198
  ├── template/ # Project template (copied to user projects)
112
199
  │ ├── .claude/ # Claude Code config
113
200
  │ │ ├── commands/ # Slash commands (30+)
114
- │ │ ├── hooks/ # Lifecycle hooks (8)
201
+ │ │ ├── hooks/ # Lifecycle hooks (statusline, stop, etc.)
115
202
  │ │ └── skills/ # AI skills (7)
203
+ │ ├── scripts/ # Runtime scripts
204
+ │ │ └── context-manager.sh # Context automation
116
205
  │ ├── stages/ # 10-stage pipeline
117
206
  │ ├── config/ # Configuration files (25+)
118
207
  │ ├── state/ # State management
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
@@ -0,0 +1,22 @@
1
+ import { S as StageId } from '../stage-Cy_k5zNZ.js';
2
+
3
+ /**
4
+ * Pre-transition result
5
+ */
6
+ interface PreTransitionResult {
7
+ allowed: boolean;
8
+ currentStage: StageId;
9
+ nextStage: StageId | 'completed';
10
+ blockers: string[];
11
+ summary: string;
12
+ }
13
+ /**
14
+ * Run pre-transition validation
15
+ */
16
+ declare function runPreTransition(projectRoot: string, currentStageArg?: StageId, nextStageArg?: StageId): Promise<PreTransitionResult>;
17
+ /**
18
+ * CLI entry point
19
+ */
20
+ declare function main(): Promise<void>;
21
+
22
+ export { type PreTransitionResult, main, runPreTransition };