@bradygaster/squad-sdk 0.8.25 → 0.9.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 (202) hide show
  1. package/dist/adapter/client.d.ts +17 -0
  2. package/dist/adapter/client.d.ts.map +1 -1
  3. package/dist/adapter/client.js +101 -1
  4. package/dist/adapter/client.js.map +1 -1
  5. package/dist/agents/history-shadow.d.ts.map +1 -1
  6. package/dist/agents/history-shadow.js +99 -32
  7. package/dist/agents/history-shadow.js.map +1 -1
  8. package/dist/agents/index.d.ts +1 -0
  9. package/dist/agents/index.d.ts.map +1 -1
  10. package/dist/agents/index.js +2 -0
  11. package/dist/agents/index.js.map +1 -1
  12. package/dist/agents/model-selector.d.ts +2 -0
  13. package/dist/agents/model-selector.d.ts.map +1 -1
  14. package/dist/agents/model-selector.js +41 -35
  15. package/dist/agents/model-selector.js.map +1 -1
  16. package/dist/agents/personal.d.ts +35 -0
  17. package/dist/agents/personal.d.ts.map +1 -0
  18. package/dist/agents/personal.js +67 -0
  19. package/dist/agents/personal.js.map +1 -0
  20. package/dist/builders/index.d.ts +3 -2
  21. package/dist/builders/index.d.ts.map +1 -1
  22. package/dist/builders/index.js +28 -0
  23. package/dist/builders/index.js.map +1 -1
  24. package/dist/builders/types.d.ts +13 -0
  25. package/dist/builders/types.d.ts.map +1 -1
  26. package/dist/config/init.d.ts +8 -0
  27. package/dist/config/init.d.ts.map +1 -1
  28. package/dist/config/init.js +131 -20
  29. package/dist/config/init.js.map +1 -1
  30. package/dist/config/models.d.ts +112 -0
  31. package/dist/config/models.d.ts.map +1 -1
  32. package/dist/config/models.js +329 -18
  33. package/dist/config/models.js.map +1 -1
  34. package/dist/coordinator/index.js +2 -2
  35. package/dist/coordinator/index.js.map +1 -1
  36. package/dist/index.d.ts +8 -3
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +7 -2
  39. package/dist/index.js.map +1 -1
  40. package/dist/platform/azure-devops.d.ts +42 -0
  41. package/dist/platform/azure-devops.d.ts.map +1 -1
  42. package/dist/platform/azure-devops.js +75 -0
  43. package/dist/platform/azure-devops.js.map +1 -1
  44. package/dist/platform/comms-file-log.d.ts.map +1 -1
  45. package/dist/platform/comms-file-log.js +2 -1
  46. package/dist/platform/comms-file-log.js.map +1 -1
  47. package/dist/platform/index.d.ts +2 -1
  48. package/dist/platform/index.d.ts.map +1 -1
  49. package/dist/platform/index.js +1 -0
  50. package/dist/platform/index.js.map +1 -1
  51. package/dist/ralph/capabilities.d.ts +67 -0
  52. package/dist/ralph/capabilities.d.ts.map +1 -0
  53. package/dist/ralph/capabilities.js +111 -0
  54. package/dist/ralph/capabilities.js.map +1 -0
  55. package/dist/ralph/index.d.ts +2 -0
  56. package/dist/ralph/index.d.ts.map +1 -1
  57. package/dist/ralph/index.js +6 -5
  58. package/dist/ralph/index.js.map +1 -1
  59. package/dist/ralph/rate-limiting.d.ts +99 -0
  60. package/dist/ralph/rate-limiting.d.ts.map +1 -0
  61. package/dist/ralph/rate-limiting.js +170 -0
  62. package/dist/ralph/rate-limiting.js.map +1 -0
  63. package/dist/resolution.d.ts +24 -2
  64. package/dist/resolution.d.ts.map +1 -1
  65. package/dist/resolution.js +106 -6
  66. package/dist/resolution.js.map +1 -1
  67. package/dist/roles/catalog-categories.d.ts +146 -0
  68. package/dist/roles/catalog-categories.d.ts.map +1 -0
  69. package/dist/roles/catalog-categories.js +374 -0
  70. package/dist/roles/catalog-categories.js.map +1 -0
  71. package/dist/roles/catalog-engineering.d.ts +212 -0
  72. package/dist/roles/catalog-engineering.d.ts.map +1 -0
  73. package/dist/roles/catalog-engineering.js +549 -0
  74. package/dist/roles/catalog-engineering.js.map +1 -0
  75. package/dist/roles/catalog.d.ts +24 -0
  76. package/dist/roles/catalog.d.ts.map +1 -0
  77. package/dist/roles/catalog.js +28 -0
  78. package/dist/roles/catalog.js.map +1 -0
  79. package/dist/roles/index.d.ts +69 -0
  80. package/dist/roles/index.d.ts.map +1 -0
  81. package/dist/roles/index.js +197 -0
  82. package/dist/roles/index.js.map +1 -0
  83. package/dist/roles/types.d.ts +87 -0
  84. package/dist/roles/types.d.ts.map +1 -0
  85. package/dist/roles/types.js +14 -0
  86. package/dist/roles/types.js.map +1 -0
  87. package/dist/runtime/benchmarks.js +5 -5
  88. package/dist/runtime/benchmarks.js.map +1 -1
  89. package/dist/runtime/constants.d.ts +2 -2
  90. package/dist/runtime/constants.d.ts.map +1 -1
  91. package/dist/runtime/constants.js +5 -3
  92. package/dist/runtime/constants.js.map +1 -1
  93. package/dist/runtime/cross-squad.d.ts +118 -0
  94. package/dist/runtime/cross-squad.d.ts.map +1 -0
  95. package/dist/runtime/cross-squad.js +234 -0
  96. package/dist/runtime/cross-squad.js.map +1 -0
  97. package/dist/runtime/otel-init.d.ts +24 -17
  98. package/dist/runtime/otel-init.d.ts.map +1 -1
  99. package/dist/runtime/otel-init.js +29 -20
  100. package/dist/runtime/otel-init.js.map +1 -1
  101. package/dist/runtime/otel-metrics.d.ts +5 -0
  102. package/dist/runtime/otel-metrics.d.ts.map +1 -1
  103. package/dist/runtime/otel-metrics.js +54 -0
  104. package/dist/runtime/otel-metrics.js.map +1 -1
  105. package/dist/runtime/rework.d.ts +71 -0
  106. package/dist/runtime/rework.d.ts.map +1 -0
  107. package/dist/runtime/rework.js +107 -0
  108. package/dist/runtime/rework.js.map +1 -0
  109. package/dist/runtime/scheduler.d.ts +128 -0
  110. package/dist/runtime/scheduler.d.ts.map +1 -0
  111. package/dist/runtime/scheduler.js +427 -0
  112. package/dist/runtime/scheduler.js.map +1 -0
  113. package/dist/runtime/squad-observer.d.ts.map +1 -1
  114. package/dist/runtime/squad-observer.js +4 -0
  115. package/dist/runtime/squad-observer.js.map +1 -1
  116. package/dist/runtime/streaming.d.ts +2 -0
  117. package/dist/runtime/streaming.d.ts.map +1 -1
  118. package/dist/runtime/streaming.js +6 -0
  119. package/dist/runtime/streaming.js.map +1 -1
  120. package/dist/runtime/telemetry.d.ts +2 -0
  121. package/dist/runtime/telemetry.d.ts.map +1 -1
  122. package/dist/runtime/telemetry.js +6 -0
  123. package/dist/runtime/telemetry.js.map +1 -1
  124. package/dist/sharing/consult.d.ts +2 -2
  125. package/dist/sharing/consult.js +6 -6
  126. package/dist/sharing/consult.js.map +1 -1
  127. package/dist/sharing/export.d.ts.map +1 -1
  128. package/dist/sharing/export.js +17 -4
  129. package/dist/sharing/export.js.map +1 -1
  130. package/dist/skills/handler-types.d.ts +271 -0
  131. package/dist/skills/handler-types.d.ts.map +1 -0
  132. package/dist/skills/handler-types.js +31 -0
  133. package/dist/skills/handler-types.js.map +1 -0
  134. package/dist/skills/index.d.ts +3 -0
  135. package/dist/skills/index.d.ts.map +1 -1
  136. package/dist/skills/index.js +3 -0
  137. package/dist/skills/index.js.map +1 -1
  138. package/dist/skills/skill-script-loader.d.ts +65 -0
  139. package/dist/skills/skill-script-loader.d.ts.map +1 -0
  140. package/dist/skills/skill-script-loader.js +227 -0
  141. package/dist/skills/skill-script-loader.js.map +1 -0
  142. package/dist/skills/skill-source.d.ts.map +1 -1
  143. package/dist/skills/skill-source.js +5 -1
  144. package/dist/skills/skill-source.js.map +1 -1
  145. package/dist/tools/index.d.ts +10 -1
  146. package/dist/tools/index.d.ts.map +1 -1
  147. package/dist/tools/index.js +49 -8
  148. package/dist/tools/index.js.map +1 -1
  149. package/dist/upstream/resolver.d.ts.map +1 -1
  150. package/dist/upstream/resolver.js +14 -5
  151. package/dist/upstream/resolver.js.map +1 -1
  152. package/package.json +34 -3
  153. package/templates/casting/Futurama.json +10 -0
  154. package/templates/casting-policy.json +4 -2
  155. package/templates/casting-reference.md +104 -0
  156. package/templates/cooperative-rate-limiting.md +229 -0
  157. package/templates/issue-lifecycle.md +412 -0
  158. package/templates/keda-scaler.md +164 -0
  159. package/templates/machine-capabilities.md +75 -0
  160. package/templates/mcp-config.md +0 -8
  161. package/templates/orchestration-log.md +27 -27
  162. package/templates/package.json +3 -0
  163. package/templates/ralph-circuit-breaker.md +313 -0
  164. package/templates/ralph-triage.js +543 -0
  165. package/templates/routing.md +5 -20
  166. package/templates/schedule.json +19 -0
  167. package/templates/scribe-charter.md +1 -1
  168. package/templates/skills/agent-collaboration/SKILL.md +42 -0
  169. package/templates/skills/agent-conduct/SKILL.md +24 -0
  170. package/templates/skills/architectural-proposals/SKILL.md +151 -0
  171. package/templates/skills/ci-validation-gates/SKILL.md +84 -0
  172. package/templates/skills/cli-wiring/SKILL.md +47 -0
  173. package/templates/skills/client-compatibility/SKILL.md +89 -0
  174. package/templates/skills/cross-squad/SKILL.md +114 -0
  175. package/templates/skills/distributed-mesh/SKILL.md +287 -0
  176. package/templates/skills/distributed-mesh/mesh.json.example +30 -0
  177. package/templates/skills/distributed-mesh/sync-mesh.ps1 +111 -0
  178. package/templates/skills/distributed-mesh/sync-mesh.sh +104 -0
  179. package/templates/skills/docs-standards/SKILL.md +71 -0
  180. package/templates/skills/economy-mode/SKILL.md +114 -0
  181. package/templates/skills/external-comms/SKILL.md +329 -0
  182. package/templates/skills/gh-auth-isolation/SKILL.md +183 -0
  183. package/templates/skills/git-workflow/SKILL.md +204 -0
  184. package/templates/skills/github-multi-account/SKILL.md +95 -0
  185. package/templates/skills/history-hygiene/SKILL.md +36 -0
  186. package/templates/skills/humanizer/SKILL.md +105 -0
  187. package/templates/skills/init-mode/SKILL.md +102 -0
  188. package/templates/skills/model-selection/SKILL.md +117 -0
  189. package/templates/skills/nap/SKILL.md +24 -0
  190. package/templates/skills/personal-squad/SKILL.md +57 -0
  191. package/templates/skills/release-process/SKILL.md +423 -0
  192. package/templates/skills/reskill/SKILL.md +92 -0
  193. package/templates/skills/reviewer-protocol/SKILL.md +79 -0
  194. package/templates/skills/secret-handling/SKILL.md +200 -0
  195. package/templates/skills/session-recovery/SKILL.md +155 -0
  196. package/templates/skills/squad-conventions/SKILL.md +69 -0
  197. package/templates/skills/test-discipline/SKILL.md +37 -0
  198. package/templates/skills/windows-compatibility/SKILL.md +74 -0
  199. package/templates/squad.agent.md +1287 -1146
  200. package/templates/workflows/squad-docs.yml +8 -4
  201. package/templates/workflows/squad-heartbeat.yml +55 -200
  202. package/templates/workflows/squad-insider-release.yml +1 -1
