@bradygaster/squad-sdk 0.9.1 → 0.9.2-insider.1

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 (285) hide show
  1. package/README.md +340 -296
  2. package/dist/agents/history-shadow.d.ts +7 -5
  3. package/dist/agents/history-shadow.d.ts.map +1 -1
  4. package/dist/agents/history-shadow.js +69 -78
  5. package/dist/agents/history-shadow.js.map +1 -1
  6. package/dist/agents/index.d.ts +12 -1
  7. package/dist/agents/index.d.ts.map +1 -1
  8. package/dist/agents/index.js +62 -9
  9. package/dist/agents/index.js.map +1 -1
  10. package/dist/agents/lifecycle.d.ts +4 -0
  11. package/dist/agents/lifecycle.d.ts.map +1 -1
  12. package/dist/agents/lifecycle.js +6 -7
  13. package/dist/agents/lifecycle.js.map +1 -1
  14. package/dist/agents/onboarding.d.ts +4 -2
  15. package/dist/agents/onboarding.d.ts.map +1 -1
  16. package/dist/agents/onboarding.js +26 -16
  17. package/dist/agents/onboarding.js.map +1 -1
  18. package/dist/agents/personal.d.ts +2 -1
  19. package/dist/agents/personal.d.ts.map +1 -1
  20. package/dist/agents/personal.js +11 -12
  21. package/dist/agents/personal.js.map +1 -1
  22. package/dist/build/bundle.d.ts.map +1 -1
  23. package/dist/build/bundle.js +6 -6
  24. package/dist/build/bundle.js.map +1 -1
  25. package/dist/build/github-dist.js +42 -42
  26. package/dist/build/release.d.ts.map +1 -1
  27. package/dist/build/release.js +7 -5
  28. package/dist/build/release.js.map +1 -1
  29. package/dist/casting/index.d.ts.map +1 -1
  30. package/dist/casting/index.js +4 -3
  31. package/dist/casting/index.js.map +1 -1
  32. package/dist/config/agent-source.d.ts +5 -1
  33. package/dist/config/agent-source.d.ts.map +1 -1
  34. package/dist/config/agent-source.js +85 -41
  35. package/dist/config/agent-source.js.map +1 -1
  36. package/dist/config/init.d.ts +4 -3
  37. package/dist/config/init.d.ts.map +1 -1
  38. package/dist/config/init.js +257 -236
  39. package/dist/config/init.js.map +1 -1
  40. package/dist/config/legacy-fallback.d.ts +3 -2
  41. package/dist/config/legacy-fallback.d.ts.map +1 -1
  42. package/dist/config/legacy-fallback.js +16 -14
  43. package/dist/config/legacy-fallback.js.map +1 -1
  44. package/dist/config/models.d.ts +9 -6
  45. package/dist/config/models.d.ts.map +1 -1
  46. package/dist/config/models.js +35 -25
  47. package/dist/config/models.js.map +1 -1
  48. package/dist/index.d.ts +5 -1
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +14 -1
  51. package/dist/index.js.map +1 -1
  52. package/dist/marketplace/packaging.d.ts.map +1 -1
  53. package/dist/marketplace/packaging.js +18 -16
  54. package/dist/marketplace/packaging.js.map +1 -1
  55. package/dist/multi-squad.d.ts.map +1 -1
  56. package/dist/multi-squad.js +10 -9
  57. package/dist/multi-squad.js.map +1 -1
  58. package/dist/platform/comms-file-log.d.ts.map +1 -1
  59. package/dist/platform/comms-file-log.js +7 -6
  60. package/dist/platform/comms-file-log.js.map +1 -1
  61. package/dist/platform/comms.d.ts.map +1 -1
  62. package/dist/platform/comms.js +6 -5
  63. package/dist/platform/comms.js.map +1 -1
  64. package/dist/platform/index.d.ts.map +1 -1
  65. package/dist/platform/index.js +4 -3
  66. package/dist/platform/index.js.map +1 -1
  67. package/dist/ralph/capabilities.d.ts +30 -1
  68. package/dist/ralph/capabilities.d.ts.map +1 -1
  69. package/dist/ralph/capabilities.js +51 -6
  70. package/dist/ralph/capabilities.js.map +1 -1
  71. package/dist/ralph/index.d.ts +1 -1
  72. package/dist/ralph/index.d.ts.map +1 -1
  73. package/dist/ralph/index.js +4 -3
  74. package/dist/ralph/index.js.map +1 -1
  75. package/dist/ralph/rate-limiting.d.ts.map +1 -1
  76. package/dist/ralph/rate-limiting.js +4 -4
  77. package/dist/ralph/rate-limiting.js.map +1 -1
  78. package/dist/remote/bridge.d.ts.map +1 -1
  79. package/dist/remote/bridge.js +2 -2
  80. package/dist/remote/bridge.js.map +1 -1
  81. package/dist/resolution.d.ts +9 -0
  82. package/dist/resolution.d.ts.map +1 -1
  83. package/dist/resolution.js +39 -16
  84. package/dist/resolution.js.map +1 -1
  85. package/dist/roles/catalog.d.ts +1 -1
  86. package/dist/runtime/config.d.ts.map +1 -1
  87. package/dist/runtime/config.js +8 -7
  88. package/dist/runtime/config.js.map +1 -1
  89. package/dist/runtime/cross-squad.d.ts.map +1 -1
  90. package/dist/runtime/cross-squad.js +8 -7
  91. package/dist/runtime/cross-squad.js.map +1 -1
  92. package/dist/runtime/scheduler.d.ts.map +1 -1
  93. package/dist/runtime/scheduler.js +8 -8
  94. package/dist/runtime/scheduler.js.map +1 -1
  95. package/dist/runtime/squad-observer.d.ts.map +1 -1
  96. package/dist/runtime/squad-observer.js +7 -4
  97. package/dist/runtime/squad-observer.js.map +1 -1
  98. package/dist/sharing/consult.d.ts +1 -1
  99. package/dist/sharing/consult.d.ts.map +1 -1
  100. package/dist/sharing/consult.js +144 -142
  101. package/dist/sharing/consult.js.map +1 -1
  102. package/dist/sharing/export.d.ts.map +1 -1
  103. package/dist/sharing/export.js +16 -16
  104. package/dist/sharing/export.js.map +1 -1
  105. package/dist/sharing/import.d.ts.map +1 -1
  106. package/dist/sharing/import.js +13 -12
  107. package/dist/sharing/import.js.map +1 -1
  108. package/dist/skills/skill-loader.d.ts.map +1 -1
  109. package/dist/skills/skill-loader.js +10 -9
  110. package/dist/skills/skill-loader.js.map +1 -1
  111. package/dist/skills/skill-script-loader.d.ts.map +1 -1
  112. package/dist/skills/skill-script-loader.js +6 -4
  113. package/dist/skills/skill-script-loader.js.map +1 -1
  114. package/dist/skills/skill-source.d.ts +3 -1
  115. package/dist/skills/skill-source.d.ts.map +1 -1
  116. package/dist/skills/skill-source.js +18 -16
  117. package/dist/skills/skill-source.js.map +1 -1
  118. package/dist/state/collection-map.d.ts +43 -0
  119. package/dist/state/collection-map.d.ts.map +1 -0
  120. package/dist/state/collection-map.js +9 -0
  121. package/dist/state/collection-map.js.map +1 -0
  122. package/dist/state/collections.d.ts +102 -0
  123. package/dist/state/collections.d.ts.map +1 -0
  124. package/dist/state/collections.js +317 -0
  125. package/dist/state/collections.js.map +1 -0
  126. package/dist/state/domain-types.d.ts +122 -0
  127. package/dist/state/domain-types.d.ts.map +1 -0
  128. package/dist/state/domain-types.js +54 -0
  129. package/dist/state/domain-types.js.map +1 -0
  130. package/dist/state/handles.d.ts +16 -0
  131. package/dist/state/handles.d.ts.map +1 -0
  132. package/dist/state/handles.js +161 -0
  133. package/dist/state/handles.js.map +1 -0
  134. package/dist/state/index.d.ts +17 -0
  135. package/dist/state/index.d.ts.map +1 -0
  136. package/dist/state/index.js +15 -0
  137. package/dist/state/index.js.map +1 -0
  138. package/dist/state/io/charter-io.d.ts +28 -0
  139. package/dist/state/io/charter-io.d.ts.map +1 -0
  140. package/dist/state/io/charter-io.js +94 -0
  141. package/dist/state/io/charter-io.js.map +1 -0
  142. package/dist/state/io/decisions-io.d.ts +42 -0
  143. package/dist/state/io/decisions-io.d.ts.map +1 -0
  144. package/dist/state/io/decisions-io.js +66 -0
  145. package/dist/state/io/decisions-io.js.map +1 -0
  146. package/dist/state/io/history-io.d.ts +37 -0
  147. package/dist/state/io/history-io.d.ts.map +1 -0
  148. package/dist/state/io/history-io.js +102 -0
  149. package/dist/state/io/history-io.js.map +1 -0
  150. package/dist/state/io/index.d.ts +19 -0
  151. package/dist/state/io/index.d.ts.map +1 -0
  152. package/dist/state/io/index.js +19 -0
  153. package/dist/state/io/index.js.map +1 -0
  154. package/dist/state/io/routing-io.d.ts +37 -0
  155. package/dist/state/io/routing-io.d.ts.map +1 -0
  156. package/dist/state/io/routing-io.js +99 -0
  157. package/dist/state/io/routing-io.js.map +1 -0
  158. package/dist/state/io/team-io.d.ts +46 -0
  159. package/dist/state/io/team-io.d.ts.map +1 -0
  160. package/dist/state/io/team-io.js +82 -0
  161. package/dist/state/io/team-io.js.map +1 -0
  162. package/dist/state/schema.d.ts +24 -0
  163. package/dist/state/schema.d.ts.map +1 -0
  164. package/dist/state/schema.js +41 -0
  165. package/dist/state/schema.js.map +1 -0
  166. package/dist/state/squad-state.d.ts +42 -0
  167. package/dist/state/squad-state.d.ts.map +1 -0
  168. package/dist/state/squad-state.js +68 -0
  169. package/dist/state/squad-state.js.map +1 -0
  170. package/dist/storage/fs-storage-provider.d.ts +60 -0
  171. package/dist/storage/fs-storage-provider.d.ts.map +1 -0
  172. package/dist/storage/fs-storage-provider.js +377 -0
  173. package/dist/storage/fs-storage-provider.js.map +1 -0
  174. package/dist/storage/in-memory-storage-provider.d.ts +46 -0
  175. package/dist/storage/in-memory-storage-provider.d.ts.map +1 -0
  176. package/dist/storage/in-memory-storage-provider.js +264 -0
  177. package/dist/storage/in-memory-storage-provider.js.map +1 -0
  178. package/dist/storage/index.d.ts +6 -0
  179. package/dist/storage/index.d.ts.map +1 -0
  180. package/dist/storage/index.js +5 -0
  181. package/dist/storage/index.js.map +1 -0
  182. package/dist/storage/sqlite-storage-provider.d.ts +95 -0
  183. package/dist/storage/sqlite-storage-provider.d.ts.map +1 -0
  184. package/dist/storage/sqlite-storage-provider.js +383 -0
  185. package/dist/storage/sqlite-storage-provider.js.map +1 -0
  186. package/dist/storage/storage-error.d.ts +28 -0
  187. package/dist/storage/storage-error.d.ts.map +1 -0
  188. package/dist/storage/storage-error.js +35 -0
  189. package/dist/storage/storage-error.js.map +1 -0
  190. package/dist/storage/storage-provider.d.ts +161 -0
  191. package/dist/storage/storage-provider.d.ts.map +1 -0
  192. package/dist/storage/storage-provider.js +18 -0
  193. package/dist/storage/storage-provider.js.map +1 -0
  194. package/dist/streams/resolver.d.ts.map +1 -1
  195. package/dist/streams/resolver.js +6 -5
  196. package/dist/streams/resolver.js.map +1 -1
  197. package/dist/tools/index.d.ts +5 -1
  198. package/dist/tools/index.d.ts.map +1 -1
  199. package/dist/tools/index.js +54 -15
  200. package/dist/tools/index.js.map +1 -1
  201. package/dist/upstream/resolver.d.ts +3 -2
  202. package/dist/upstream/resolver.d.ts.map +1 -1
  203. package/dist/upstream/resolver.js +33 -32
  204. package/dist/upstream/resolver.js.map +1 -1
  205. package/package.json +33 -1
  206. package/templates/casting/Futurama.json +9 -9
  207. package/templates/casting-history.json +4 -4
  208. package/templates/casting-policy.json +37 -37
  209. package/templates/casting-reference.md +104 -104
  210. package/templates/casting-registry.json +3 -3
  211. package/templates/ceremonies.md +41 -41
  212. package/templates/charter.md +53 -53
  213. package/templates/constraint-tracking.md +38 -38
  214. package/templates/cooperative-rate-limiting.md +229 -229
  215. package/templates/copilot-instructions.md +46 -46
  216. package/templates/history.md +10 -10
  217. package/templates/identity/now.md +9 -9
  218. package/templates/identity/wisdom.md +15 -15
  219. package/templates/issue-lifecycle.md +412 -412
  220. package/templates/keda-scaler.md +164 -164
  221. package/templates/machine-capabilities.md +74 -74
  222. package/templates/mcp-config.md +90 -90
  223. package/templates/multi-agent-format.md +28 -28
  224. package/templates/plugin-marketplace.md +49 -49
  225. package/templates/ralph-circuit-breaker.md +313 -313
  226. package/templates/raw-agent-output.md +37 -37
  227. package/templates/roster.md +60 -60
  228. package/templates/routing.md +39 -39
  229. package/templates/run-output.md +50 -50
  230. package/templates/schedule.json +19 -19
  231. package/templates/scribe-charter.md +123 -119
  232. package/templates/skill.md +24 -24
  233. package/templates/skills/agent-collaboration/SKILL.md +42 -42
  234. package/templates/skills/agent-conduct/SKILL.md +24 -24
  235. package/templates/skills/architectural-proposals/SKILL.md +151 -151
  236. package/templates/skills/ci-validation-gates/SKILL.md +84 -84
  237. package/templates/skills/cli-wiring/SKILL.md +47 -47
  238. package/templates/skills/client-compatibility/SKILL.md +89 -89
  239. package/templates/skills/cross-machine-coordination/SKILL.md +434 -0
  240. package/templates/skills/cross-squad/SKILL.md +114 -114
  241. package/templates/skills/distributed-mesh/SKILL.md +287 -287
  242. package/templates/skills/distributed-mesh/mesh.json.example +30 -30
  243. package/templates/skills/distributed-mesh/sync-mesh.ps1 +111 -111
  244. package/templates/skills/distributed-mesh/sync-mesh.sh +104 -104
  245. package/templates/skills/docs-standards/SKILL.md +71 -71
  246. package/templates/skills/economy-mode/SKILL.md +114 -114
  247. package/templates/skills/error-recovery/SKILL.md +99 -0
  248. package/templates/skills/external-comms/SKILL.md +329 -329
  249. package/templates/skills/gh-auth-isolation/SKILL.md +183 -183
  250. package/templates/skills/git-workflow/SKILL.md +204 -204
  251. package/templates/skills/github-multi-account/SKILL.md +95 -95
  252. package/templates/skills/history-hygiene/SKILL.md +36 -36
  253. package/templates/skills/humanizer/SKILL.md +105 -105
  254. package/templates/skills/init-mode/SKILL.md +102 -102
  255. package/templates/skills/iterative-retrieval/SKILL.md +165 -0
  256. package/templates/skills/model-selection/SKILL.md +117 -117
  257. package/templates/skills/nap/SKILL.md +24 -24
  258. package/templates/skills/notification-routing/SKILL.md +105 -0
  259. package/templates/skills/personal-squad/SKILL.md +57 -57
  260. package/templates/skills/pr-screenshots/SKILL.md +149 -0
  261. package/templates/skills/project-conventions/SKILL.md +56 -56
  262. package/templates/skills/ralph-two-pass-scan/SKILL.md +35 -0
  263. package/templates/skills/reflect/SKILL.md +229 -0
  264. package/templates/skills/release-process/SKILL.md +131 -423
  265. package/templates/skills/reskill/SKILL.md +92 -92
  266. package/templates/skills/retro-enforcement/SKILL.md +148 -0
  267. package/templates/skills/reviewer-protocol/SKILL.md +79 -79
  268. package/templates/skills/secret-handling/SKILL.md +200 -200
  269. package/templates/skills/session-recovery/SKILL.md +155 -155
  270. package/templates/skills/squad-conventions/SKILL.md +69 -69
  271. package/templates/skills/test-discipline/SKILL.md +37 -37
  272. package/templates/skills/tiered-memory/SKILL.md +234 -0
  273. package/templates/skills/windows-compatibility/SKILL.md +98 -74
  274. package/templates/{squad.agent.md → squad.agent.md.template} +57 -28
  275. package/templates/workflows/squad-ci.yml +24 -24
  276. package/templates/workflows/squad-docs.yml +54 -54
  277. package/templates/workflows/squad-heartbeat.yml +167 -171
  278. package/templates/workflows/squad-insider-release.yml +61 -61
  279. package/templates/workflows/squad-issue-assign.yml +161 -161
  280. package/templates/workflows/squad-label-enforce.yml +181 -181
  281. package/templates/workflows/squad-preview.yml +55 -55
  282. package/templates/workflows/squad-promote.yml +120 -120
  283. package/templates/workflows/squad-release.yml +77 -77
  284. package/templates/workflows/squad-triage.yml +260 -260
  285. package/templates/workflows/sync-squad-labels.yml +169 -169
