Skip to content

Commit 4d77ecf

Browse files
author
StackMemory Bot (CLI)
committed
feat(symphony): add Symphony orchestrator integration for cross-workspace context persistence
- CLI commands: capture, restore, archive, search for managing cross-run context - Hook scripts: after-create (init+restore), after-run (capture), before-remove (archive) - Global SQLite database at ~/.stackmemory/symphony/ for cross-workspace storage - WORKFLOW.md template documenting integration setup - Tests covering capture, restore, archive, search, and hook script validation
1 parent 735af2a commit 4d77ecf

File tree

7 files changed

+918
-0
lines changed

7 files changed

+918
-0
lines changed

scripts/symphony/WORKFLOW.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# StackMemory + Symphony Integration
2+
3+
## Overview
4+
5+
StackMemory provides persistent agent memory across Symphony workspace lifecycle events.
6+
When Symphony creates a workspace for an issue, StackMemory restores context from prior
7+
attempts. After each run, it captures context. Before workspace removal, it archives everything.
8+
9+
## Hook Configuration
10+
11+
Add to your Symphony `config.toml`:
12+
13+
```toml
14+
[hooks]
15+
after_create = "scripts/symphony/after-create.sh"
16+
after_run = "scripts/symphony/after-run.sh"
17+
before_remove = "scripts/symphony/before-remove.sh"
18+
```
19+
20+
## Environment Variables
21+
22+
Symphony sets these automatically:
23+
24+
| Variable | Description | Example |
25+
|---|---|---|
26+
| `SYMPHONY_WORKSPACE_DIR` | Workspace path | `/tmp/symphony/STA-476` |
27+
| `SYMPHONY_ISSUE_ID` | Internal issue ID | `uuid-string` |
28+
| `SYMPHONY_ISSUE_IDENTIFIER` | Human-readable ID | `STA-476` |
29+
| `SYMPHONY_ATTEMPT` | Current attempt number | `1` |
30+
31+
## Lifecycle
32+
33+
```
34+
Issue assigned
35+
→ after_create: stackmemory init + restore prior context
36+
→ agent runs...
37+
→ after_run: capture frames/anchors/events to global store
38+
→ (repeat for retries, attempt increments)
39+
→ before_remove: archive full context, workspace deleted
40+
```
41+
42+
## Manual Commands
43+
44+
```bash
45+
# Capture context from a workspace
46+
stackmemory symphony capture --issue STA-476 --workspace /path/to/ws --attempt 1
47+
48+
# Restore prior context into workspace
49+
stackmemory symphony restore --issue STA-476 --workspace /path/to/ws
50+
51+
# Archive before deletion
52+
stackmemory symphony archive --issue STA-476 --workspace /path/to/ws
53+
54+
# Search across all issue contexts
55+
stackmemory symphony search "database migration"
56+
```
57+
58+
## Storage
59+
60+
Global context stored at `~/.stackmemory/symphony/context.db` (SQLite).
61+
Per-workspace context at `<workspace>/.stackmemory/context.db`.
62+
63+
The global database persists across workspace deletions, enabling cross-attempt learning.

scripts/symphony/after-create.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env bash
2+
# Symphony after_create hook
3+
# Initializes StackMemory in the workspace directory
4+
# Called once when Symphony creates a new workspace for an issue
5+
#
6+
# Environment: SYMPHONY_WORKSPACE_DIR, SYMPHONY_ISSUE_ID, SYMPHONY_ISSUE_IDENTIFIER
7+
set -euo pipefail
8+
9+
WORKSPACE="${SYMPHONY_WORKSPACE_DIR:-$(pwd)}"
10+
ISSUE_ID="${SYMPHONY_ISSUE_IDENTIFIER:-${SYMPHONY_ISSUE_ID:-unknown}}"
11+
12+
cd "$WORKSPACE"
13+
14+
# Initialize StackMemory if not already present
15+
if [ ! -d ".stackmemory" ]; then
16+
stackmemory init 2>/dev/null || true
17+
fi
18+
19+
# Restore relevant context from prior runs on this issue
20+
stackmemory symphony restore --issue "$ISSUE_ID" --workspace "$WORKSPACE" 2>/dev/null || true
21+
22+
echo "[stackmemory] Workspace initialized for $ISSUE_ID"

scripts/symphony/after-run.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env bash
2+
# Symphony after_run hook
3+
# Captures context from the agent run and tags it with the issue identifier
4+
# Called after each agent attempt (success or failure)
5+
#
6+
# Environment: SYMPHONY_WORKSPACE_DIR, SYMPHONY_ISSUE_ID, SYMPHONY_ISSUE_IDENTIFIER
7+
set -euo pipefail
8+
9+
WORKSPACE="${SYMPHONY_WORKSPACE_DIR:-$(pwd)}"
10+
ISSUE_ID="${SYMPHONY_ISSUE_IDENTIFIER:-${SYMPHONY_ISSUE_ID:-unknown}}"
11+
ATTEMPT="${SYMPHONY_ATTEMPT:-1}"
12+
13+
cd "$WORKSPACE"
14+
15+
# Capture context from this run, tagged with issue ID and attempt number
16+
stackmemory symphony capture \
17+
--issue "$ISSUE_ID" \
18+
--workspace "$WORKSPACE" \
19+
--attempt "$ATTEMPT" \
20+
2>/dev/null || true
21+
22+
echo "[stackmemory] Context captured for $ISSUE_ID (attempt $ATTEMPT)"

scripts/symphony/before-remove.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/usr/bin/env bash
2+
# Symphony before_remove hook
3+
# Archives workspace context before Symphony deletes the workspace
4+
# Called when the issue reaches a terminal state
5+
#
6+
# Environment: SYMPHONY_WORKSPACE_DIR, SYMPHONY_ISSUE_ID, SYMPHONY_ISSUE_IDENTIFIER
7+
set -euo pipefail
8+
9+
WORKSPACE="${SYMPHONY_WORKSPACE_DIR:-$(pwd)}"
10+
ISSUE_ID="${SYMPHONY_ISSUE_IDENTIFIER:-${SYMPHONY_ISSUE_ID:-unknown}}"
11+
12+
cd "$WORKSPACE"
13+
14+
# Archive context to global store before workspace deletion
15+
stackmemory symphony archive \
16+
--issue "$ISSUE_ID" \
17+
--workspace "$WORKSPACE" \
18+
2>/dev/null || true
19+
20+
echo "[stackmemory] Context archived for $ISSUE_ID"

0 commit comments

Comments
 (0)