@@ -26,17 +26,21 @@ jobs:
26
26
  - uses: actions/setup-node@v4
27
27
  with:
28
28
  node-version: '22'
29
+ cache: npm
30
+ cache-dependency-path: docs/package-lock.json
29
31
 
30
- - name: Install build dependencies
31
- run: npm install --no-save markdown-it markdown-it-anchor
32
+ - name: Install docs dependencies
33
+ working-directory: docs
34
+ run: npm ci
32
35
 
33
36
  - name: Build docs site
34
- run: node docs/build.js --out _site --base /squad
37
+ working-directory: docs
38
+ run: npm run build
35
39
 
36
40
  - name: Upload Pages artifact
37
41
  uses: actions/upload-pages-artifact@v3
38
42
  with:
39
- path: _site
43
+ path: docs/dist
40
44
 
41
45
  deploy:
42
46
  needs: build
@@ -1,10 +1,15 @@
1
1
  name: Squad Heartbeat (Ralph)
2
+ # ⚠️ SYNC: This workflow is maintained in 4 locations. Changes must be applied to all:
3
+ # - templates/workflows/squad-heartbeat.yml (source template)
4
+ # - packages/squad-cli/templates/workflows/squad-heartbeat.yml (CLI package)
5
+ # - .squad/templates/workflows/squad-heartbeat.yml (installed template)
6
+ # - .github/workflows/squad-heartbeat.yml (active workflow)
7
+ # Run 'squad upgrade' to sync installed copies from source templates.
2
8
 