@@ -1,161 +1,161 @@
1
- name: Squad Issue Assign
2
-
3
- on:
4
- issues:
5
- types: [labeled]
6
-
7
- permissions:
8
- issues: write
9
- contents: read
10
-
11
- jobs:
12
- assign-work:
13
- # Only trigger on squad:{member} labels (not the base "squad" label)
14
- if: startsWith(github.event.label.name, 'squad:')
15
- runs-on: ubuntu-latest
16
- steps:
17
- - uses: actions/checkout@v4
18
-
19
- - name: Identify assigned member and trigger work
20
- uses: actions/github-script@v7
21
- with:
22
- script: |
23
- const fs = require('fs');
24
- const issue = context.payload.issue;
25
- const label = context.payload.label.name;
26
-
27
- // Extract member name from label (e.g., "squad:ripley" → "ripley")
28
- const memberName = label.replace('squad:', '').toLowerCase();
29
-
30
- // Read team roster — check .squad/ first, fall back to .ai-team/
31
- let teamFile = '.squad/team.md';
32
- if (!fs.existsSync(teamFile)) {
33
- teamFile = '.ai-team/team.md';
34
- }
35
- if (!fs.existsSync(teamFile)) {
36
- core.warning('No .squad/team.md or .ai-team/team.md found — cannot assign work');
37
- return;
38
- }
39
-
40
- const content = fs.readFileSync(teamFile, 'utf8');
41
- const lines = content.split('\n');
42
-
43
- // Check if this is a coding agent assignment
44
- const isCopilotAssignment = memberName === 'copilot';
45
-
46
- let assignedMember = null;
47
- if (isCopilotAssignment) {
48
- assignedMember = { name: '@copilot', role: 'Coding Agent' };
49
- } else {
50
- let inMembersTable = false;
51
- for (const line of lines) {
52
- if (line.match(/^##\s+(Members|Team Roster)/i)) {
53
- inMembersTable = true;
54
- continue;
55
- }
56
- if (inMembersTable && line.startsWith('## ')) {
57
- break;
58
- }
59
- if (inMembersTable && line.startsWith('|') && !line.includes('---') && !line.includes('Name')) {
60
- const cells = line.split('|').map(c => c.trim()).filter(Boolean);
61
- if (cells.length >= 2 && cells[0].toLowerCase() === memberName) {
62
- assignedMember = { name: cells[0], role: cells[1] };
63
- break;
64
- }
65
- }
66
- }
67
- }
68
-
69
- if (!assignedMember) {
70
- core.warning(`No member found matching label "${label}"`);
71
- await github.rest.issues.createComment({
72
- owner: context.repo.owner,
73
- repo: context.repo.repo,
74
- issue_number: issue.number,
75
- body: `⚠️ No squad member found matching label \`${label}\`. Check \`.squad/team.md\` (or \`.ai-team/team.md\`) for valid member names.`
76
- });
77
- return;
78
- }
79
-
80
- // Post assignment acknowledgment
81
- let comment;
82
- if (isCopilotAssignment) {
83
- comment = [
84
- `### 🤖 Routed to @copilot (Coding Agent)`,
85
- '',
86
- `**Issue:** #${issue.number} — ${issue.title}`,
87
- '',
88
- `@copilot has been assigned and will pick this up automatically.`,
89
- '',
90
- `> The coding agent will create a \`copilot/*\` branch and open a draft PR.`,
91
- `> Review the PR as you would any team member's work.`,
92
- ].join('\n');
93
- } else {
94
- comment = [
95
- `### 📋 Assigned to ${assignedMember.name} (${assignedMember.role})`,
96
- '',
97
- `**Issue:** #${issue.number} — ${issue.title}`,
98
- '',
99
- `${assignedMember.name} will pick this up in the next Copilot session.`,
100
- '',
101
- `> **For Copilot coding agent:** If enabled, this issue will be worked automatically.`,
102
- `> Otherwise, start a Copilot session and say:`,
103
- `> \`${assignedMember.name}, work on issue #${issue.number}\``,
104
- ].join('\n');
105
- }
106
-
107
- await github.rest.issues.createComment({
108
- owner: context.repo.owner,
109
- repo: context.repo.repo,
110
- issue_number: issue.number,
111
- body: comment
112
- });
113
-
114
- core.info(`Issue #${issue.number} assigned to ${assignedMember.name} (${assignedMember.role})`);
115
-
116
- # Separate step: assign @copilot using PAT (required for coding agent)
117
- - name: Assign @copilot coding agent
118
- if: github.event.label.name == 'squad:copilot'
119
- uses: actions/github-script@v7
120
- with:
121
- github-token: ${{ secrets.COPILOT_ASSIGN_TOKEN }}
122
- script: |
123
- const owner = context.repo.owner;
124
- const repo = context.repo.repo;
125
- const issue_number = context.payload.issue.number;
126
-
127
- // Get the default branch name (main, master, etc.)
128
- const { data: repoData } = await github.rest.repos.get({ owner, repo });
129
- const baseBranch = repoData.default_branch;
130
-
131
- try {
132
- await github.request('POST /repos/{owner}/{repo}/issues/{issue_number}/assignees', {
133
- owner,
134
- repo,
135
- issue_number,
136
- assignees: ['copilot-swe-agent[bot]'],
137
- agent_assignment: {
138
- target_repo: `${owner}/${repo}`,
139
- base_branch: baseBranch,
140
- custom_instructions: '',
141
- custom_agent: '',
142
- model: ''
143
- },
144
- headers: {
145
- 'X-GitHub-Api-Version': '2022-11-28'
146
- }
147
- });
148
- core.info(`Assigned copilot-swe-agent to issue #${issue_number} (base: ${baseBranch})`);
149
- } catch (err) {
150
- core.warning(`Assignment with agent_assignment failed: ${err.message}`);
151
- // Fallback: try without agent_assignment
152
- try {
153
- await github.rest.issues.addAssignees({
154
- owner, repo, issue_number,
155
- assignees: ['copilot-swe-agent']
156
- });
157
- core.info(`Fallback assigned copilot-swe-agent to issue #${issue_number}`);
158
- } catch (err2) {
159
- core.warning(`Fallback also failed: ${err2.message}`);
160
- }
161
- }
1
+ name: Squad Issue Assign
2
+
3
+ on:
4
+ issues:
5
+ types: [labeled]
6
+
7
+ permissions:
8
+ issues: write
9
+ contents: read
10
+
11
+ jobs:
12
+ assign-work:
13
+ # Only trigger on squad:{member} labels (not the base "squad" label)
14
+ if: startsWith(github.event.label.name, 'squad:')
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Identify assigned member and trigger work
20
+ uses: actions/github-script@v7
21
+ with:
22
+ script: |
23
+ const fs = require('fs');
24
+ const issue = context.payload.issue;
25
+ const label = context.payload.label.name;
26
+
27
+ // Extract member name from label (e.g., "squad:ripley" → "ripley")
28
+ const memberName = label.replace('squad:', '').toLowerCase();
29
+
30
+ // Read team roster — check .squad/ first, fall back to .ai-team/
31
+ let teamFile = '.squad/team.md';
32
+ if (!fs.existsSync(teamFile)) {
33
+ teamFile = '.ai-team/team.md';
34
+ }
35
+ if (!fs.existsSync(teamFile)) {
36
+ core.warning('No .squad/team.md or .ai-team/team.md found — cannot assign work');
37
+ return;
38
+ }
39
+
40
+ const content = fs.readFileSync(teamFile, 'utf8');
41
+ const lines = content.split('\n');
42
+
43
+ // Check if this is a coding agent assignment
44
+ const isCopilotAssignment = memberName === 'copilot';
45
+
46
+ let assignedMember = null;
47
+ if (isCopilotAssignment) {
48
+ assignedMember = { name: '@copilot', role: 'Coding Agent' };
49
+ } else {
50
+ let inMembersTable = false;
51
+ for (const line of lines) {
52
+ if (line.match(/^##\s+(Members|Team Roster)/i)) {
53
+ inMembersTable = true;
54
+ continue;
55
+ }
56
+ if (inMembersTable && line.startsWith('## ')) {
57
+ break;
58
+ }
59
+ if (inMembersTable && line.startsWith('|') && !line.includes('---') && !line.includes('Name')) {
60
+ const cells = line.split('|').map(c => c.trim()).filter(Boolean);
61
+ if (cells.length >= 2 && cells[0].toLowerCase() === memberName) {
62
+ assignedMember = { name: cells[0], role: cells[1] };
63
+ break;
64
+ }
65
+ }
66
+ }
67
+ }
68
+
69
+ if (!assignedMember) {
70
+ core.warning(`No member found matching label "${label}"`);
71
+ await github.rest.issues.createComment({
72
+ owner: context.repo.owner,
73
+ repo: context.repo.repo,
74
+ issue_number: issue.number,
75
+ body: `⚠️ No squad member found matching label \`${label}\`. Check \`.squad/team.md\` (or \`.ai-team/team.md\`) for valid member names.`
76
+ });
77
+ return;
78
+ }
79
+
80
+ // Post assignment acknowledgment
81
+ let comment;
82
+ if (isCopilotAssignment) {
83
+ comment = [
84
+ `### 🤖 Routed to @copilot (Coding Agent)`,
85
+ '',
86
+ `**Issue:** #${issue.number} — ${issue.title}`,
87
+ '',
88
+ `@copilot has been assigned and will pick this up automatically.`,
89
+ '',
90
+ `> The coding agent will create a \`copilot/*\` branch and open a draft PR.`,
91
+ `> Review the PR as you would any team member's work.`,
92
+ ].join('\n');
93
+ } else {
94
+ comment = [
95
+ `### 📋 Assigned to ${assignedMember.name} (${assignedMember.role})`,
96
+ '',
97
+ `**Issue:** #${issue.number} — ${issue.title}`,
98
+ '',
99
+ `${assignedMember.name} will pick this up in the next Copilot session.`,
100
+ '',
101
+ `> **For Copilot coding agent:** If enabled, this issue will be worked automatically.`,
102
+ `> Otherwise, start a Copilot session and say:`,
103
+ `> \`${assignedMember.name}, work on issue #${issue.number}\``,
104
+ ].join('\n');
105
+ }
106
+
107
+ await github.rest.issues.createComment({
108
+ owner: context.repo.owner,
109
+ repo: context.repo.repo,
110
+ issue_number: issue.number,
111
+ body: comment
112
+ });
113
+
114
+ core.info(`Issue #${issue.number} assigned to ${assignedMember.name} (${assignedMember.role})`);
115
+
116
+ # Separate step: assign @copilot using PAT (required for coding agent)
117
+ - name: Assign @copilot coding agent
118
+ if: github.event.label.name == 'squad:copilot'
119
+ uses: actions/github-script@v7
120
+ with:
121
+ github-token: ${{ secrets.COPILOT_ASSIGN_TOKEN }}
122
+ script: |
123
+ const owner = context.repo.owner;
124
+ const repo = context.repo.repo;
125
+ const issue_number = context.payload.issue.number;
126
+
127
+ // Get the default branch name (main, master, etc.)
128
+ const { data: repoData } = await github.rest.repos.get({ owner, repo });
129
+ const baseBranch = repoData.default_branch;
130
+
131
+ try {
132
+ await github.request('POST /repos/{owner}/{repo}/issues/{issue_number}/assignees', {
133
+ owner,
134
+ repo,
135
+ issue_number,
136
+ assignees: ['copilot-swe-agent[bot]'],
137
+ agent_assignment: {
138
+ target_repo: `${owner}/${repo}`,
139
+ base_branch: baseBranch,
140
+ custom_instructions: '',
141
+ custom_agent: '',
142
+ model: ''
143
+ },
144
+ headers: {
145
+ 'X-GitHub-Api-Version': '2022-11-28'
146
+ }
147
+ });
148
+ core.info(`Assigned copilot-swe-agent to issue #${issue_number} (base: ${baseBranch})`);
149
+ } catch (err) {
150
+ core.warning(`Assignment with agent_assignment failed: ${err.message}`);
151
+ // Fallback: try without agent_assignment
152
+ try {
153
+ await github.rest.issues.addAssignees({
154
+ owner, repo, issue_number,
155
+ assignees: ['copilot-swe-agent']
156
+ });
157
+ core.info(`Fallback assigned copilot-swe-agent to issue #${issue_number}`);
158
+ } catch (err2) {
159
+ core.warning(`Fallback also failed: ${err2.message}`);
160
+ }
161
+ }