opencode-onboard 0.4.2 → 0.4.4

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 (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +304 -301
  3. package/content/.agents/agents/basic-engineer.md +4 -2
  4. package/content/.agents/agents/devops-manager.md +123 -123
  5. package/content/.agents/skills/ob-default/SKILL.md +25 -21
  6. package/content/.agents/skills/ob-generic-guardrails/SKILL.md +36 -32
  7. package/content/.agents/skills/ob-global/SKILL.md +92 -49
  8. package/content/.agents/skills/ob-pullrequest-az/SKILL.md +168 -160
  9. package/content/.agents/skills/ob-pullrequest-gh/SKILL.md +140 -136
  10. package/content/.opencode/commands/create-engineer.md +109 -0
  11. package/content/.opencode/commands/init.md +1 -1
  12. package/content/.opencode/commands/main.md +1 -1
  13. package/content/.opencode/commands/opsx-apply.md +131 -70
  14. package/content/.opencode/commands/plan.md +1 -1
  15. package/content/.opencode/plugins/session-log.js +523 -519
  16. package/content/.opencode/skills/openspec-apply-change/SKILL.md +86 -64
  17. package/content/AGENTS.md +67 -39
  18. package/package.json +1 -1
  19. package/src/commands/join.js +3 -3
  20. package/src/commands/single.js +2 -0
  21. package/src/commands/wizard.js +124 -99
  22. package/src/presets/browser.json +22 -18
  23. package/src/presets/optimization.json +27 -22
  24. package/src/presets/source.json +7 -1
  25. package/src/steps/browser/browser.test.js +115 -81
  26. package/src/steps/browser/index.js +62 -54
  27. package/src/steps/clean/index.js +108 -107
  28. package/src/steps/copy/agents.js +28 -0
  29. package/src/steps/copy/copy.test.js +1 -0
  30. package/src/steps/copy/index.js +2 -1
  31. package/src/steps/metadata/index.js +63 -61
  32. package/src/steps/models/format.js +61 -60
  33. package/src/steps/models/write.test.js +117 -117
  34. package/src/steps/openspec/ensemble.js +30 -7
  35. package/src/steps/openspec/ensemble.test.js +79 -79
  36. package/src/steps/openspec/index.js +121 -32
  37. package/src/steps/openspec/index.test.js +63 -0
  38. package/src/steps/optimization/caveman.js +34 -29
  39. package/src/steps/optimization/codegraph.js +52 -0
  40. package/src/steps/optimization/global.js +88 -64
  41. package/src/steps/optimization/global.test.js +99 -0
  42. package/src/steps/optimization/index.js +109 -101
  43. package/src/steps/optimization/optimization.test.js +101 -93
  44. package/src/steps/optimization/quota.js +84 -84
  45. package/src/steps/source/index.js +48 -0
  46. package/src/steps/source/source.test.js +124 -91
  47. package/src/utils/__tests__/copy.test.js +117 -117
  48. package/src/utils/exec-spinner.js +47 -47
  49. package/src/utils/exec.js +134 -131
  50. package/src/utils/terminal.js +6 -0
@@ -0,0 +1,109 @@
1
+ ---
2
+ description: Create a custom engineer agent from a description, with skills from skills.sh
3
+ ---
4
+
5
+ Create a new custom engineer agent based on the `basic-engineer.md` template.
6
+
7
+ **Usage**: `/create-engineer <name> "<description>"`
8
+
9
+ Example: `/create-engineer frontend-engineer "A frontend engineer specialized in React, Next.js, and CSS"`
10
+
11
+ **Steps**
12
+
13
+ 1. **Parse input**
14
+
15
+ Extract `<name>` and `<description>` from the arguments after `/create-engineer`.
16
+ - Name should be kebab-case (e.g., `frontend-engineer`)
17
+ - Description is the quoted string explaining the agent's specialty
18
+ - If no input provided, use the AskUserQuestion tool to ask for both.
19
+
20
+ 2. **Search for relevant skills from skills.sh**
21
+
22
+ Based on the description and the project context (read ARCHITECTURE.md, DESIGN.md), search for relevant skills:
23
+
24
+ ```bash
25
+ npx skills search "<relevant keywords from description>"
26
+ ```
27
+
28
+ If the search doesn't work or returns nothing, browse https://www.skills.sh/ for relevant skills based on the agent's specialty.
29
+
30
+ Select 2-5 skills that are most relevant to the agent's role. Prefer official/popular skills.
31
+
32
+ 3. **Install selected skills**
33
+
34
+ For each selected skill:
35
+ ```bash
36
+ npx skills add <owner/repo>
37
+ ```
38
+
39
+ This installs the skill files into the project.
40
+
41
+ 4. **Create the agent file**
42
+
43
+ Create `.agents/agents/<name>.md` with this structure:
44
+
45
+ ```markdown
46
+ ---
47
+ description: <description>
48
+ mode: subagent
49
+ color: <pick a unique hex color>
50
+ temperature: 0.2
51
+ permission:
52
+ edit: allow
53
+ bash: allow
54
+ read: allow
55
+ glob: allow
56
+ grep: allow
57
+ ---
58
+
59
+ ## Abilities
60
+ - Guardrails: @ob-generic-guardrails
61
+ - Development: <@installed-skill-1>, <@installed-skill-2>, ...
62
+ - Testing: <@installed-skill-for-testing>, ...
63
+ - Infrastructure: <@installed-skill-for-devops-cicd>, ...
64
+
65
+ ## Workflow
66
+
67
+ When spawned by the lead:
68
+ 1. Call `team_tasks_list` and verify your assigned task IDs and status before starting.
69
+ 2. For each assigned task: before calling `team_claim task_id:<id>`, check `team_tasks_list` to confirm every dependency of that task has status `done`. If any dependency is not done, skip to the next assigned task that IS unblocked. Only claim tasks whose dependencies are fully complete.
70
+ 3. Load `@ob-global` first, then load mandatory ability `Guardrails`.
71
+ 4. Load additional abilities from the `## Abilities` section as needed for the claimed task domain (for example: development, testing, infrastructure). Each ability can include one or more skills; load all relevant skills listed under each selected ability.
72
+ 5. Send a short `team_message` to lead confirming claimed task ID and loaded skills.
73
+ 6. Implement the task following all loaded skill rules.
74
+ 7. Call `team_tasks_complete task_id:<id>` after finishing that task.
75
+ 8. Repeat until all currently assigned tasks are completed or blocked.
76
+ 9. Message lead with results via `team_message`. Lead may assign more tasks, do NOT stop working or shut down until lead confirms no more tasks for you.
77
+ 10. If lead sends new task IDs via `team_message`, treat them as new assignments and go back to step 2.
78
+ ```
79
+
80
+ Place the installed skills under the most relevant ability category:
81
+ - **Development** — language frameworks, UI libraries, application code skills
82
+ - **Testing** — test frameworks, linting, type checking, validation skills
83
+ - **Infrastructure** — DevOps, CI/CD, cloud, deployment, containerization skills
84
+
85
+ Distribute skills across ALL categories that apply. Only include categories that have at least one real skill assigned (besides Guardrails which is always present).
86
+
87
+ 5. **Update AGENTS.md**
88
+
89
+ Add the new agent to the agents table in AGENTS.md:
90
+ ```
91
+ | `<name>` | .agents/agents/<name>.md | <short role description> |
92
+ ```
93
+
94
+ 6. **Show summary**
95
+
96
+ Report:
97
+ - Agent file created at `.agents/agents/custom-engineer-<name>.md`
98
+ - Skills installed (list each with source)
99
+ - How to use: "This agent will be spawned by the lead during `/opsx-apply` for tasks matching its specialty."
100
+
101
+ **Guidelines**
102
+ - Always keep `@ob-generic-guardrails` in the Guardrails ability
103
+ - NEVER use `@ob-default` in any ability category - all abilities must reference real installed skills
104
+ - **Development** = language/framework/UI skills. **Testing** = test/lint/typecheck skills. **Infrastructure** = DevOps, CI/CD, cloud, deployment skills. Never put UI/CSS skills under Infrastructure.
105
+ - Distribute installed skills across the appropriate categories — not just Development
106
+ - Only include ability categories that have at least one real skill assigned
107
+ - Pick a color that doesn't conflict with existing agents (basic-engineer uses #68A063)
108
+ - Skills should match both the agent description AND the project's tech stack
109
+ - If `npx skills` CLI is not available, manually reference skills by their `owner/repo` name in the abilities section and tell the user to install them
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Initialize the project runs the bootstrap sequence defined in AGENTS.md if not yet initialized.
2
+ description: Initialize the project, runs the bootstrap sequence defined in AGENTS.md if not yet initialized.
3
3
  ---
4
4
 
5
5
  Check if `AGENTS.md` is in bootstrap mode (contains `<!-- AGENTS-TEMPLATE-START -->`).
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Quick direct implementation no OpenSpec, no ensemble, no PRs. Just do it.
2
+ description: Quick direct implementation, no OpenSpec, no ensemble, no PRs. Just do it.
3
3
  ---
4
4
 
5
5
  Implement the task described after `/main` directly and immediately.
@@ -86,79 +86,134 @@ Implement tasks from an OpenSpec change using the ensemble agent team.
86
86
  DO NOT call team_claim yourself, only agents claim tasks.
87
87
  DO NOT proceed to 6d until team_tasks_add succeeds.
88
88
 
89
- **Step 6d.** Discover available agents, assign tasks by best fit, then spawn workers.
90
-
91
- Agent discovery and assignment rule:
92
- - Read `.agents/agents/*.md` and use each agent's `description` and `## Abilities` to understand specialization.
93
- - For each task ID, choose the best-fit agent based on task domain (backend, frontend, infra, testing, etc.).
94
- - Prefer specialized agents when available; use `basic-engineer` as fallback only.
95
- - Only spawn agents that have assigned task IDs.
96
-
97
- REQUIRED assignment algorithm (do not skip):
98
- 1. Build candidate list from `.agents/agents/*.md` excluding `devops-manager`.
99
- 2. Classify each task by domain using task text (api/backend, ui/frontend, infra/devops, testing/qa).
100
- 3. For each task, score every candidate agent:
101
- - +3 if agent description explicitly matches domain
102
- - +2 if agent `## Abilities` include domain-relevant skills
103
- - +1 if prior tasks of same domain already assigned to that agent (cohesion)
104
- 4. Assign task to highest-score agent.
105
- 5. Use `basic-engineer` ONLY when no specialized agent has positive score.
106
- 6. If all tasks go to `basic-engineer`, you MUST explain why no specialist matched.
107
-
108
- HARD RULES:
109
- - NEVER assign a task to `basic-engineer` if a specialized agent has higher score.
110
- - NEVER skip agent discovery from `.agents/agents/*.md`.
111
- - ALWAYS include assignment rationale in spawn prompt: "Selected because <domain match>".
112
-
113
- Skill loading is worker-driven:
114
- - The spawned agent MUST load `@ob-global` first.
115
- - Then it MUST load skills from its own `## Abilities` for the claimed task domain.
116
-
117
- Each team_spawn MUST include the agent field (required, causes NOT NULL error if omitted).
118
-
119
- The spawn prompt must contain exactly:
120
- 1. Their name and role on this team
121
- 2. Which tasks are theirs, list the task IDs and content from the board
122
- 2.1 Why they were selected for those tasks (domain/abilities match)
123
- 3. Key context they need (summarized from context files, do NOT tell them to read files themselves)
124
- 4. The 6 OpenCode tools they have available (these are OpenCode tools, NOT shell commands, call them directly as tools, never via bash):
125
- team_claim, team_tasks_complete, team_tasks_list, team_tasks_add, team_message, team_broadcast
126
- 5. How to proceed: call team_claim tool with the task_id to claim a task before starting it, call team_tasks_complete tool after finishing it, repeat until all their tasks are done, then call team_message tool to notify lead with results or blockers
127
- 6. Which skills to load: list the skill names and paths they MUST read before implementing. Example: "Before starting, read `.agents/skills/next-best-practices/SKILL.md` and follow its rules for all Next.js code."
128
-
129
- Keep spawn prompts under 600 tokens. Do not describe team internals or how ensemble works.
130
- Only spawn agents whose tasks are actually needed by this change. Skip agents with no tasks.
131
-
132
- Spawn one or more best-fit workers (parallel when dependencies allow):
133
- ```
134
- team_spawn name:"eng-1" agent:"backend-engineer" prompt:"..."
135
- team_spawn name:"eng-2" agent:"frontend-engineer" prompt:"..."
136
- team_spawn name:"eng-3" agent:"basic-engineer" prompt:"..."
137
- ```
138
-
139
- Then immediately send each spawned worker a start message with exact task IDs:
140
- ```
141
- team_message to:"eng-1" text:"Start now. Load @ob-global first, then use your agent `## Abilities` for these tasks: [task-<id1>] ... Claim each task ID before starting."
142
- team_message to:"eng-2" text:"Start now. Load @ob-global first, then use your agent `## Abilities` for these tasks: [task-<id2>] ... Claim each task ID before starting."
143
- team_message to:"eng-3" text:"Start now. Load @ob-global first, then use your agent `## Abilities` for these tasks: [task-<id3>] ... Claim each task ID before starting."
144
- ```
89
+ **Step 6d.** Discover available agents, assign an INITIAL BATCH of tasks, then spawn workers.
90
+
91
+ **CONCURRENCY LIMIT: Maximum {{MAX_CONCURRENT_AGENTS}} truly concurrent agents at a time.**
92
+ All agents in a wave MUST be spawned and running simultaneously, not one-at-a-time sequentially.
93
+
94
+ **ROLLING BATCH MODEL:**
95
+ Agents do NOT receive all their tasks upfront. Instead:
96
+ - Assign each agent an initial batch of up to 3 tasks (respecting dependencies).
97
+ - When an agent completes its batch and messages back, the lead assigns the next batch of up to 3 unassigned tasks from the board that match the agent's domain.
98
+ - Repeat until no pending tasks remain on the board.
99
+ - Only shut down an agent when the board has no more tasks for its domain.
100
+
101
+ This prevents agents from idling after one task, avoids overloading spawn prompts, and lets the lead adapt assignments based on progress.
102
+
103
+ **FILE DOMAIN SEPARATION (mandatory):**
104
+ Each agent MUST own a non-overlapping set of files/directories. Examples:
105
+ - Agent A owns `src/backend/Application/Commands/`, Agent B owns `src/backend/Application/Queries/`
106
+ - Agent A owns `src/frontend/app/(auth)/events/`, Agent B owns `src/frontend/app/(auth)/admin/`
107
+ Never assign two agents tasks that touch the same file or controller.
108
+
109
+ Agent discovery and assignment rule:
110
+ - Read `.agents/agents/*.md` and use each agent's `description` and `## Abilities` to understand specialization.
111
+ - For each task ID, choose the best-fit agent based on task domain (backend, frontend, infra, testing, etc.).
112
+ - Prefer specialized agents when available; use `basic-engineer` as fallback only.
113
+ - Only spawn agents that have assigned task IDs.
114
+
115
+ REQUIRED assignment algorithm (do not skip):
116
+ 1. Build candidate list from `.agents/agents/*.md` excluding `devops-manager`.
117
+ 2. Classify each task by domain using task text (api/backend, ui/frontend, infra/devops, testing/qa).
118
+ 3. For each task, score every candidate agent:
119
+ - +3 if agent description explicitly matches domain
120
+ - +2 if agent `## Abilities` include domain-relevant skills
121
+ - +1 if prior tasks of same domain already assigned to that agent (cohesion)
122
+ 4. Assign task to highest-score agent.
123
+ 5. Use `basic-engineer` ONLY when no specialized agent has positive score.
124
+ 6. If all tasks go to `basic-engineer`, you MUST explain why no specialist matched.
125
+
126
+ HARD RULES:
127
+ - NEVER assign a task to `basic-engineer` if a specialized agent has higher score.
128
+ - NEVER skip agent discovery from `.agents/agents/*.md`.
129
+ - ALWAYS include assignment rationale in spawn prompt: "Selected because <domain match>".
130
+
131
+ Skill loading is worker-driven:
132
+ - The spawned agent MUST load `@ob-global` first.
133
+ - Then it MUST load skills from its own `## Abilities` for the claimed task domain.
134
+
135
+ Each team_spawn MUST include the agent field (required, causes NOT NULL error if omitted).
136
+
137
+ **Spawn prompt format (strict, max 400 tokens):**
138
+
139
+ ```
140
+ You are {name}, {role}. Your file domain: {list of directories you own exclusively}.
141
+
142
+ Initial tasks (claim each with team_claim before starting, team_tasks_complete after commit):
143
+ - {task_id_1}: {one-line description}
144
+ - {task_id_2}: {one-line description}
145
+ - {task_id_3}: {one-line description}
146
+
147
+ Context: {2-3 sentences of essential context from the specs, NOT full file contents}
148
+
149
+ Build command: {e.g., "dotnet build TechEvents.slnx" or "pnpm build"}
150
+ After each task: git add -A && git commit -m "feat: <description>"
151
+
152
+ IMPORTANT: After completing all tasks above, message lead with results.
153
+ Lead may assign you more tasks. Do NOT shut down until lead confirms no more tasks.
154
+ Start with team_claim on your first task NOW. Do not read files or plan first.
155
+ ```
156
+
157
+ DO NOT include:
158
+ - Full file contents or code snippets in the prompt
159
+ - Descriptions of how ensemble works
160
+ - Lists of available tools (the agent already knows from its agent.md)
161
+ - Instructions to "message lead when planning", agents should only message when DONE or BLOCKED
162
+
163
+ Spawn workers:
164
+ ```
165
+ team_spawn name:"eng-1" agent:"backend-engineer" prompt:"..."
166
+ team_spawn name:"eng-2" agent:"frontend-engineer" prompt:"..."
167
+ ```
168
+
169
+ Then immediately send each spawned worker a start message:
170
+ ```
171
+ team_message to:"eng-1" text:"Start now. First action: team_claim {first_task_id}. Go."
172
+ team_message to:"eng-2" text:"Start now. First action: team_claim {first_task_id}. Go."
173
+ ```
145
174
 
146
175
  **Step 6e.** After sending start messages, tell the user what is running, then STOP and wait.
147
- Do NOT call team_results, team_status, or team_broadcast in a loop.
148
- Teammates will message you when done or blocked. Wait for those messages.
149
-
150
- **Step 6f.** When a teammate messages back, you receive a ping only, the full content is NOT in the notification.
151
- Call team_results to read the full message and mark it read. Then for each teammate: team_shutdown → team_merge.
152
- If team_merge blocks ("overlapping local changes"), commit or stash your local changes first, then retry.
153
- Fix any other blockers reported.
176
+ Do NOT call team_results, team_status, or team_broadcast in a loop.
177
+ Teammates will message you when done or blocked. Wait for those messages.
178
+
179
+ Tell the user: "Agents spawned. Check dashboard at http://localhost:4747/. I'll report when they finish."
180
+
181
+ **Step 6f.** When a teammate messages back (rolling re-assignment loop):
182
+ 1. Call `team_results from:"<name>"` to read full message.
183
+ 2. Call `team_tasks_list` to check remaining pending/unassigned tasks on the board.
184
+ 3. **If there are more unassigned tasks matching this agent's domain:**
185
+ - Pick up to 3 unassigned, unblocked tasks for this agent's domain.
186
+ - Send them via `team_message to:"<name>" text:"Next tasks: [task-<id1>] <desc>, [task-<id2>] <desc>, [task-<id3>] <desc>. Claim each with team_claim before starting."`
187
+ - Do NOT shut down the agent. Go back to waiting (step 6e).
188
+ 4. **If no more tasks for this agent:**
189
+ - `team_shutdown member:"<name>"`
190
+ - `team_merge member:"<name>"`
191
+ - If team_merge blocks on local changes: `git stash`, retry merge, `git stash pop`
192
+ 5. **If ALL agents are shut down and tasks remain unassigned** (new domain, dependencies unblocked):
193
+ - Spawn new agents for the remaining tasks (back to step 6d).
194
+ 6. **If ALL tasks are done:** proceed to step 7.
195
+
196
+ **IMMEDIATE SHUTDOWN RULE:** Never leave a finished agent running when there are no more tasks for it. But DO keep agents alive if more tasks in their domain are pending.
197
+
198
+ **ZERO PENDING TASKS GUARANTEE:** Before proceeding to step 7, call `team_tasks_list` and verify EVERY task is either `done` or `blocked`. If any task is `pending` and unassigned, assign it to an agent or spawn a new one. Never leave pending tasks orphaned.
199
+
200
+ **Step 6g. Stall detection (if agent has no commits after 5 minutes):**
201
+ 1. `team_message to:"<name>" text:"Status? If stuck, report blocker. If not started, run team_claim {task_id} now."`
202
+ 2. Wait 2 more minutes
203
+ 3. If still no response: `team_shutdown member:"<name>" force:true`
204
+ 4. Respawn with same tasks, fresh prompt
205
+ 5. Log stall in session-log for post-mortem
154
206
 
155
207
  7. **Verification check**
156
208
 
157
- Run verification tasks (tests/build/lint) using a worker suited for verification scope:
158
- - either same engineer workers
159
- - or a dedicated verifier worker if your project defines one
160
-
161
- Wait for results → fix blockers.
209
+ After ALL agents are merged, run verification on the lead branch directly:
210
+ ```bash
211
+ # Backend
212
+ dotnet build <solution>
213
+ # Frontend
214
+ pnpm build
215
+ ```
216
+ Fix any errors yourself (small fixes only). If large fixes needed, spawn one more agent.
162
217
 
163
218
  8. **Mark tasks complete in openspec**
164
219
 
@@ -183,12 +238,18 @@ Implement tasks from an OpenSpec change using the ensemble agent team.
183
238
  - NEVER call team_spawn before team_tasks_add, tasks must exist before agents are spawned
184
239
  - NEVER poll team_results or team_status in a loop, wait for teammates to message you
185
240
  - NEVER call team_claim or team_tasks_complete as lead, only agents call these tools
186
- - ALWAYS pass the task IDs returned by team_tasks_add to each agent's spawn prompt
187
241
  - NEVER edit files between team_spawn and team_merge, team_merge blocks on overlapping local changes
242
+ - NEVER leave pending tasks orphaned, always verify board is empty before proceeding to step 7
188
243
  - ALWAYS add every task to the board with team_tasks_add before spawning
244
+ - ALWAYS assign initial batch of up to 3 tasks per agent in spawn prompt
245
+ - ALWAYS re-assign next batch (up to 3) via team_message when agent reports done, if more tasks exist for its domain
246
+ - ALWAYS call team_tasks_list after each agent reports done to check for remaining unassigned tasks
189
247
  - ALWAYS spawn workers based on dependencies: parallel when safe, sequential when required
190
248
  - ALWAYS instruct agents to call team_claim before each task and team_tasks_complete after
191
- - If teammates are stuck, use team_message to resend tasks, then wait, never implement directly
249
+ - ALWAYS enforce max {{MAX_CONCURRENT_AGENTS}} truly concurrent agents (all running simultaneously, not sequentially)
250
+ - ALWAYS enforce non-overlapping file domains per agent
251
+ - ALWAYS shut down + merge agents only when no more tasks remain for their domain
252
+ - If teammates are stuck, use team_message to nudge, then stall detection (step 6g)
192
253
  - Mark tasks complete in openspec AFTER worker implementation and verification finish, not before
193
254
  - Pause on errors, blockers, or unclear requirements. Do not guess
194
255
  - Use contextFiles from CLI output, do not assume specific file paths
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Parse a user story URL and produce a plan proposal, specs, and tasks. Stops before implementation.
2
+ description: Parse a user story URL and produce a plan, proposal, specs, and tasks. Stops before implementation.
3
3
  ---
4
4
 
5
5
  Parse the work item at the URL provided after `/plan` and produce a full implementation plan.