3
9
  on:
4
- # DISABLED: Cron heartbeat commented out pre-migration — re-enable when ready
5
- # schedule:
6
- # # Every 30 minutes adjust or remove if not needed
7
- # - cron: '*/30 * * * *'
10
+ schedule:
11
+ # Every 30 minutes — adjust via cron expression as needed
12
+ - cron: '*/30 * * * *'
8
13
 
9
14
  # React to completed work or new squad work
10
15
  issues:
@@ -26,225 +31,75 @@ jobs:
26
31
  steps:
27
32
  - uses: actions/checkout@v4
28
33
 
29
- - name: Ralph — Check for squad work
34
+ - name: Check triage script
35
+ id: check-script
36
+ run: |
37
+ if [ -f ".squad/templates/ralph-triage.js" ]; then
38
+ echo "has_script=true" >> $GITHUB_OUTPUT
39
+ else
40
+ echo "has_script=false" >> $GITHUB_OUTPUT
41
+ echo "⚠️ ralph-triage.js not found — run 'squad upgrade' to install"
42
+ fi
43
+
44
+ - name: Ralph — Smart triage
45
+ if: steps.check-script.outputs.has_script == 'true'
46
+ env:
47
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
48
+ run: |
49
+ node .squad/templates/ralph-triage.js \
50
+ --squad-dir .squad \
51
+ --output triage-results.json
52
+
53
+ - name: Ralph — Apply triage decisions
54
+ if: steps.check-script.outputs.has_script == 'true' && hashFiles('triage-results.json') != ''
30
55
  uses: actions/github-script@v7
