relay-cc 2.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.
Files changed (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +428 -0
  3. package/agents/relay-codebase-mapper.md +761 -0
  4. package/agents/relay-debugger.md +1203 -0
  5. package/agents/relay-estimator.md +257 -0
  6. package/agents/relay-executor.md +823 -0
  7. package/agents/relay-plan-checker.md +812 -0
  8. package/agents/relay-planner.md +1418 -0
  9. package/agents/relay-reviewer.md +279 -0
  10. package/agents/relay-ticket-researcher.md +287 -0
  11. package/agents/relay-verifier.md +778 -0
  12. package/bin/install.js +1667 -0
  13. package/commands/relay/add-todo.md +193 -0
  14. package/commands/relay/check-todos.md +200 -0
  15. package/commands/relay/debug.md +169 -0
  16. package/commands/relay/estimate.md +182 -0
  17. package/commands/relay/help.md +328 -0
  18. package/commands/relay/history.md +203 -0
  19. package/commands/relay/map-codebase.md +71 -0
  20. package/commands/relay/pause-work.md +128 -0
  21. package/commands/relay/pr.md +223 -0
  22. package/commands/relay/quick.md +307 -0
  23. package/commands/relay/resume-work.md +40 -0
  24. package/commands/relay/resume.md +181 -0
  25. package/commands/relay/review.md +322 -0
  26. package/commands/relay/rollback.md +248 -0
  27. package/commands/relay/set-profile.md +116 -0
  28. package/commands/relay/settings.md +165 -0
  29. package/commands/relay/setup.md +247 -0
  30. package/commands/relay/status.md +131 -0
  31. package/commands/relay/tickets.md +106 -0
  32. package/commands/relay/update.md +200 -0
  33. package/commands/relay/work.md +398 -0
  34. package/hooks/dist/relay-check-update.js +61 -0
  35. package/hooks/dist/relay-statusline.js +91 -0
  36. package/package.json +47 -0
  37. package/relay/references/checkpoints.md +1078 -0
  38. package/relay/references/continuation-format.md +249 -0
  39. package/relay/references/git-integration.md +209 -0
  40. package/relay/references/model-profiles.md +57 -0
  41. package/relay/references/planning-config.md +189 -0
  42. package/relay/references/questioning.md +141 -0
  43. package/relay/references/tdd.md +263 -0
  44. package/relay/references/ui-brand.md +162 -0
  45. package/relay/references/verification-patterns.md +612 -0
  46. package/relay/templates/DEBUG.md +159 -0
  47. package/relay/templates/UAT.md +247 -0
  48. package/relay/templates/analysis.md +101 -0
  49. package/relay/templates/codebase/architecture.md +255 -0
  50. package/relay/templates/codebase/concerns.md +310 -0
  51. package/relay/templates/codebase/conventions.md +307 -0
  52. package/relay/templates/codebase/integrations.md +280 -0
  53. package/relay/templates/codebase/stack.md +186 -0
  54. package/relay/templates/codebase/structure.md +285 -0
  55. package/relay/templates/codebase/testing.md +480 -0
  56. package/relay/templates/config.json +40 -0
  57. package/relay/templates/context.md +283 -0
  58. package/relay/templates/continue-here.md +78 -0
  59. package/relay/templates/debug-subagent-prompt.md +91 -0
  60. package/relay/templates/estimate.md +108 -0
  61. package/relay/templates/phase-prompt.md +567 -0
  62. package/relay/templates/planner-subagent-prompt.md +117 -0
  63. package/relay/templates/research.md +552 -0
  64. package/relay/templates/state.md +127 -0
  65. package/relay/templates/summary.md +246 -0
  66. package/relay/templates/verification-report.md +322 -0
  67. package/relay/workflows/analyze-ticket.md +42 -0
  68. package/relay/workflows/diagnose-issues.md +231 -0
  69. package/relay/workflows/execute-phase.md +700 -0
  70. package/relay/workflows/execute-plan.md +1851 -0
  71. package/relay/workflows/map-codebase.md +357 -0
  72. package/relay/workflows/resume-project.md +307 -0
  73. package/relay/workflows/sync-ticket.md +58 -0
  74. package/relay/workflows/verify-phase.md +628 -0
  75. package/relay/workflows/verify-ticket.md +596 -0
  76. package/scripts/build-hooks.js +42 -0
@@ -0,0 +1,322 @@
1
+ ---
2
+ name: relay:review
3
+ description: Review a PR or address review comments on your own PR
4
+ allowed-tools:
5
+ - Read
6
+ - Write
7
+ - Edit
8
+ - Bash
9
+ - Glob
10
+ - Grep
11
+ - Task
12
+ - AskUserQuestion
13
+ ---
14
+
15
+ <objective>
16
+ Two modes:
17
+ - **Mode A — Review a PR**: Analyze someone else's PR with a code review agent
18
+ - **Mode B — Address comments**: Fix review comments on your own PR
19
+
20
+ Selected upfront via user choice.
21
+ </objective>
22
+
23
+ <context>
24
+ @.relay/config.json
25
+ @.relay/STATE.md
26
+ </context>
27
+
28
+ <process>
29
+
30
+ ## 0. Pre-flight
31
+
32
+ ```bash
33
+ test -f .relay/config.json && echo "config exists" || echo "no config"
34
+ command -v gh >/dev/null 2>&1 && echo "gh available" || echo "gh missing"
35
+ ```
36
+
37
+ If no config: suggest `/relay:setup` and STOP.
38
+ If `gh` CLI not available: report that `gh` is required and STOP.
39
+
40
+ Read model profile:
41
+ ```bash
42
+ MODEL_PROFILE=$(cat .relay/config.json 2>/dev/null | grep -o '"model_profile"[[:space:]]*:[[:space:]]*"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"' || echo "balanced")
43
+ ```
44
+
45
+ **Model lookup table:**
46
+
47
+ | Agent | quality | balanced | budget |
48
+ |-------|---------|----------|--------|
49
+ | relay-reviewer | opus | sonnet | sonnet |
50
+
51
+ ## 1. Choose Mode
52
+
53
+ ```
54
+ AskUserQuestion(
55
+ header: "Review",
56
+ question: "What would you like to do?",
57
+ options: [
58
+ { label: "Review a PR", description: "Analyze someone else's PR and provide code review" },
59
+ { label: "Address comments", description: "Fix review comments on your own PR" }
60
+ ]
61
+ )
62
+ ```
63
+
64
+ ---
65
+
66
+ ## Mode A — Review a PR
67
+
68
+ ### A1. List Open PRs
69
+
70
+ ```bash
71
+ gh pr list --state open --limit 20
72
+ ```
73
+
74
+ If no open PRs: report and STOP.
75
+
76
+ ```
77
+ AskUserQuestion(
78
+ header: "PR",
79
+ question: "Which PR would you like to review?",
80
+ options: [
81
+ { label: "#${PR_1_NUM}", description: "${PR_1_TITLE}" },
82
+ { label: "#${PR_2_NUM}", description: "${PR_2_TITLE}" },
83
+ { label: "#${PR_3_NUM}", description: "${PR_3_TITLE}" }
84
+ ]
85
+ )
86
+ ```
87
+
88
+ ### A2. Save Current Branch and Checkout PR
89
+
90
+ ```bash
91
+ ORIGINAL_BRANCH=$(git branch --show-current)
92
+ git fetch origin
93
+ gh pr checkout ${PR_NUMBER}
94
+ ```
95
+
96
+ ### A3. Get Diff
97
+
98
+ ```bash
99
+ BASE_BRANCH=$(gh pr view ${PR_NUMBER} --json baseRefName --jq '.baseRefName')
100
+ git diff ${BASE_BRANCH}...HEAD --stat
101
+ git diff ${BASE_BRANCH}...HEAD
102
+ ```
103
+
104
+ ### A4. Spawn Reviewer Agent
105
+
106
+ ```bash
107
+ mkdir -p .relay/reviews
108
+ ```
109
+
110
+ ```
111
+ Task(
112
+ prompt="
113
+ <pr>
114
+ Number: ${PR_NUMBER}
115
+ Title: ${PR_TITLE}
116
+ Author: ${PR_AUTHOR}
117
+ Base: ${BASE_BRANCH}
118
+ Description: ${PR_DESCRIPTION}
119
+
120
+ <diff>
121
+ ${DIFF_CONTENT}
122
+ </diff>
123
+
124
+ <files_changed>
125
+ ${DIFF_STAT}
126
+ </files_changed>
127
+ </pr>
128
+
129
+ <codebase_context>
130
+ @.relay/codebase/ARCHITECTURE.md (if exists)
131
+ @.relay/codebase/CONVENTIONS.md (if exists)
132
+ @.relay/codebase/TESTING.md (if exists)
133
+ </codebase_context>
134
+
135
+ <output>
136
+ Write review to: .relay/reviews/PR-${PR_NUMBER}-review.md
137
+ </output>
138
+ ",
139
+ subagent_type="relay-reviewer",
140
+ model="{reviewer_model}",
141
+ description="Review PR #${PR_NUMBER}"
142
+ )
143
+ ```
144
+
145
+ ### A5. Display Review and Offer Actions
146
+
147
+ Read `.relay/reviews/PR-${PR_NUMBER}-review.md` and display summary.
148
+
149
+ ```
150
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
151
+ Relay ► REVIEW COMPLETE — PR #${PR_NUMBER}
152
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
153
+
154
+ Recommendation: ${APPROVE | COMMENT | REQUEST_CHANGES}
155
+ Critical: ${COUNT}
156
+ Suggestions: ${COUNT}
157
+
158
+ Full review: .relay/reviews/PR-${PR_NUMBER}-review.md
159
+ ```
160
+
161
+ ```
162
+ AskUserQuestion(
163
+ header: "Action",
164
+ question: "What would you like to do with this review?",
165
+ options: [
166
+ { label: "Post as PR comment", description: "Submit review via gh pr review" },
167
+ { label: "View full review", description: "Display the complete review document" },
168
+ { label: "Done", description: "Return to original branch" }
169
+ ]
170
+ )
171
+ ```
172
+
173
+ **If "Post as PR comment":**
174
+ ```bash
175
+ gh pr review ${PR_NUMBER} --body "$(cat .relay/reviews/PR-${PR_NUMBER}-review.md)" --comment
176
+ ```
177
+
178
+ ### A6. Restore Original Branch
179
+
180
+ ```bash
181
+ git checkout "${ORIGINAL_BRANCH}"
182
+ ```
183
+
184
+ Always restore the original branch, regardless of action taken.
185
+
186
+ ---
187
+
188
+ ## Mode B — Address PR Comments
189
+
190
+ ### B1. List Your Open PRs
191
+
192
+ ```bash
193
+ gh pr list --state open --author @me --limit 20
194
+ ```
195
+
196
+ If no open PRs: report and STOP.
197
+
198
+ ```
199
+ AskUserQuestion(
200
+ header: "PR",
201
+ question: "Which PR has comments to address?",
202
+ options: [
203
+ { label: "#${PR_1_NUM}", description: "${PR_1_TITLE}" },
204
+ { label: "#${PR_2_NUM}", description: "${PR_2_TITLE}" },
205
+ { label: "#${PR_3_NUM}", description: "${PR_3_TITLE}" }
206
+ ]
207
+ )
208
+ ```
209
+
210
+ ### B2. Fetch Review Comments
211
+
212
+ ```bash
213
+ REPO=$(gh repo view --json nameWithOwner --jq '.nameWithOwner')
214
+ gh api repos/${REPO}/pulls/${PR_NUMBER}/comments --jq '.[] | {path: .path, line: .line, body: .body, user: .user.login}'
215
+ gh api repos/${REPO}/pulls/${PR_NUMBER}/reviews --jq '.[] | select(.state != "APPROVED") | {body: .body, user: .user.login, state: .state}'
216
+ ```
217
+
218
+ ### B3. Display Comments Grouped by File
219
+
220
+ Group comments by file path and display:
221
+
222
+ ```
223
+ ## Review Comments for PR #${PR_NUMBER}
224
+
225
+ ### ${FILE_1}
226
+ - Line ${LINE}: ${COMMENT_BODY} (by ${USER})
227
+
228
+ ### ${FILE_2}
229
+ - Line ${LINE}: ${COMMENT_BODY} (by ${USER})
230
+ ```
231
+
232
+ ### B4. Choose What to Address
233
+
234
+ ```
235
+ AskUserQuestion(
236
+ header: "Comments",
237
+ question: "Which comments would you like to address?",
238
+ options: [
239
+ { label: "All comments", description: "Address every review comment" },
240
+ { label: "Select specific", description: "Choose which comments to fix" },
241
+ { label: "View only", description: "Just review the comments, don't change code" }
242
+ ]
243
+ )
244
+ ```
245
+
246
+ If "View only": display and STOP.
247
+
248
+ If "Select specific": let user pick which comments to address.
249
+
250
+ ### B5. Checkout PR Branch and Fix
251
+
252
+ ```bash
253
+ gh pr checkout ${PR_NUMBER}
254
+ ```
255
+
256
+ For each comment to address:
257
+ 1. Read the file at the mentioned line
258
+ 2. Understand the feedback
259
+ 3. Make the code change using Edit
260
+ 4. Verify the fix
261
+
262
+ ### B6. Commit Fixes
263
+
264
+ For each file changed, commit with descriptive message:
265
+
266
+ ```bash
267
+ # Detect ticket ID from branch name or PR title
268
+ TICKET_ID=$(git branch --show-current | grep -oE '[A-Z]+-[0-9]+' | head -1)
269
+ TICKET_ID=${TICKET_ID:-review}
270
+
271
+ git add ${CHANGED_FILE}
272
+ git commit -m "fix(${TICKET_ID}): address review — ${DESCRIPTION}"
273
+ ```
274
+
275
+ ### B7. Offer to Push
276
+
277
+ ```
278
+ AskUserQuestion(
279
+ header: "Push",
280
+ question: "Push fixes to update the PR?",
281
+ options: [
282
+ { label: "Push", description: "Push commits to update PR #${PR_NUMBER}" },
283
+ { label: "Skip", description: "Keep changes local for now" }
284
+ ]
285
+ )
286
+ ```
287
+
288
+ If "Push":
289
+ ```bash
290
+ git push
291
+ ```
292
+
293
+ ```
294
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
295
+ Relay ► COMMENTS ADDRESSED — PR #${PR_NUMBER}
296
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
297
+
298
+ Comments addressed: ${COUNT}
299
+ Commits: ${COMMIT_COUNT}
300
+ Pushed: ${YES/NO}
301
+ ```
302
+
303
+ </process>
304
+
305
+ <success_criteria>
306
+ **Mode A:**
307
+ - [ ] PR selected from open PRs
308
+ - [ ] Original branch saved
309
+ - [ ] PR branch checked out
310
+ - [ ] Diff captured
311
+ - [ ] Reviewer agent produced structured review
312
+ - [ ] Review displayed with recommendation
313
+ - [ ] Action taken (post, view, or skip)
314
+ - [ ] Original branch restored
315
+
316
+ **Mode B:**
317
+ - [ ] User's PR selected
318
+ - [ ] Review comments fetched and displayed
319
+ - [ ] Selected comments addressed with code changes
320
+ - [ ] Each fix committed with descriptive message
321
+ - [ ] Pushed if requested
322
+ </success_criteria>
@@ -0,0 +1,248 @@
1
+ ---
2
+ name: relay:rollback
3
+ description: Safely revert work done on a specific ticket
4
+ argument-hint: <ticket-id>
5
+ allowed-tools:
6
+ - Read
7
+ - Write
8
+ - Bash
9
+ - Glob
10
+ - Grep
11
+ - AskUserQuestion
12
+ ---
13
+
14
+ <objective>
15
+ Safely revert ticket work using `git revert` (creates new commits — no history rewriting).
16
+
17
+ Destructive action — requires explicit user confirmation before executing.
18
+ </objective>
19
+
20
+ <context>
21
+ @.relay/STATE.md
22
+ Ticket ID: $ARGUMENTS
23
+ </context>
24
+
25
+ <process>
26
+
27
+ ## 0. Pre-flight
28
+
29
+ ```bash
30
+ test -f .relay/config.json && echo "config exists" || echo "no config"
31
+ ```
32
+
33
+ If no config: suggest `/relay:setup` and STOP.
34
+
35
+ If no $ARGUMENTS:
36
+ ```
37
+ AskUserQuestion(
38
+ header: "Ticket",
39
+ question: "Which ticket's work would you like to rollback?",
40
+ options: [
41
+ { label: "Enter ID", description: "Type a ticket ID (e.g., PROJ-123)" },
42
+ { label: "Cancel", description: "Don't rollback anything" }
43
+ ]
44
+ )
45
+ ```
46
+
47
+ ## 1. Find Ticket Commits
48
+
49
+ ```bash
50
+ git log --oneline --all --grep="${TICKET_ID}"
51
+ ```
52
+
53
+ If no commits found:
54
+ ```
55
+ No commits found for ${TICKET_ID}.
56
+ ```
57
+ STOP.
58
+
59
+ ## 2. Display Commits and Files
60
+
61
+ ```
62
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
63
+ Relay ► ROLLBACK — ${TICKET_ID}
64
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
65
+ ```
66
+
67
+ Show commits:
68
+ ```bash
69
+ git log --oneline --all --grep="${TICKET_ID}" --format="%h %s (%ai)"
70
+ ```
71
+
72
+ Show files affected:
73
+ ```bash
74
+ git log --all --grep="${TICKET_ID}" --name-only --format="" | sort -u
75
+ ```
76
+
77
+ Count total:
78
+ ```bash
79
+ COMMIT_COUNT=$(git log --oneline --all --grep="${TICKET_ID}" | wc -l | tr -d ' ')
80
+ FILE_COUNT=$(git log --all --grep="${TICKET_ID}" --name-only --format="" | sort -u | wc -l | tr -d ' ')
81
+ ```
82
+
83
+ ```
84
+ Found ${COMMIT_COUNT} commits affecting ${FILE_COUNT} files.
85
+ ```
86
+
87
+ ## 3. Check for Interleaved Commits
88
+
89
+ Check if other work is interleaved with ticket commits:
90
+
91
+ ```bash
92
+ # Get the range of ticket commits
93
+ FIRST_COMMIT=$(git log --oneline --all --grep="${TICKET_ID}" --format="%H" | tail -1)
94
+ LAST_COMMIT=$(git log --oneline --all --grep="${TICKET_ID}" --format="%H" | head -1)
95
+
96
+ # Check for non-ticket commits in that range
97
+ git log --oneline ${FIRST_COMMIT}..${LAST_COMMIT} | grep -v "${TICKET_ID}"
98
+ ```
99
+
100
+ If interleaved commits exist, warn:
101
+ ```
102
+ WARNING: Other commits exist between ${TICKET_ID} commits.
103
+ Reverting may cause conflicts. Consider selective revert.
104
+ ```
105
+
106
+ ## 4. Choose Rollback Mode
107
+
108
+ ```
109
+ AskUserQuestion(
110
+ header: "Mode",
111
+ question: "How would you like to rollback ${TICKET_ID}? (${COMMIT_COUNT} commits, ${FILE_COUNT} files)",
112
+ options: [
113
+ { label: "Full revert", description: "Revert all ${COMMIT_COUNT} commits for ${TICKET_ID}" },
114
+ { label: "Selective revert", description: "Choose which commits to revert" },
115
+ { label: "Soft rollback", description: "Just switch to main branch (no revert commits)" },
116
+ { label: "Cancel", description: "Don't rollback" }
117
+ ]
118
+ )
119
+ ```
120
+
121
+ If "Cancel": STOP.
122
+
123
+ ### Soft Rollback
124
+
125
+ ```bash
126
+ BASE_BRANCH=$(git remote show origin 2>/dev/null | grep 'HEAD branch' | sed 's/.*: //')
127
+ BASE_BRANCH=${BASE_BRANCH:-main}
128
+ git checkout "${BASE_BRANCH}"
129
+ ```
130
+
131
+ Skip to step 6.
132
+
133
+ ### Selective Revert
134
+
135
+ Display commits numbered for selection:
136
+ ```bash
137
+ git log --oneline --all --grep="${TICKET_ID}" --format="%h %s"
138
+ ```
139
+
140
+ Ask user which commits to revert (by hash or number).
141
+
142
+ ### Full Revert / Selective Revert
143
+
144
+ Continue to step 5.
145
+
146
+ ## 5. Confirm and Execute
147
+
148
+ **Explicit confirmation required:**
149
+
150
+ ```
151
+ AskUserQuestion(
152
+ header: "Confirm",
153
+ question: "This will create revert commits for ${REVERT_COUNT} commits. This cannot be easily undone. Proceed?",
154
+ options: [
155
+ { label: "Revert", description: "Execute git revert for selected commits" },
156
+ { label: "Cancel", description: "Abort rollback" }
157
+ ]
158
+ )
159
+ ```
160
+
161
+ If "Cancel": STOP.
162
+
163
+ **Execute reverts (newest first):**
164
+
165
+ ```bash
166
+ # Get commits in reverse chronological order (newest first)
167
+ COMMITS=$(git log --oneline --all --grep="${TICKET_ID}" --format="%H")
168
+
169
+ for COMMIT in ${COMMITS}; do
170
+ git revert --no-edit ${COMMIT} || {
171
+ echo "Conflict during revert of ${COMMIT}"
172
+ echo "Resolve conflicts and run: git revert --continue"
173
+ break
174
+ }
175
+ done
176
+ ```
177
+
178
+ If conflicts occur, display:
179
+ ```
180
+ Conflict encountered while reverting ${COMMIT_HASH}.
181
+
182
+ Conflicting files:
183
+ $(git diff --name-only --diff-filter=U)
184
+
185
+ Options:
186
+ 1. Resolve conflicts manually, then run: git revert --continue
187
+ 2. Abort the rollback: git revert --abort
188
+ ```
189
+
190
+ ## 6. Handle Artifacts
191
+
192
+ ```
193
+ AskUserQuestion(
194
+ header: "Artifacts",
195
+ question: "What should happen to the ticket artifacts in .relay/tickets/${TICKET_ID}/?",
196
+ options: [
197
+ { label: "Archive", description: "Move to .relay/tickets/${TICKET_ID}/.archived/" },
198
+ { label: "Delete", description: "Remove all ticket artifacts" },
199
+ { label: "Keep", description: "Leave artifacts as-is" }
200
+ ]
201
+ )
202
+ ```
203
+
204
+ **Archive:**
205
+ ```bash
206
+ mkdir -p .relay/tickets/${TICKET_ID}/.archived
207
+ mv .relay/tickets/${TICKET_ID}/*.md .relay/tickets/${TICKET_ID}/.archived/ 2>/dev/null
208
+ ```
209
+
210
+ **Delete:**
211
+ ```bash
212
+ rm -rf .relay/tickets/${TICKET_ID}
213
+ ```
214
+
215
+ **Keep:** No action.
216
+
217
+ ## 7. Update State
218
+
219
+ Update STATE.md:
220
+ - Clear active ticket if it was the rolled-back ticket
221
+ - Add note to recent tickets: "reverted"
222
+
223
+ ```
224
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
225
+ Relay ► ROLLBACK COMPLETE — ${TICKET_ID}
226
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
227
+
228
+ Reverted: ${REVERT_COUNT} commits
229
+ Artifacts: ${archived/deleted/kept}
230
+
231
+ ## Next Steps
232
+
233
+ - `/relay:tickets` — browse available tickets
234
+ - `/relay:status` — check current state
235
+ ```
236
+
237
+ </process>
238
+
239
+ <success_criteria>
240
+ - [ ] Ticket commits found and displayed
241
+ - [ ] Interleaved commits warned about
242
+ - [ ] User chose rollback mode
243
+ - [ ] Explicit confirmation obtained before revert
244
+ - [ ] `git revert --no-edit` executed for selected commits (newest first)
245
+ - [ ] Conflicts handled gracefully if they occur
246
+ - [ ] Artifacts archived, deleted, or kept per user choice
247
+ - [ ] STATE.md updated (active ticket cleared, marked as reverted)
248
+ </success_criteria>
@@ -0,0 +1,116 @@
1
+ ---
2
+ name: set-profile
3
+ description: Switch model profile for Relay agents (quality/balanced/budget)
4
+ arguments:
5
+ - name: profile
6
+ description: "Profile name: quality, balanced, or budget"
7
+ required: true
8
+ ---
9
+
10
+ <objective>
11
+ Switch the model profile used by Relay agents. This controls which Claude model each agent uses, balancing quality vs token spend.
12
+ </objective>
13
+
14
+ <profiles>
15
+ | Profile | Description |
16
+ |---------|-------------|
17
+ | **quality** | Opus everywhere except read-only verification |
18
+ | **balanced** | Opus for planning, Sonnet for execution/verification (default) |
19
+ | **budget** | Sonnet for writing, Haiku for research/verification |
20
+ </profiles>
21
+
22
+ <process>
23
+
24
+ ## 1. Validate argument
25
+
26
+ ```
27
+ if $ARGUMENTS.profile not in ["quality", "balanced", "budget"]:
28
+ Error: Invalid profile "$ARGUMENTS.profile"
29
+ Valid profiles: quality, balanced, budget
30
+ STOP
31
+ ```
32
+
33
+ ## 2. Ensure config exists
34
+
35
+ ```bash
36
+ ls .relay/config.json 2>/dev/null
37
+ ```
38
+
39
+ If `.relay/config.json` missing, create it with defaults:
40
+ ```bash
41
+ mkdir -p .relay
42
+ ```
43
+ ```json
44
+ {
45
+ "model_profile": "balanced",
46
+ "workflow": {
47
+ "research": true,
48
+ "plan_check": true,
49
+ "verifier": true
50
+ }
51
+ }
52
+ ```
53
+ Write this to `.relay/config.json`, then continue.
54
+
55
+ ## 3. Update config.json
56
+
57
+ Read current config:
58
+ ```bash
59
+ cat .relay/config.json
60
+ ```
61
+
62
+ Update `model_profile` field:
63
+ ```json
64
+ {
65
+ "model_profile": "$ARGUMENTS.profile"
66
+ }
67
+ ```
68
+
69
+ Write updated config back to `.relay/config.json`.
70
+
71
+ ## 4. Confirm
72
+
73
+ ```
74
+ ✓ Model profile set to: $ARGUMENTS.profile
75
+
76
+ Agents will now use:
77
+ [Show table from model-profiles.md for selected profile]
78
+
79
+ Next spawned agents will use the new profile.
80
+ ```
81
+
82
+ </process>
83
+
84
+ <examples>
85
+
86
+ **Switch to budget mode:**
87
+ ```
88
+ /relay:set-profile budget
89
+
90
+ ✓ Model profile set to: budget
91
+
92
+ Agents will now use:
93
+ | Agent | Model |
94
+ |-------|-------|
95
+ | relay-planner | sonnet |
96
+ | relay-executor | sonnet |
97
+ | relay-verifier | haiku |
98
+ | ... | ... |
99
+ ```
100
+
101
+ **Switch to quality mode:**
102
+ ```
103
+ /relay:set-profile quality
104
+
105
+ ✓ Model profile set to: quality
106
+
107
+ Agents will now use:
108
+ | Agent | Model |
109
+ |-------|-------|
110
+ | relay-planner | opus |
111
+ | relay-executor | opus |
112
+ | relay-verifier | sonnet |
113
+ | ... | ... |
114
+ ```
115
+
116
+ </examples>