opencode-onboard 0.1.4 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/content/.agents/agents/back-engineer.md +8 -0
- package/content/.agents/agents/devops-manager.md +14 -4
- package/content/.agents/agents/front-engineer.md +8 -0
- package/content/.agents/agents/infra-engineer.md +8 -0
- package/content/.agents/agents/quality-engineer.md +8 -0
- package/content/.agents/agents/security-auditor.md +8 -0
- package/content/.agents/skills/browser-automation/SKILL.md +3 -3
- package/content/.agents/skills/ob-pullrequest-az/SKILL.md +6 -6
- package/content/.agents/skills/ob-pullrequest-gh/SKILL.md +5 -5
- package/content/.agents/skills/ob-userstory-az/SKILL.md +2 -2
- package/content/.agents/skills/ob-userstory-gh/SKILL.md +4 -3
- package/content/.opencode/plugins/session-log.js +110 -0
- package/content/AGENTS.md +147 -29
- package/package.json +1 -1
- package/src/index.js +10 -7
- package/src/utils/copy.js +1 -1
|
@@ -72,3 +72,11 @@ Rules:
|
|
|
72
72
|
**Files changed:** <list>
|
|
73
73
|
**Blockers:** none | <description>
|
|
74
74
|
```
|
|
75
|
+
|
|
76
|
+
## Session Log
|
|
77
|
+
|
|
78
|
+
Append to `.agents/session-log.md`. Create the file with header if it does not exist (see AGENTS.md Session Log section). This is mandatory, do it before any other work.
|
|
79
|
+
|
|
80
|
+
- On start: `| {ISO timestamp} | back-engineer | started | {task summary} |`
|
|
81
|
+
- On skill load: `| {ISO timestamp} | back-engineer | skill-loaded | {skill-name} |`
|
|
82
|
+
- On done: `| {ISO timestamp} | back-engineer | completed | {files changed count} files, skills: {comma-separated skill names or none} |`
|
|
@@ -56,10 +56,11 @@ Rules:
|
|
|
56
56
|
1. Verify all changes are on a feature branch, never `main`
|
|
57
57
|
2. Load the matching pullrequest skill
|
|
58
58
|
3. Capture screenshots of local running app if UI changes exist
|
|
59
|
-
4.
|
|
60
|
-
5.
|
|
61
|
-
6.
|
|
62
|
-
7.
|
|
59
|
+
4. Read `.agents/session-log.md` if it exists, include a "Session Activity" section in the PR description with agent names, task counts, and total duration
|
|
60
|
+
5. Commit and push the feature branch
|
|
61
|
+
6. Create the PR following the skill instructions
|
|
62
|
+
7. Post PR comment with screenshots and change summary
|
|
63
|
+
8. Report PR URL to the lead
|
|
63
64
|
|
|
64
65
|
### Feedback Mode (PR review loop)
|
|
65
66
|
1. Load the matching pullrequest observer skill
|
|
@@ -73,6 +74,7 @@ Rules:
|
|
|
73
74
|
- Does not merge PRs, human-only
|
|
74
75
|
- Does not approve PRs, human-only
|
|
75
76
|
- Does not force push
|
|
77
|
+
- ALL GitHub and Azure DevOps data MUST come from `gh` or `az` CLI — NEVER use webfetch or HTTP requests to fetch platform URLs, even as a fallback. If CLI is unavailable, report as a blocker.
|
|
76
78
|
- Browser MCP tools permitted only for screenshots of local app on `localhost` URLs, never for navigating GitHub or Azure DevOps
|
|
77
79
|
|
|
78
80
|
## Output Format
|
|
@@ -106,3 +108,11 @@ Rules:
|
|
|
106
108
|
**Questions for human:** <count>, <list>
|
|
107
109
|
**Acknowledged only:** <count>
|
|
108
110
|
```
|
|
111
|
+
|
|
112
|
+
## Session Log
|
|
113
|
+
|
|
114
|
+
Append to `.agents/session-log.md`. Create the file with header if it does not exist (see AGENTS.md Session Log section). This is mandatory — do it before any other work.
|
|
115
|
+
|
|
116
|
+
- On start: `| {ISO timestamp} | devops-manager | started | {mode} mode |`
|
|
117
|
+
- On skill load: `| {ISO timestamp} | devops-manager | skill-loaded | {skill-name} |`
|
|
118
|
+
- On done: `| {ISO timestamp} | devops-manager | completed | {summary}, skills: {comma-separated skill names or none} |`
|
|
@@ -71,3 +71,11 @@ Rules:
|
|
|
71
71
|
**Files changed:** <list>
|
|
72
72
|
**Blockers:** none | <description>
|
|
73
73
|
```
|
|
74
|
+
|
|
75
|
+
## Session Log
|
|
76
|
+
|
|
77
|
+
Append to `.agents/session-log.md`. Create the file with header if it does not exist (see AGENTS.md Session Log section). This is mandatory, do it before any other work.
|
|
78
|
+
|
|
79
|
+
- On start: `| {ISO timestamp} | front-engineer | started | {task summary} |`
|
|
80
|
+
- On skill load: `| {ISO timestamp} | front-engineer | skill-loaded | {skill-name} |`
|
|
81
|
+
- On done: `| {ISO timestamp} | front-engineer | completed | {files changed count} files, skills: {comma-separated skill names or none} |`
|
|
@@ -72,3 +72,11 @@ Rules:
|
|
|
72
72
|
**Resources affected:** <list>
|
|
73
73
|
**Blockers:** none | <description>
|
|
74
74
|
```
|
|
75
|
+
|
|
76
|
+
## Session Log
|
|
77
|
+
|
|
78
|
+
Append to `.agents/session-log.md`. Create the file with header if it does not exist (see AGENTS.md Session Log section). This is mandatory — do it before any other work.
|
|
79
|
+
|
|
80
|
+
- On start: `| {ISO timestamp} | infra-engineer | started | {task summary} |`
|
|
81
|
+
- On skill load: `| {ISO timestamp} | infra-engineer | skill-loaded | {skill-name} |`
|
|
82
|
+
- On done: `| {ISO timestamp} | infra-engineer | completed | {files changed count} files, skills: {comma-separated skill names or none} |`
|
|
@@ -72,3 +72,11 @@ Rules:
|
|
|
72
72
|
**Acceptance criteria:** met | <unmet items>
|
|
73
73
|
**Blockers:** none | <description>
|
|
74
74
|
```
|
|
75
|
+
|
|
76
|
+
## Session Log
|
|
77
|
+
|
|
78
|
+
Append to `.agents/session-log.md`. Create the file with header if it does not exist (see AGENTS.md Session Log section). This is mandatory — do it before any other work.
|
|
79
|
+
|
|
80
|
+
- On start: `| {ISO timestamp} | quality-engineer | started | {task summary} |`
|
|
81
|
+
- On skill load: `| {ISO timestamp} | quality-engineer | skill-loaded | {skill-name} |`
|
|
82
|
+
- On done: `| {ISO timestamp} | quality-engineer | completed | {tests added count} tests, skills: {comma-separated skill names or none} |`
|
|
@@ -82,3 +82,11 @@ Rules:
|
|
|
82
82
|
|
|
83
83
|
**Blockers:** none | <critical findings that must be resolved before PR>
|
|
84
84
|
```
|
|
85
|
+
|
|
86
|
+
## Session Log
|
|
87
|
+
|
|
88
|
+
Append to `.agents/session-log.md`. Create the file with header if it does not exist (see AGENTS.md Session Log section). This is mandatory — do it before any other work.
|
|
89
|
+
|
|
90
|
+
- On start: `| {ISO timestamp} | security-auditor | started | {task summary} |`
|
|
91
|
+
- On skill load: `| {ISO timestamp} | security-auditor | skill-loaded | {skill-name} |`
|
|
92
|
+
- On done: `| {ISO timestamp} | security-auditor | completed | {findings count} findings, skills: {comma-separated skill names or none} |`
|
|
@@ -74,6 +74,6 @@ Browser MCP tools are permitted ONLY for interactions with the LOCAL running app
|
|
|
74
74
|
|
|
75
75
|
- ✅ Screenshots of locally running app on `localhost` URLs
|
|
76
76
|
- ✅ Click, type, scroll, query on `localhost` pages
|
|
77
|
-
- ❌ Navigate to external services (github.com, dev.azure.com, npmjs.com, etc.)
|
|
78
|
-
- ❌ Use browser tools for any DevOps or GitHub operations
|
|
79
|
-
- ❌ Use browser tools to read or modify production systems
|
|
77
|
+
- ❌ Navigate to external services (github.com, dev.azure.com, npmjs.com, etc.), FORBIDDEN
|
|
78
|
+
- ❌ Use browser tools for any DevOps or GitHub operations, FORBIDDEN
|
|
79
|
+
- ❌ Use browser tools to read or modify production systems, FORBIDDEN
|
|
@@ -64,7 +64,7 @@ rtk az repos pr create \
|
|
|
64
64
|
--description "{description}"
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
### Step 5: Link work item (MANDATORY, run sequentially
|
|
67
|
+
### Step 5: Link work item (MANDATORY, run sequentially, not in parallel)
|
|
68
68
|
|
|
69
69
|
```bash
|
|
70
70
|
rtk az repos pr work-item add --id {pr-id} --work-items {workitem-id}
|
|
@@ -151,7 +151,7 @@ rtk az devops invoke \
|
|
|
151
151
|
{
|
|
152
152
|
"comments": [{
|
|
153
153
|
"parentCommentId": 1,
|
|
154
|
-
"content": "Acknowledged
|
|
154
|
+
"content": "Acknowledged, applying this change now.",
|
|
155
155
|
"commentType": 1
|
|
156
156
|
}]
|
|
157
157
|
}
|
|
@@ -164,7 +164,7 @@ rtk az devops invoke \
|
|
|
164
164
|
- ✅ Commit and push to feature branches only
|
|
165
165
|
- ✅ Create and comment on PRs via az CLI
|
|
166
166
|
- ✅ Screenshots of localhost only via browser_screenshot
|
|
167
|
-
- ❌ Commit or push to `main
|
|
168
|
-
- ❌ Force push
|
|
169
|
-
- ❌ Merge or approve PRs
|
|
170
|
-
- ❌ Navigate browser to dev.azure.com
|
|
167
|
+
- ❌ Commit or push to `main`, FORBIDDEN
|
|
168
|
+
- ❌ Force push, FORBIDDEN
|
|
169
|
+
- ❌ Merge or approve PRs, human-only
|
|
170
|
+
- ❌ Navigate browser to dev.azure.com, FORBIDDEN
|
|
@@ -121,7 +121,7 @@ Update: `openspec/changes/{change}/proposal.md`, `design.md`, or `tasks.md` as a
|
|
|
121
121
|
# Reply to a review comment
|
|
122
122
|
rtk gh api repos/{owner}/{repo}/pulls/{pr-number}/comments/{comment-id}/replies \
|
|
123
123
|
--method POST \
|
|
124
|
-
--field body="Acknowledged
|
|
124
|
+
--field body="Acknowledged, applying this change now."
|
|
125
125
|
|
|
126
126
|
# Or post a general PR comment
|
|
127
127
|
rtk gh pr comment {pr-number} --body "Updated design.md to reflect feedback."
|
|
@@ -134,7 +134,7 @@ rtk gh pr comment {pr-number} --body "Updated design.md to reflect feedback."
|
|
|
134
134
|
- ✅ Commit and push to feature branches only
|
|
135
135
|
- ✅ Create and comment on PRs via gh CLI
|
|
136
136
|
- ✅ Screenshots of localhost only via browser_screenshot
|
|
137
|
-
- ❌ Commit or push to `main
|
|
138
|
-
- ❌ Force push
|
|
139
|
-
- ❌ Merge or approve PRs
|
|
140
|
-
- ❌ Navigate browser to github.com
|
|
137
|
+
- ❌ Commit or push to `main`, FORBIDDEN
|
|
138
|
+
- ❌ Force push, FORBIDDEN
|
|
139
|
+
- ❌ Merge or approve PRs, human-only
|
|
140
|
+
- ❌ Navigate browser to github.com, FORBIDDEN
|
|
@@ -168,5 +168,5 @@ https://dev.azure.com/{org}/{project}/_git/{repo}/pullrequest/{pr-id}
|
|
|
168
168
|
|
|
169
169
|
- ✅ Parse Azure DevOps URL and create OpenSpec change
|
|
170
170
|
- ✅ Use `rtk` for all Azure CLI operations
|
|
171
|
-
- ❌ Browser MCP tools for Azure DevOps operations
|
|
172
|
-
- ❌ Implementation
|
|
171
|
+
- ❌ Browser MCP tools for Azure DevOps operations, FORBIDDEN
|
|
172
|
+
- ❌ Implementation, this skill only parses and proposes
|
|
@@ -16,7 +16,7 @@ Use `rtk` wrapper for ALL CLI commands:
|
|
|
16
16
|
- `rtk gh issue edit` NOT `gh issue edit`
|
|
17
17
|
- `rtk openspec new change` NOT `openspec new change`
|
|
18
18
|
|
|
19
|
-
**
|
|
19
|
+
**ALL GitHub data MUST come from `gh` CLI. NEVER use webfetch, HTTP requests, or browser MCP tools to fetch GitHub URLs — even if gh CLI fails. If `gh` is unavailable, report it as a blocker.**
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
@@ -131,5 +131,6 @@ https://raw.githubusercontent.com/{owner}/{repo}/{branch}/{path}
|
|
|
131
131
|
|
|
132
132
|
- ✅ Parse GitHub Issue URL and create OpenSpec change
|
|
133
133
|
- ✅ Use `rtk gh` for all GitHub CLI operations
|
|
134
|
-
- ❌
|
|
135
|
-
- ❌
|
|
134
|
+
- ❌ `webfetch` or HTTP requests to GitHub URLs, FORBIDDEN — use `gh` CLI only
|
|
135
|
+
- ❌ Browser MCP tools for GitHub operations, FORBIDDEN
|
|
136
|
+
- ❌ Implementation, this skill only parses and proposes
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import fs from "node:fs"
|
|
2
|
+
import path from "node:path"
|
|
3
|
+
|
|
4
|
+
const LOG_FILE = ".agents/session-log.md"
|
|
5
|
+
const LOG_HEADER = "# Session Log\n\n| Timestamp | Agent | Action | Detail |\n|-----------|-------|--------|--------|\n"
|
|
6
|
+
|
|
7
|
+
// Per-session state: editCount and skills loaded
|
|
8
|
+
const sessionState = new Map()
|
|
9
|
+
|
|
10
|
+
function ts() {
|
|
11
|
+
return new Date().toISOString()
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function appendLog(directory, row) {
|
|
15
|
+
const logPath = path.join(directory, LOG_FILE)
|
|
16
|
+
const dir = path.dirname(logPath)
|
|
17
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })
|
|
18
|
+
if (!fs.existsSync(logPath)) fs.writeFileSync(logPath, LOG_HEADER, "utf8")
|
|
19
|
+
fs.appendFileSync(logPath, row + "\n", "utf8")
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function resolveAgentName(session) {
|
|
23
|
+
// session.agent is the path to the agent .md file, e.g. ".agents/agents/back-engineer.md"
|
|
24
|
+
const agentPath = session?.agent
|
|
25
|
+
if (agentPath) {
|
|
26
|
+
const base = path.basename(agentPath, ".md")
|
|
27
|
+
if (base) return base
|
|
28
|
+
}
|
|
29
|
+
// Fall back to session title (ensemble sets it to agent name)
|
|
30
|
+
const title = session?.title
|
|
31
|
+
if (title) return title
|
|
32
|
+
return "lead"
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const SessionLogPlugin = async ({ client, directory }) => {
|
|
36
|
+
return {
|
|
37
|
+
"session.created": async ({ event }) => {
|
|
38
|
+
try {
|
|
39
|
+
const sessionId = event.properties?.sessionID
|
|
40
|
+
if (!sessionId) return
|
|
41
|
+
|
|
42
|
+
const res = await client.session.get({ path: { id: sessionId } })
|
|
43
|
+
const session = res?.data
|
|
44
|
+
const agentName = resolveAgentName(session)
|
|
45
|
+
|
|
46
|
+
sessionState.set(sessionId, { agentName, editCount: 0, skills: [] })
|
|
47
|
+
|
|
48
|
+
appendLog(
|
|
49
|
+
directory,
|
|
50
|
+
`| ${ts()} | ${agentName} | started | session ${sessionId.slice(0, 8)} |`
|
|
51
|
+
)
|
|
52
|
+
} catch (_) {}
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
"tool.execute.after": async ({ event }) => {
|
|
56
|
+
try {
|
|
57
|
+
const { sessionID, tool, output } = event.properties ?? {}
|
|
58
|
+
if (!sessionID) return
|
|
59
|
+
|
|
60
|
+
const state = sessionState.get(sessionID)
|
|
61
|
+
const agentName = state?.agentName ?? "unknown"
|
|
62
|
+
|
|
63
|
+
// Skill detection: agent read a SKILL.md
|
|
64
|
+
if (tool === "read") {
|
|
65
|
+
const filePath = output?.args?.filePath ?? output?.input?.filePath ?? ""
|
|
66
|
+
const match = filePath.match(/[/\\]skills[/\\]([^/\\]+)[/\\]SKILL\.md$/i)
|
|
67
|
+
if (match) {
|
|
68
|
+
const skillName = match[1]
|
|
69
|
+
if (state && !state.skills.includes(skillName)) {
|
|
70
|
+
state.skills.push(skillName)
|
|
71
|
+
}
|
|
72
|
+
appendLog(
|
|
73
|
+
directory,
|
|
74
|
+
`| ${ts()} | ${agentName} | skill-loaded | ${skillName} |`
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
} catch (_) {}
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
"file.edited": async ({ event }) => {
|
|
82
|
+
try {
|
|
83
|
+
const { sessionID } = event.properties ?? {}
|
|
84
|
+
if (!sessionID) return
|
|
85
|
+
const state = sessionState.get(sessionID)
|
|
86
|
+
if (state) state.editCount++
|
|
87
|
+
} catch (_) {}
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
"session.idle": async ({ event }) => {
|
|
91
|
+
try {
|
|
92
|
+
const sessionId = event.properties?.sessionID
|
|
93
|
+
if (!sessionId) return
|
|
94
|
+
|
|
95
|
+
const state = sessionState.get(sessionId)
|
|
96
|
+
if (!state) return
|
|
97
|
+
|
|
98
|
+
const { agentName, editCount, skills } = state
|
|
99
|
+
const skillsSummary = skills.length > 0 ? skills.join(", ") : "none"
|
|
100
|
+
|
|
101
|
+
appendLog(
|
|
102
|
+
directory,
|
|
103
|
+
`| ${ts()} | ${agentName} | completed | ${editCount} files edited, skills: ${skillsSummary} |`
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
sessionState.delete(sessionId)
|
|
107
|
+
} catch (_) {}
|
|
108
|
+
},
|
|
109
|
+
}
|
|
110
|
+
}
|
package/content/AGENTS.md
CHANGED
|
@@ -35,33 +35,104 @@ openspec archive "project-history"
|
|
|
35
35
|
|
|
36
36
|
### Step 2, Generate DESIGN.md
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
`DESIGN.md` contains a prompt. You MUST follow this exact sequence, do not skip or reorder steps:
|
|
39
39
|
|
|
40
|
-
1.
|
|
41
|
-
2.
|
|
42
|
-
3.
|
|
43
|
-
4.
|
|
40
|
+
1. **Read `DESIGN.md` now** using a file read tool. The file contains a prompt with instructions and an output format.
|
|
41
|
+
2. **Store the full prompt text** in your context.
|
|
42
|
+
3. **Overwrite `DESIGN.md` with an empty string** (zero bytes). Do this before generating any content.
|
|
43
|
+
4. **Analyze the actual codebase**: read CSS files, Tailwind config, component files, token definitions. Do not rely on prior knowledge, read the files.
|
|
44
|
+
5. **Write the result into `DESIGN.md`** following exactly the format and sections described in the stored prompt.
|
|
44
45
|
|
|
45
|
-
The output must be a real, populated `DESIGN.md
|
|
46
|
+
The output must be a real, populated `DESIGN.md` based on what you found in the codebase, not from memory or assumptions.
|
|
46
47
|
|
|
47
48
|
---
|
|
48
49
|
|
|
49
50
|
### Step 3, Generate ARCHITECTURE.md
|
|
50
51
|
|
|
51
|
-
|
|
52
|
+
`ARCHITECTURE.md` contains a prompt. You MUST follow this exact sequence, do not skip or reorder steps:
|
|
52
53
|
|
|
53
|
-
1.
|
|
54
|
-
2.
|
|
55
|
-
3.
|
|
56
|
-
4.
|
|
54
|
+
1. **Read `ARCHITECTURE.md` now** using a file read tool. The file contains a prompt with instructions and an output format.
|
|
55
|
+
2. **Store the full prompt text** in your context.
|
|
56
|
+
3. **Overwrite `ARCHITECTURE.md` with an empty string** (zero bytes). Do this before generating any content.
|
|
57
|
+
4. **Analyze the actual codebase**: read folder structure, config files, route definitions, data models, integration points. Do not rely on prior knowledge, read the files.
|
|
58
|
+
5. **Write the result into `ARCHITECTURE.md`** following exactly the format and sections described in the stored prompt.
|
|
57
59
|
|
|
58
|
-
The output must be a real, populated `ARCHITECTURE.md`
|
|
60
|
+
The output must be a real, populated `ARCHITECTURE.md` based on what you found in the codebase, covering all sections the prompt describes.
|
|
59
61
|
|
|
60
62
|
---
|
|
61
63
|
|
|
62
64
|
### Step 4, Rewrite this file
|
|
63
65
|
|
|
64
|
-
Replace the entire contents of this file (`AGENTS.md`) with everything below the line `<!-- AGENTS-TEMPLATE-START -->` in this same file. Delete the bootstrap section and the template marker
|
|
66
|
+
Replace the entire contents of this file (`AGENTS.md`) with everything below the line `<!-- AGENTS-TEMPLATE-START -->` in this same file. Delete the bootstrap section and the template marker, the file should contain only the template content when done.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
### Step 4b, Patch opsx-apply for ensemble
|
|
71
|
+
|
|
72
|
+
Read **both** `.opencode/commands/opsx-apply.md` AND `.opencode/skills/openspec-apply-change/SKILL.md`. They contain the same solo implementation loop. Patch both identically.
|
|
73
|
+
|
|
74
|
+
In each file, find the step that instructs the agent to **implement tasks directly**, it will contain phrases like "make the code changes", "implement tasks", "loop until done or blocked". This step tells the agent to write code itself.
|
|
75
|
+
|
|
76
|
+
**Replace that step and everything after it** (completion output, pause output, guardrails, fluid workflow) with the following:
|
|
77
|
+
|
|
78
|
+
```markdown
|
|
79
|
+
6. **Implement via ensemble team**
|
|
80
|
+
|
|
81
|
+
NEVER implement tasks directly. Always delegate to specialists via ensemble.
|
|
82
|
+
|
|
83
|
+
a. Create feature branch if not already on one: `feature/{id}-{slug}`
|
|
84
|
+
b. Create team:
|
|
85
|
+
```
|
|
86
|
+
team_create "<change-name>"
|
|
87
|
+
```
|
|
88
|
+
Announce: "Team running. Monitor at http://localhost:4747/"
|
|
89
|
+
|
|
90
|
+
c. Spawn only what the tasks require (in parallel):
|
|
91
|
+
```
|
|
92
|
+
team_spawn name:front agent:front-engineer → UI/frontend tasks
|
|
93
|
+
team_spawn name:back agent:back-engineer → backend/API tasks
|
|
94
|
+
team_spawn name:infra agent:infra-engineer → infra/pipeline tasks
|
|
95
|
+
```
|
|
96
|
+
Pass each specialist: their relevant tasks + all context file paths from step above.
|
|
97
|
+
Log each spawn to `.agents/session-log.md` (see Session Log section).
|
|
98
|
+
|
|
99
|
+
d. Wait for all → `team_results` → `team_shutdown` + `team_merge`
|
|
100
|
+
|
|
101
|
+
7. **Quality check**
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
team_spawn name:quality agent:quality-engineer
|
|
105
|
+
```
|
|
106
|
+
Wait → `team_results` → fix blockers → `team_shutdown`
|
|
107
|
+
|
|
108
|
+
8. **Mark tasks complete in openspec**
|
|
109
|
+
|
|
110
|
+
After specialists finish, update the tasks file: `- [ ]` → `- [x]` for each completed task.
|
|
111
|
+
Run `openspec status --change "<name>" --json` to confirm progress.
|
|
112
|
+
|
|
113
|
+
9. **On completion or pause, show status**
|
|
114
|
+
|
|
115
|
+
Display:
|
|
116
|
+
- Tasks completed this session
|
|
117
|
+
- Overall progress: "N/M tasks complete"
|
|
118
|
+
- If all done: suggest archive with `/opsx-archive`
|
|
119
|
+
- If paused: explain why and wait for guidance
|
|
120
|
+
|
|
121
|
+
Then run `team_cleanup`.
|
|
122
|
+
|
|
123
|
+
**Guardrails**
|
|
124
|
+
- NEVER implement tasks directly, always use `team_create` + `team_spawn`, no exceptions
|
|
125
|
+
- "Small feature", "faster to do it directly", "environment issues" are NOT valid reasons to skip ensemble, if you find yourself thinking this, stop and spawn anyway
|
|
126
|
+
- Always read context files before spawning (from the apply instructions output)
|
|
127
|
+
- Always pass context file paths and task list to spawned specialists
|
|
128
|
+
- Mark tasks complete in openspec AFTER specialists finish, not before
|
|
129
|
+
- If task is ambiguous, pause and ask before spawning
|
|
130
|
+
- If implementation reveals issues, pause and suggest artifact updates
|
|
131
|
+
- Pause on errors, blockers, or unclear requirements, don't guess
|
|
132
|
+
- Use contextFiles from CLI output, don't assume specific file names
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Keep all steps before the implementation step unchanged in both files, they are openspec's domain (select change, check status, get instructions, read context, show progress).
|
|
65
136
|
|
|
66
137
|
---
|
|
67
138
|
|
|
@@ -87,6 +158,7 @@ You're ready to work.
|
|
|
87
158
|
- Do NOT implement any features
|
|
88
159
|
- Do NOT create branches or PRs
|
|
89
160
|
- Do NOT modify any project source files
|
|
161
|
+
- Do NOT create RTK files, scripts, or wrappers, RTK is already defined in AGENTS.md and agent files
|
|
90
162
|
- Only read source files for analysis, write only to ARCHITECTURE.md, DESIGN.md, AGENTS.md, and openspec/
|
|
91
163
|
|
|
92
164
|
<!-- AGENTS-TEMPLATE-START -->
|
|
@@ -108,12 +180,12 @@ This is the agent orchestration layer for your project. It provides:
|
|
|
108
180
|
When the user provides a work item URL, says "implement the plan", or "I've added comments to the PR", **I own the full lifecycle**. I load the appropriate skill and use ensemble tools (`team_create`, `team_spawn`, etc.) to coordinate the agent team.
|
|
109
181
|
|
|
110
182
|
Trigger patterns:
|
|
111
|
-
- `work on this <azure-devops-url>` → spawn `devops-manager` in read mode → propose OpenSpec → implement → ship
|
|
112
|
-
- `work on this <github-url>` → spawn `devops-manager` in read mode → propose OpenSpec → implement → ship
|
|
113
|
-
- `implement the plan` →
|
|
183
|
+
- `work on this <azure-devops-url>` → spawn `devops-manager` in read mode → propose OpenSpec → **confirm with user** → implement → ship
|
|
184
|
+
- `work on this <github-url>` → spawn `devops-manager` in read mode → propose OpenSpec → **confirm with user** → implement → ship
|
|
185
|
+
- `implement the plan` → run `/opsx-apply` (ensemble orchestration is built into the command) → ship
|
|
114
186
|
- `I've added comments to the PR` → spawn `devops-manager` in feedback mode → fix → update PR
|
|
115
187
|
|
|
116
|
-
**Never delegate without a plan. Never write implementation code directly, always spawn specialists.**
|
|
188
|
+
**Never delegate without a plan. Never write implementation code directly, always spawn specialists, no exceptions. "Small feature", "faster to do it directly", or "environment issues" are not valid reasons to skip ensemble.**
|
|
117
189
|
|
|
118
190
|
## Multi-Agent Execution, opencode-ensemble
|
|
119
191
|
|
|
@@ -166,21 +238,17 @@ devops-manager (ship mode)
|
|
|
166
238
|
1. team_spawn devops-manager (read mode) → fetch work item via skill, output summary
|
|
167
239
|
2. Load skill: openspec-propose → generate proposal.md, specs/, tasks.md
|
|
168
240
|
- team_create → spawn design + specs in parallel → merge → write tasks.md
|
|
169
|
-
3. Show
|
|
241
|
+
3. Show the plan: change name, schema, total tasks, task list summary
|
|
242
|
+
4. STOP. Ask user: "Ready to implement? (yes/no)", DO NOT proceed until confirmed.
|
|
170
243
|
```
|
|
171
244
|
|
|
172
245
|
### Phase 2, Implement
|
|
173
246
|
|
|
174
247
|
```
|
|
175
|
-
1.
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
5. Spawn only what the task needs (in parallel):
|
|
180
|
-
team_spawn name:front agent:front-engineer → UI tasks
|
|
181
|
-
team_spawn name:back agent:back-engineer → backend tasks
|
|
182
|
-
team_spawn name:infra agent:infra-engineer → infra tasks
|
|
183
|
-
6. Wait for all → team_results → team_shutdown + team_merge
|
|
248
|
+
1. Run /opsx-apply (or load skill openspec-apply-change)
|
|
249
|
+
The command handles context reading, ensemble orchestration, and task marking automatically.
|
|
250
|
+
DO NOT implement tasks directly, the command spawns specialists via ensemble.
|
|
251
|
+
2. After /opsx-apply completes, proceed to quality check.
|
|
184
252
|
```
|
|
185
253
|
|
|
186
254
|
### Phase 3, Quality
|
|
@@ -247,7 +315,7 @@ Skills are located in `.agents/skills/`. Each skill has a `SKILL.md` with a desc
|
|
|
247
315
|
| `openspec-propose` | Propose change artifacts (proposal, specs, tasks) |
|
|
248
316
|
| `openspec-apply-change` | Implement change with agent team |
|
|
249
317
|
| `openspec-archive-change` | Archive completed change |
|
|
250
|
-
| `browser-automation` | Browser automation for localhost UI
|
|
318
|
+
| `browser-automation` | Browser automation for localhost UI, screenshots, clicks, queries |
|
|
251
319
|
|
|
252
320
|
---
|
|
253
321
|
|
|
@@ -277,6 +345,56 @@ Example: `feature/42-add-user-auth`
|
|
|
277
345
|
|
|
278
346
|
---
|
|
279
347
|
|
|
348
|
+
## Session Log
|
|
349
|
+
|
|
350
|
+
<!-- session-logging: enabled -->
|
|
351
|
+
|
|
352
|
+
All agents MUST log their activity to `.agents/session-log.md`.
|
|
353
|
+
|
|
354
|
+
**Check before logging:** Read the `session-logging` comment above. If it says `disabled`, skip all logging.
|
|
355
|
+
|
|
356
|
+
**Every agent MUST create or append to this file when it starts, no exceptions.** If the file does not exist, create it with this exact header first:
|
|
357
|
+
|
|
358
|
+
```markdown
|
|
359
|
+
# Session Log
|
|
360
|
+
|
|
361
|
+
| Timestamp | Agent | Action | Detail |
|
|
362
|
+
|-----------|-------|--------|--------|
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
Then immediately append a `started` row.
|
|
366
|
+
|
|
367
|
+
**Log these events** by appending a row:
|
|
368
|
+
- Lead spawns an agent → `| {ISO timestamp} | lead | spawned | {agent-name}, {purpose} |`
|
|
369
|
+
- Agent starts → `| {ISO timestamp} | {agent-name} | started | {task summary} |`
|
|
370
|
+
- Agent loads a skill → `| {ISO timestamp} | {agent-name} | skill-loaded | {skill-name} |`
|
|
371
|
+
- Agent completes → `| {ISO timestamp} | {agent-name} | completed | {files changed count} files, skills: {comma-separated skill names or none} |`
|
|
372
|
+
- Agent blocked → `| {ISO timestamp} | {agent-name} | blocked | {reason} |`
|
|
373
|
+
|
|
374
|
+
**Rules:**
|
|
375
|
+
- Creating the file and logging `started` is mandatory, do it before any other work
|
|
376
|
+
- Append only, never overwrite previous entries
|
|
377
|
+
- One row per event, keep detail column short
|
|
378
|
+
- Use ISO 8601 timestamps
|
|
379
|
+
- The file is gitignored, never commit it
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## RTK
|
|
384
|
+
|
|
385
|
+
Use `rtk` wrapper for ALL CLI commands. Never run git, az, gh, or openspec commands directly.
|
|
386
|
+
|
|
387
|
+
- `rtk git add` NOT `git add`
|
|
388
|
+
- `rtk git commit` NOT `git commit`
|
|
389
|
+
- `rtk git push` NOT `git push`
|
|
390
|
+
- `rtk az boards work-item show` NOT `az boards work-item show`
|
|
391
|
+
- `rtk az repos pr create` NOT `az repos pr create`
|
|
392
|
+
- `rtk gh issue view` NOT `gh issue view`
|
|
393
|
+
- `rtk gh pr create` NOT `gh pr create`
|
|
394
|
+
- `rtk openspec new change` NOT `openspec new change`
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
280
398
|
## Guardrails
|
|
281
399
|
|
|
282
400
|
### Git Operations
|
|
@@ -293,7 +411,7 @@ Agents CANNOT:
|
|
|
293
411
|
|
|
294
412
|
### Platform CLI
|
|
295
413
|
|
|
296
|
-
ALL platform interactions via CLI only. Browser MCP FORBIDDEN for any DevOps or GitHub operation.
|
|
414
|
+
ALL platform interactions via CLI only. Browser MCP and webfetch FORBIDDEN for any DevOps or GitHub operation — use `gh` or `az` CLI exclusively, never fall back to HTTP requests.
|
|
297
415
|
|
|
298
416
|
| Operation | Azure DevOps | GitHub |
|
|
299
417
|
|-----------|-------------|--------|
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import chalk from 'chalk'
|
|
3
|
+
import { createRequire } from 'node:module'
|
|
3
4
|
import { checkEnv } from './steps/check-env.js'
|
|
4
5
|
import { checkPlatform } from './steps/check-platform.js'
|
|
5
6
|
import { checkRtk } from './steps/check-rtk.js'
|
|
@@ -13,22 +14,24 @@ import { installBrowser } from './steps/install-browser.js'
|
|
|
13
14
|
|
|
14
15
|
if (process.stdout.isTTY) console.clear()
|
|
15
16
|
console.log()
|
|
17
|
+
const require = createRequire(import.meta.url)
|
|
18
|
+
const { version } = require('../package.json')
|
|
16
19
|
const logo = chalk.hex('#fe3d57')
|
|
17
20
|
const bannerLines = [
|
|
18
|
-
logo('
|
|
21
|
+
logo(' '),
|
|
19
22
|
logo(' ▒▒▒▒▒▒▒▒▒▒▒▒▒ '),
|
|
20
23
|
logo(' ▒▒▓ ▓▒▓ '),
|
|
21
24
|
logo(' ▒▒▒▒▒▒▓▒▒▒▒▒▒▒▒▒▓▓▒▒▒▒▒ '),
|
|
22
25
|
logo(' ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓ '),
|
|
23
26
|
logo(' ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓ '),
|
|
24
|
-
logo('
|
|
27
|
+
logo(' ▓▒▒▒▒░░░▒▒▒▒▒▒▒▒▒▒▒░░░▒▒▒▓▓ '),
|
|
25
28
|
logo(' ▓▓▓▓▒▒▒▓▓▓▓▓▓▓▓▓▓▓▒▒▒▓▓▓▓ '),
|
|
26
|
-
logo('
|
|
27
|
-
logo(' ▓▒▒▒▒▒▒░▓▒▒▓▒▓▒▒▒▒▒▒▒▒▒▓▓ '),
|
|
29
|
+
logo(' ▓▓▒▒▒▒▒▒░▒▒▒▒▒▒▒░▒▒▒▒▒▒▓▓ '),
|
|
28
30
|
logo(' ▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓ '),
|
|
29
|
-
logo('
|
|
31
|
+
logo(' ▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓ '),
|
|
32
|
+
logo(' ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ '),
|
|
30
33
|
'',
|
|
31
|
-
chalk.bold(' 🧰 opencode-onboard'),
|
|
34
|
+
chalk.bold(' 🧰 opencode-onboard') + chalk.dim(` v${version}`),
|
|
32
35
|
chalk.dim(' Prepare your codebase for AI agents'),
|
|
33
36
|
]
|
|
34
37
|
|
|
@@ -51,7 +54,7 @@ if (process.stdin.isTTY) {
|
|
|
51
54
|
})
|
|
52
55
|
}
|
|
53
56
|
|
|
54
|
-
try {
|
|
57
|
+
try {
|
|
55
58
|
// 1. Check Node + pnpm
|
|
56
59
|
await checkEnv()
|
|
57
60
|
|
package/src/utils/copy.js
CHANGED
|
@@ -2,7 +2,7 @@ import fse from 'fs-extra'
|
|
|
2
2
|
import path from 'path'
|
|
3
3
|
|
|
4
4
|
// Folders never copied (skills handled separately by chooseSkillsProvider, .bootstrap is internal tooling)
|
|
5
|
-
const ALWAYS_EXCLUDE = ['.bootstrap', 'skills']
|
|
5
|
+
const ALWAYS_EXCLUDE = ['.bootstrap', 'skills', 'node_modules']
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Copy content/ directory to destination, excluding skills (handled separately by chooseSkillsProvider)
|