31
56
  with:
32
57
  script: |
33
58
  const fs = require('fs');
34
-
35
- // Read team roster — check .squad/ first, fall back to .ai-team/
36
- let teamFile = '.squad/team.md';
37
- if (!fs.existsSync(teamFile)) {
38
- teamFile = '.ai-team/team.md';
39
- }
40
- if (!fs.existsSync(teamFile)) {
41
- core.info('No .squad/team.md or .ai-team/team.md found — Ralph has nothing to monitor');
59
+ const path = 'triage-results.json';
60
+ if (!fs.existsSync(path)) {
61
+ core.info('No triage results — board is clear');
42
62
  return;
43
63
  }
44
-
45
- const content = fs.readFileSync(teamFile, 'utf8');
46
-
47
- // Check if Ralph is on the roster
48
- if (!content.includes('Ralph') || !content.includes('🔄')) {
49
- core.info('Ralph not on roster — heartbeat disabled');
64
+
65
+ const results = JSON.parse(fs.readFileSync(path, 'utf8'));
66
+ if (results.length === 0) {
67
+ core.info('📋 Board is clear — Ralph found no untriaged issues');
50
68
  return;
51
69
  }
52
-
53
- // Parse members from roster
54
- const lines = content.split('\n');
55
- const members = [];
56
- let inMembersTable = false;
57
- for (const line of lines) {
58
- if (line.match(/^##\s+(Members|Team Roster)/i)) {
59
- inMembersTable = true;
60
- continue;
61
- }
62
- if (inMembersTable && line.startsWith('## ')) break;
63
- if (inMembersTable && line.startsWith('|') && !line.includes('---') && !line.includes('Name')) {
64
- const cells = line.split('|').map(c => c.trim()).filter(Boolean);
65
- if (cells.length >= 2 && !['Scribe', 'Ralph'].includes(cells[0])) {
66
- members.push({
67
- name: cells[0],
68
- role: cells[1],
69
- label: `squad:${cells[0].toLowerCase()}`
70
- });
71
- }
72
- }
73
- }
74
-
75
- if (members.length === 0) {
76
- core.info('No squad members found — nothing to monitor');
77
- return;
78
- }
79
-
80
- // 1. Find untriaged issues (labeled "squad" but no "squad:{member}" label)
81
- const { data: squadIssues } = await github.rest.issues.listForRepo({
82
- owner: context.repo.owner,
83
- repo: context.repo.repo,
84
- labels: 'squad',
85
- state: 'open',
86
- per_page: 20
87
- });
88
-
89
- const memberLabels = members.map(m => m.label);
90
- const untriaged = squadIssues.filter(issue => {
91
- const issueLabels = issue.labels.map(l => l.name);
92
- return !memberLabels.some(ml => issueLabels.includes(ml));
93
- });
94
-
95
- // 2. Find assigned but unstarted issues (has squad:{member} label, no assignee)
96
- const unstarted = [];
97
- for (const member of members) {
70
+
71
+ for (const decision of results) {
98
72
  try {
99
- const { data: memberIssues } = await github.rest.issues.listForRepo({
100
- owner: context.repo.owner,
101
- repo: context.repo.repo,
102
- labels: member.label,
103
- state: 'open',
104
- per_page: 10
105
- });
106
- for (const issue of memberIssues) {
107
- if (!issue.assignees || issue.assignees.length === 0) {
108
- unstarted.push({ issue, member });
109
- }
110
- }
111
- } catch (e) {
112
- // Label may not exist yet
113
- }
114
- }
115
-
116
- // 3. Find squad issues missing triage verdict (no go:* label)
117
- const missingVerdict = squadIssues.filter(issue => {
118
- const labels = issue.labels.map(l => l.name);
119
- return !labels.some(l => l.startsWith('go:'));
120
- });
121
-
122
- // 4. Find go:yes issues missing release target
123
- const goYesIssues = squadIssues.filter(issue => {
124
- const labels = issue.labels.map(l => l.name);
125
- return labels.includes('go:yes') && !labels.some(l => l.startsWith('release:'));
126
- });
127
-
128
- // 4b. Find issues missing type: label
129
- const missingType = squadIssues.filter(issue => {
130
- const labels = issue.labels.map(l => l.name);
131
- return !labels.some(l => l.startsWith('type:'));
132
- });
133
-
134
- // 5. Find open PRs that need attention
135
- const { data: openPRs } = await github.rest.pulls.list({
136
- owner: context.repo.owner,
137
- repo: context.repo.repo,
138
- state: 'open',
139
- per_page: 20
140
- });
141
-
142
- const squadPRs = openPRs.filter(pr =>
143
- pr.labels.some(l => l.name.startsWith('squad'))
144
- );
145
-
146
- // Build status summary
147
- const summary = [];
148
- if (untriaged.length > 0) {
149
- summary.push(`🔴 **${untriaged.length} untriaged issue(s)** need triage`);
150
- }
151
- if (unstarted.length > 0) {
152
- summary.push(`🟡 **${unstarted.length} assigned issue(s)** have no assignee`);
153
- }
154
- if (missingVerdict.length > 0) {
155
- summary.push(`⚪ **${missingVerdict.length} issue(s)** missing triage verdict (no \`go:\` label)`);
156
- }
157
- if (goYesIssues.length > 0) {
158
- summary.push(`⚪ **${goYesIssues.length} approved issue(s)** missing release target (no \`release:\` label)`);
159
- }
160
- if (missingType.length > 0) {
161
- summary.push(`⚪ **${missingType.length} issue(s)** missing \`type:\` label`);
162
- }
163
- if (squadPRs.length > 0) {
164
- const drafts = squadPRs.filter(pr => pr.draft).length;
165
- const ready = squadPRs.length - drafts;
166
- if (drafts > 0) summary.push(`🟡 **${drafts} draft PR(s)** in progress`);
167
- if (ready > 0) summary.push(`🟢 **${ready} PR(s)** open for review/merge`);
168
- }
169
-
170
- if (summary.length === 0) {
171
- core.info('📋 Board is clear — Ralph found no pending work');
172
- return;
173
- }
174
-
175
- core.info(`🔄 Ralph found work:\n${summary.join('\n')}`);
176
-
177
- // Auto-triage untriaged issues
178
- for (const issue of untriaged) {
179
- const issueText = `${issue.title}\n${issue.body || ''}`.toLowerCase();
180
- let assignedMember = null;
181
- let reason = '';
182
-
183
- // Simple keyword-based routing
184
- for (const member of members) {
185
- const role = member.role.toLowerCase();
186
- if ((role.includes('frontend') || role.includes('ui')) &&
187
- (issueText.includes('ui') || issueText.includes('frontend') ||
188
- issueText.includes('css') || issueText.includes('component'))) {
189
- assignedMember = member;
190
- reason = 'Matches frontend/UI domain';
191
- break;
192
- }
193
- if ((role.includes('backend') || role.includes('api') || role.includes('server')) &&
194
- (issueText.includes('api') || issueText.includes('backend') ||
195
- issueText.includes('database') || issueText.includes('endpoint'))) {
196
- assignedMember = member;
197
- reason = 'Matches backend/API domain';
198
- break;
199
- }
200
- if ((role.includes('test') || role.includes('qa')) &&
201
- (issueText.includes('test') || issueText.includes('bug') ||
202
- issueText.includes('fix') || issueText.includes('regression'))) {
203
- assignedMember = member;
204
- reason = 'Matches testing/QA domain';
205
- break;
206
- }
207
- }
208
-
209
- // Default to Lead
210
- if (!assignedMember) {
211
- const lead = members.find(m =>
212
- m.role.toLowerCase().includes('lead') ||
213
- m.role.toLowerCase().includes('architect')
214
- );
215
- if (lead) {
216
- assignedMember = lead;
217
- reason = 'No domain match — routed to Lead';
218
- }
219
- }
220
-
221
- if (assignedMember) {
222
- // Add member label
223
73
  await github.rest.issues.addLabels({
224
74
  owner: context.repo.owner,
225
75
  repo: context.repo.repo,
226
- issue_number: issue.number,
227
- labels: [assignedMember.label]
76
+ issue_number: decision.issueNumber,
77
+ labels: [decision.label]
228
78
  });
229
-
230
- // Post triage comment
79
+
231
80
  await github.rest.issues.createComment({
232
81
  owner: context.repo.owner,
233
82
  repo: context.repo.repo,
234
- issue_number: issue.number,
83
+ issue_number: decision.issueNumber,
235
84
  body: [
236
- `### 🔄 Ralph — Auto-Triage`,
85
+ '### 🔄 Ralph — Auto-Triage',
237
86
  '',
238
- `**Assigned to:** ${assignedMember.name} (${assignedMember.role})`,
239
- `**Reason:** ${reason}`,
87
+ `**Assigned to:** ${decision.assignTo}`,
88
+ `**Reason:** ${decision.reason}`,
89
+ `**Source:** ${decision.source}`,
240
90
  '',
241
- `> Ralph auto-triaged this issue via the squad heartbeat. To reassign, swap the \`squad:*\` label.`
91
+ '> Ralph auto-triaged this issue using routing rules.',
92
+ '> To reassign, swap the `squad:*` label.'
242
93
  ].join('\n')
243
94
  });
244
-
245
- core.info(`Auto-triaged #${issue.number} → ${assignedMember.name}`);
95
+
96
+ core.info(`Triaged #${decision.issueNumber} → ${decision.assignTo} (${decision.source})`);
97
+ } catch (e) {
98
+ core.warning(`Failed to triage #${decision.issueNumber}: ${e.message}`);
246
99
  }
247
100
  }
101
+
102
+ core.info(`🔄 Ralph triaged ${results.length} issue(s)`);
248
103
 
249
104
  # Copilot auto-assign step (uses PAT if available)
250
105
  - name: Ralph — Assign @copilot issues
@@ -50,7 +50,7 @@ jobs:
50
50
  run: |
51
51
  gh release create "${{ steps.version.outputs.insider_tag }}" \
52
52
  --title "${{ steps.version.outputs.insider_tag }}" \
53
- --notes "This is an insider/development build of Squad. Install with:\`\`\`bash\nnpx github:bradygaster/squad#${{ steps.version.outputs.insider_tag }}\n\`\`\`\n\n**Note:** Insider builds may be unstable and are intended for early adopters and testing only." \
53
+ --notes "This is an insider/development build of Squad. Install with:\`\`\`bash\nnpm install -g @bradygaster/squad-cli@${{ steps.version.outputs.insider_tag }}\n\`\`\`\n\n**Note:** Insider builds may be unstable and are intended for early adopters and testing only." \
54
54
  --prerelease
55
55
 
56
56
  - name: Verify release