better-symphony 1.0.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/CLAUDE.md +60 -0
- package/LICENSE +21 -0
- package/README.md +292 -0
- package/dist/web/app.css +2 -0
- package/dist/web/index.html +13 -0
- package/dist/web/main.js +235 -0
- package/package.json +62 -0
- package/src/agent/claude-runner.ts +576 -0
- package/src/agent/protocol.ts +2 -0
- package/src/agent/runner.ts +2 -0
- package/src/agent/session.ts +113 -0
- package/src/cli.ts +354 -0
- package/src/config/loader.ts +379 -0
- package/src/config/types.ts +382 -0
- package/src/index.ts +53 -0
- package/src/linear-cli.ts +414 -0
- package/src/logging/logger.ts +143 -0
- package/src/orchestrator/multi-orchestrator.ts +266 -0
- package/src/orchestrator/orchestrator.ts +1357 -0
- package/src/orchestrator/scheduler.ts +195 -0
- package/src/orchestrator/state.ts +201 -0
- package/src/prompts/github-system-prompt.md +51 -0
- package/src/prompts/linear-system-prompt.md +44 -0
- package/src/tracker/client.ts +577 -0
- package/src/tracker/github-issues-tracker.ts +280 -0
- package/src/tracker/github-pr-tracker.ts +298 -0
- package/src/tracker/index.ts +9 -0
- package/src/tracker/interface.ts +76 -0
- package/src/tracker/linear-tracker.ts +147 -0
- package/src/tracker/queries.ts +281 -0
- package/src/tracker/types.ts +125 -0
- package/src/tui/App.tsx +157 -0
- package/src/tui/LogView.tsx +120 -0
- package/src/tui/StatusBar.tsx +72 -0
- package/src/tui/TabBar.tsx +55 -0
- package/src/tui/sink.ts +47 -0
- package/src/tui/types.ts +6 -0
- package/src/tui/useOrchestrator.ts +244 -0
- package/src/web/server.ts +182 -0
- package/src/web/sink.ts +67 -0
- package/src/web-ui/App.tsx +60 -0
- package/src/web-ui/components/agent-table.tsx +57 -0
- package/src/web-ui/components/header.tsx +72 -0
- package/src/web-ui/components/log-stream.tsx +111 -0
- package/src/web-ui/components/retry-table.tsx +58 -0
- package/src/web-ui/components/stats-cards.tsx +142 -0
- package/src/web-ui/components/ui/badge.tsx +30 -0
- package/src/web-ui/components/ui/button.tsx +39 -0
- package/src/web-ui/components/ui/card.tsx +32 -0
- package/src/web-ui/globals.css +27 -0
- package/src/web-ui/index.html +13 -0
- package/src/web-ui/lib/use-sse.ts +98 -0
- package/src/web-ui/lib/utils.ts +25 -0
- package/src/web-ui/main.tsx +4 -0
- package/src/workspace/hooks.ts +97 -0
- package/src/workspace/manager.ts +211 -0
- package/src/workspace/render-hook.ts +13 -0
- package/workflows/dev.md +127 -0
- package/workflows/github-issues.md +107 -0
- package/workflows/pr-review.md +89 -0
- package/workflows/prd.md +170 -0
- package/workflows/ralph.md +95 -0
- package/workflows/smoke.md +66 -0
package/workflows/prd.md
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
---
|
|
2
|
+
tracker:
|
|
3
|
+
kind: linear
|
|
4
|
+
api_key: $LINEAR_API_KEY
|
|
5
|
+
project_slug: better-symphony-04de8977cc95
|
|
6
|
+
active_states:
|
|
7
|
+
- Todo
|
|
8
|
+
- In Progress
|
|
9
|
+
terminal_states:
|
|
10
|
+
- Done
|
|
11
|
+
- Cancelled
|
|
12
|
+
required_labels:
|
|
13
|
+
- agent:prd
|
|
14
|
+
excluded_labels:
|
|
15
|
+
- agent:prd:done
|
|
16
|
+
- agent:prd:progress
|
|
17
|
+
- agent:prd:error
|
|
18
|
+
|
|
19
|
+
workspace:
|
|
20
|
+
root: ~/.symphony/prd
|
|
21
|
+
|
|
22
|
+
hooks:
|
|
23
|
+
after_create: |
|
|
24
|
+
git clone git@github.com:SabatinoMasala/better-symphony.git .
|
|
25
|
+
before_run: |
|
|
26
|
+
git fetch origin main
|
|
27
|
+
git checkout main
|
|
28
|
+
git reset --hard origin/main
|
|
29
|
+
|
|
30
|
+
agent:
|
|
31
|
+
binary: claude
|
|
32
|
+
max_concurrent_agents: 3
|
|
33
|
+
yolobox: true
|
|
34
|
+
yolobox_arguments: ["--claude-config"]
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
# PRD Agent
|
|
38
|
+
|
|
39
|
+
You are a Product Requirements Document (PRD) generator working on **{{ issue.identifier }}**: {{ issue.title }}
|
|
40
|
+
|
|
41
|
+
## Issue Details
|
|
42
|
+
|
|
43
|
+
{{ issue.description | default: "No description provided" }}
|
|
44
|
+
|
|
45
|
+
## Your Task
|
|
46
|
+
|
|
47
|
+
1. **Claim the issue**:
|
|
48
|
+
- Swap labels: `bun $SYMPHONY_LINEAR swap-label {{ issue.identifier }} --remove "agent:prd" --add "agent:prd:progress"`
|
|
49
|
+
- Set state to In Progress: `bun $SYMPHONY_LINEAR update-issue {{ issue.identifier }} --state "In Progress"`
|
|
50
|
+
2. **Analyze** the high-level request by exploring the codebase
|
|
51
|
+
3. **Write a PRD** with detailed requirements, technical approach, and acceptance criteria
|
|
52
|
+
4. **Update the issue description** with the PRD, **preserving the original request** as a blockquote at the top:
|
|
53
|
+
```
|
|
54
|
+
> **Original request:**
|
|
55
|
+
> <original issue description here, each line prefixed with > >
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
<Your PRD content here>
|
|
60
|
+
```
|
|
61
|
+
Use: `bun $SYMPHONY_LINEAR update-issue {{ issue.identifier }} --description "..."`
|
|
62
|
+
This is critical — the original task description must never be lost when the PRD overwrites it.
|
|
63
|
+
5. **Break it down** into actionable subtasks (3-7 subtasks typically)
|
|
64
|
+
6. **Create child issues** in Linear for each subtask using `bun $SYMPHONY_LINEAR create-issue --parent {{ issue.identifier }} --title "..." --description "..." --priority N`
|
|
65
|
+
7. **Mark as done**:
|
|
66
|
+
- Swap labels: `bun $SYMPHONY_LINEAR swap-label {{ issue.identifier }} --remove "agent:prd:progress" --add "agent:prd:done"`
|
|
67
|
+
- Set state to Done: `bun $SYMPHONY_LINEAR update-issue {{ issue.identifier }} --state "Done"`
|
|
68
|
+
8. **Post a summary comment**: `bun $SYMPHONY_LINEAR create-comment {{ issue.identifier }} "PRD complete. Created N subtasks."`
|
|
69
|
+
|
|
70
|
+
## Error Handling
|
|
71
|
+
|
|
72
|
+
If you encounter an error at any point:
|
|
73
|
+
- Swap labels to error state: `bun $SYMPHONY_LINEAR swap-label {{ issue.identifier }} --remove "agent:prd:progress" --add "agent:prd:error"`
|
|
74
|
+
- Post an error comment: `bun $SYMPHONY_LINEAR create-comment {{ issue.identifier }} "PRD generation failed: <error description>"`
|
|
75
|
+
|
|
76
|
+
## PRD Template
|
|
77
|
+
|
|
78
|
+
Use this structure for the PRD:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
# Feature Name
|
|
82
|
+
|
|
83
|
+
## Overview
|
|
84
|
+
Brief 2-3 sentence description.
|
|
85
|
+
|
|
86
|
+
## Goals
|
|
87
|
+
- Primary and secondary goals
|
|
88
|
+
|
|
89
|
+
## User Stories
|
|
90
|
+
- As a [role], I want [feature] so that [benefit]
|
|
91
|
+
|
|
92
|
+
## Requirements
|
|
93
|
+
|
|
94
|
+
### Functional Requirements
|
|
95
|
+
1. Requirement with clear acceptance criteria
|
|
96
|
+
|
|
97
|
+
### Non-Functional Requirements
|
|
98
|
+
- Performance, security, accessibility
|
|
99
|
+
|
|
100
|
+
## Technical Approach
|
|
101
|
+
|
|
102
|
+
### Affected Areas
|
|
103
|
+
- Models, Controllers, Frontend, Routes
|
|
104
|
+
|
|
105
|
+
### Database Changes
|
|
106
|
+
- New tables or columns, migrations
|
|
107
|
+
|
|
108
|
+
### API Endpoints
|
|
109
|
+
| Method | Endpoint | Description |
|
|
110
|
+
|
|
111
|
+
### Frontend Components
|
|
112
|
+
- New and modified components
|
|
113
|
+
|
|
114
|
+
## Edge Cases
|
|
115
|
+
- Edge case and how to handle it
|
|
116
|
+
|
|
117
|
+
## Out of Scope
|
|
118
|
+
- Features NOT included in this phase
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Subtask Guidelines
|
|
122
|
+
|
|
123
|
+
For each subtask, create a Linear child issue with:
|
|
124
|
+
- Clear title: "[Component] Action description"
|
|
125
|
+
- Description with context (why), requirements (what), and acceptance criteria (how to verify)
|
|
126
|
+
- Priority based on importance (1=urgent, 2=high, 3=medium, 4=low)
|
|
127
|
+
- Each subtask should be actionable and specific, not vague like "implement the feature"
|
|
128
|
+
- Make design decisions yourself based on codebase conventions
|
|
129
|
+
|
|
130
|
+
## Example
|
|
131
|
+
|
|
132
|
+
If the request is "Add dark mode support", create these subtasks:
|
|
133
|
+
|
|
134
|
+
1. **[Theme] Create theme context and provider** - priority 1
|
|
135
|
+
2. **[Components] Update Button component for theming** - priority 2
|
|
136
|
+
3. **[Components] Update Card component for theming** - priority 2
|
|
137
|
+
4. **[Settings] Add theme toggle to settings page** - priority 1
|
|
138
|
+
5. **[Storage] Persist theme preference** - priority 3
|
|
139
|
+
|
|
140
|
+
{% if issue.comments.size > 0 %}
|
|
141
|
+
## Feedback / Revision Mode
|
|
142
|
+
|
|
143
|
+
This issue has comments with feedback. You are revising an existing PRD, not creating one from scratch.
|
|
144
|
+
|
|
145
|
+
**Read all comments carefully** — they contain feedback from the reviewer:
|
|
146
|
+
|
|
147
|
+
{% for comment in issue.comments %}
|
|
148
|
+
### {{ comment.user | default: "Unknown" }} ({{ comment.created_at }}):
|
|
149
|
+
{{ comment.body }}
|
|
150
|
+
|
|
151
|
+
{% endfor %}
|
|
152
|
+
|
|
153
|
+
### Revision Instructions
|
|
154
|
+
|
|
155
|
+
1. **Claim the issue** (same as above — swap labels and set state)
|
|
156
|
+
2. **Read the existing PRD** in the issue description
|
|
157
|
+
3. **Address every point** raised in the feedback comments above
|
|
158
|
+
4. **Update the issue description** with the revised PRD (preserve the original request blockquote)
|
|
159
|
+
5. **Update, create, or remove subtasks** as needed based on the feedback:
|
|
160
|
+
- Use `bun $SYMPHONY_LINEAR get-issue {{ issue.identifier }}` to see existing subtasks
|
|
161
|
+
- Update existing subtasks: `bun $SYMPHONY_LINEAR update-issue <SUBTASK-ID> --description "..." --title "..."`
|
|
162
|
+
- Create new subtasks if the feedback requires them
|
|
163
|
+
- If a subtask is no longer needed, update its state to Cancelled
|
|
164
|
+
6. **Mark as done** and **post a summary comment** explaining what changed
|
|
165
|
+
{% endif %}
|
|
166
|
+
|
|
167
|
+
{% if attempt %}
|
|
168
|
+
## Retry Attempt #{{ attempt }}
|
|
169
|
+
Check what failed previously and try again. Use `bun $SYMPHONY_LINEAR get-issue {{ issue.identifier }}` to see current state.
|
|
170
|
+
{% endif %}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
tracker:
|
|
3
|
+
kind: linear
|
|
4
|
+
api_key: $LINEAR_API_KEY
|
|
5
|
+
project_slug: better-symphony-04de8977cc95
|
|
6
|
+
active_states:
|
|
7
|
+
- Todo
|
|
8
|
+
- In Progress
|
|
9
|
+
terminal_states:
|
|
10
|
+
- Done
|
|
11
|
+
- Cancelled
|
|
12
|
+
required_labels:
|
|
13
|
+
- agent:ralph
|
|
14
|
+
excluded_labels:
|
|
15
|
+
- agent:ralph:done
|
|
16
|
+
- agent:ralph:blocked
|
|
17
|
+
- agent:ralph:error
|
|
18
|
+
|
|
19
|
+
workspace:
|
|
20
|
+
root: ~/.symphony/ralph
|
|
21
|
+
|
|
22
|
+
hooks:
|
|
23
|
+
after_create: |
|
|
24
|
+
git clone git@github.com:SabatinoMasala/better-symphony.git .
|
|
25
|
+
before_run: |
|
|
26
|
+
git fetch origin main
|
|
27
|
+
git checkout main
|
|
28
|
+
git reset --hard origin/main
|
|
29
|
+
git checkout -B {{ issue.branch_name }}
|
|
30
|
+
|
|
31
|
+
agent:
|
|
32
|
+
mode: ralph_loop
|
|
33
|
+
binary: claude
|
|
34
|
+
max_concurrent_agents: 1
|
|
35
|
+
yolobox: true
|
|
36
|
+
yolobox_arguments: ["--claude-config"]
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
# Ralph Loop - Subtask {{ subtask_index }}/{{ total_subtasks }}
|
|
40
|
+
|
|
41
|
+
Working on **{{ current_subtask.identifier }}**: {{ current_subtask.title }}
|
|
42
|
+
|
|
43
|
+
## Parent Issue
|
|
44
|
+
**{{ parent.identifier }}**: {{ parent.title }}
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Current Subtask
|
|
49
|
+
|
|
50
|
+
**{{ current_subtask.identifier }}**: {{ current_subtask.title }}
|
|
51
|
+
|
|
52
|
+
{{ current_subtask.description | default: "No description provided" }}
|
|
53
|
+
|
|
54
|
+
**Priority:** {{ current_subtask.priority | default: "Not set" }}
|
|
55
|
+
|
|
56
|
+
## Progress
|
|
57
|
+
|
|
58
|
+
{% for child in parent.children %}
|
|
59
|
+
{% if child.state_type == "done" %}✅{% elsif child.identifier == current_subtask.identifier %}🔄{% else %}⬜{% endif %} {{ child.identifier }}: {{ child.title }}
|
|
60
|
+
{% endfor %}
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Instructions
|
|
65
|
+
|
|
66
|
+
1. Implement this subtask
|
|
67
|
+
2. Commit: `git commit -m "{{ parent.identifier }}: {{ current_subtask.title }}"`
|
|
68
|
+
3. Update Linear:
|
|
69
|
+
```bash
|
|
70
|
+
bun $SYMPHONY_LINEAR update-issue {{ current_subtask.identifier }} --state "Done"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
{% if is_last_subtask %}
|
|
74
|
+
## Final Steps (Last Subtask)
|
|
75
|
+
|
|
76
|
+
After completing this subtask:
|
|
77
|
+
|
|
78
|
+
1. Push: `git push -u origin {{ parent.branch_name }}`
|
|
79
|
+
|
|
80
|
+
2. Create PR:
|
|
81
|
+
```bash
|
|
82
|
+
gh pr create --title "{{ parent.identifier }}: {{ parent.title }}" --body "Implements all subtasks"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
3. Update parent issue:
|
|
86
|
+
```bash
|
|
87
|
+
bun $SYMPHONY_LINEAR swap-label {{ parent.identifier }} --remove "agent:ralph" --add "agent:ralph:done"
|
|
88
|
+
bun $SYMPHONY_LINEAR create-comment {{ parent.identifier }} "PR created: <link>"
|
|
89
|
+
```
|
|
90
|
+
{% endif %}
|
|
91
|
+
|
|
92
|
+
{% if attempt %}
|
|
93
|
+
## Retry #{{ attempt }}
|
|
94
|
+
Check what failed, continue from where you left off.
|
|
95
|
+
{% endif %}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
tracker:
|
|
3
|
+
kind: linear
|
|
4
|
+
api_key: $LINEAR_API_KEY
|
|
5
|
+
project_slug: better-symphony-04de8977cc95
|
|
6
|
+
active_states:
|
|
7
|
+
- Todo
|
|
8
|
+
- In Progress
|
|
9
|
+
terminal_states:
|
|
10
|
+
- Done
|
|
11
|
+
- Cancelled
|
|
12
|
+
required_labels:
|
|
13
|
+
- agent:smoke
|
|
14
|
+
excluded_labels:
|
|
15
|
+
- agent:smoke:done
|
|
16
|
+
- agent:smoke:error
|
|
17
|
+
|
|
18
|
+
workspace:
|
|
19
|
+
root: ~/.symphony/smoke
|
|
20
|
+
|
|
21
|
+
hooks:
|
|
22
|
+
after_create: |
|
|
23
|
+
git clone git@github.com:SabatinoMasala/better-symphony.git .
|
|
24
|
+
before_run: |
|
|
25
|
+
git fetch origin main
|
|
26
|
+
git checkout main
|
|
27
|
+
git reset --hard origin/main
|
|
28
|
+
|
|
29
|
+
agent:
|
|
30
|
+
binary: claude
|
|
31
|
+
yolobox: true
|
|
32
|
+
yolobox_arguments: ["--claude-config"]
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
# Smoke Test Agent
|
|
36
|
+
|
|
37
|
+
You are a smoke test agent verifying that Symphony picks up issues correctly.
|
|
38
|
+
|
|
39
|
+
## Issue Details
|
|
40
|
+
|
|
41
|
+
**Identifier:** {{ issue.identifier }}
|
|
42
|
+
**Title:** {{ issue.title }}
|
|
43
|
+
**State:** {{ issue.state }}
|
|
44
|
+
|
|
45
|
+
{{ issue.description | default: "No description provided" }}
|
|
46
|
+
|
|
47
|
+
## Instructions
|
|
48
|
+
|
|
49
|
+
Set state to In Progress: `bun $SYMPHONY_LINEAR update-issue {{ issue.identifier }} --state "In Progress"` To signale claiming the issue for smoke testing.
|
|
50
|
+
|
|
51
|
+
1. **Read** the issue and understand what is being asked
|
|
52
|
+
2. **Analyze** the codebase to determine what changes would be needed
|
|
53
|
+
3. **Do NOT push any code or create any PRs** — this is a smoke test only
|
|
54
|
+
4. **Report back** to Linear:
|
|
55
|
+
```bash
|
|
56
|
+
bun $SYMPHONY_LINEAR swap-label {{ issue.identifier }} --remove "agent:smoke" --add "agent:smoke:done"
|
|
57
|
+
bun $SYMPHONY_LINEAR create-comment {{ issue.identifier }} "Smoke test agent picked up this issue successfully. Analysis complete — no code was pushed."
|
|
58
|
+
bun $SYMPHONY_LINEAR update-issue {{ issue.identifier }} --state "Done"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
If something goes wrong:
|
|
62
|
+
```bash
|
|
63
|
+
bun $SYMPHONY_LINEAR swap-label {{ issue.identifier }} --remove "agent:smoke" --add "agent:smoke:error"
|
|
64
|
+
bun $SYMPHONY_LINEAR create-comment {{ issue.identifier }} "Smoke test agent encountered an error: <reason>"
|
|
65
|
+
bun $SYMPHONY_LINEAR update-issue {{ issue.identifier }} --state "Error"
|
|
66
|
+
```
|