sdlc-subagents 0.1.0 → 0.1.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.
- package/LICENSE +21 -0
- package/README.md +160 -57
- package/dist/index.js +128 -58
- package/package.json +1 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Roy Zalta
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,19 +1,72 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# SDLC Sub-Agents
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
### Turn OpenCode into a multi-agent orchestrator
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
**One command. Six coding agents. Zero config.**
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
[](https://www.npmjs.com/package/sdlc-subagents)
|
|
10
|
+
[](./LICENSE)
|
|
11
|
+
[](https://nodejs.org)
|
|
12
|
+
[](./package.json)
|
|
13
|
+
|
|
14
|
+
<br />
|
|
15
|
+
|
|
16
|
+
<img src="https://opencode.ai/favicon.ico" width="28" alt="OpenCode" /> Built for [**OpenCode**](https://opencode.ai) — the open-source AI coding agent for the terminal
|
|
17
|
+
|
|
18
|
+
<br />
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
npx sdlc-subagents
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
<br />
|
|
25
|
+
|
|
26
|
+
[Quick Start](#-quick-start) · [Supported Agents](#-supported-agents) · [How It Works](#-how-it-works) · [Usage](#-usage-in-opencode) · [Install CLIs](#-installing-the-sub-agent-clis)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## The Problem
|
|
33
|
+
|
|
34
|
+
You have access to multiple AI coding agents — Gemini, Claude, Copilot, Aider, Kimi, Cursor — each with different strengths. But switching between them is manual, context is lost, and there's no unified workflow.
|
|
35
|
+
|
|
36
|
+
## The Solution
|
|
37
|
+
|
|
38
|
+
`sdlc-subagents` configures [OpenCode](https://opencode.ai) as a **meta-orchestrator** that knows when and how to delegate tasks to the right sub-agent CLI. It generates [Agent Skills](https://opencode.ai/docs/skills/) that teach OpenCode the strengths, invocation patterns, and routing logic for each agent.
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
┌─────────────────┐
|
|
42
|
+
│ OpenCode │
|
|
43
|
+
│ (orchestrator) │
|
|
44
|
+
└────────┬────────┘
|
|
45
|
+
│
|
|
46
|
+
┌──────────┬──────────┼──────────┬──────────┬──────────┐
|
|
47
|
+
▼ ▼ ▼ ▼ ▼ ▼
|
|
48
|
+
┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
|
|
49
|
+
│ Gemini │ │Copilot │ │ Claude │ │ Aider │ │ Kimi │ │ Cursor │
|
|
50
|
+
│ CLI │ │ CLI │ │ Code │ │ │ │ CLI │ │ CLI │
|
|
51
|
+
└────────┘ └────────┘ └────────┘ └────────┘ └────────┘ └────────┘
|
|
52
|
+
Research GitHub Refactor Pair Front-end IDE-grade
|
|
53
|
+
& Context Workflows & Debug Programming & UI Prototyping
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Supported Agents
|
|
59
|
+
|
|
60
|
+
| Agent | CLI | Best For | Install |
|
|
61
|
+
|:------|:----|:---------|:--------|
|
|
62
|
+
| <img src="https://www.gstatic.com/lamda/images/gemini_favicon_f069958c85030456e93de685481c559f160ea06b.png" width="16" /> [Gemini CLI](https://github.com/google-gemini/gemini-cli) | `gemini` | Large codebase analysis, research, documentation | `npm i -g @google/gemini-cli` |
|
|
63
|
+
| <img src="https://github.githubassets.com/favicons/favicon-dark.svg" width="16" /> [GitHub Copilot CLI](https://githubnext.com/projects/copilot-cli) | `copilot` | PR creation, issue management, GitHub workflows | `npm i -g @github/copilot` |
|
|
64
|
+
| <img src="https://mintlify.s3.us-west-1.amazonaws.com/anthropic/logo/light.svg" width="16" /> [Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview) | `claude` | Complex refactoring, architecture changes, debugging | `npm i -g @anthropic-ai/claude-code` |
|
|
65
|
+
| <img src="https://aider.chat/assets/icons/favicon-32x32.png" width="16" /> [Aider](https://aider.chat) | `aider` | Pair programming, auto-commits, any LLM provider | `pipx install aider-chat` |
|
|
66
|
+
| <img src="https://raw.githubusercontent.com/nicepkg/gpt-runner/main/docs/public/logo.svg" width="16" /> [Kimi CLI](https://github.com/MoonshotAI/kimi-cli) | `kimi` | Front-end development, UI components, long-context | `uv tool install --python 3.13 kimi-cli` |
|
|
67
|
+
| <img src="https://cursor.sh/favicon.ico" width="16" /> [Cursor CLI](https://cursor.sh) | `agent` | IDE-grade coding, cloud handoff, rapid prototyping | `curl https://cursor.sh/cli -fsS \| bash` |
|
|
68
|
+
|
|
69
|
+
---
|
|
17
70
|
|
|
18
71
|
## Quick Start
|
|
19
72
|
|
|
@@ -21,54 +74,81 @@ Run one command and your OpenCode agent learns how to delegate tasks to the righ
|
|
|
21
74
|
npx sdlc-subagents
|
|
22
75
|
```
|
|
23
76
|
|
|
24
|
-
That's it. The tool will:
|
|
77
|
+
That's it. No flags, no wizard, no config files to write. The tool will:
|
|
25
78
|
|
|
26
79
|
1. **Detect** which coding agent CLIs are installed on your system
|
|
27
|
-
2. **Generate** OpenCode skill files
|
|
28
|
-
3. **
|
|
80
|
+
2. **Generate** OpenCode skill files for all 6 agents (even uninstalled ones — install later)
|
|
81
|
+
3. **Create** `opencode.json` with permissions and `/delegate` custom commands
|
|
82
|
+
4. **Merge** safely into existing config (idempotent — re-run anytime)
|
|
29
83
|
|
|
30
|
-
|
|
84
|
+
### What gets created
|
|
31
85
|
|
|
32
86
|
```
|
|
33
87
|
your-project/
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
88
|
+
├── .agents/
|
|
89
|
+
│ └── skills/
|
|
90
|
+
│ ├── sdlc-orchestrator/SKILL.md ← Master routing logic
|
|
91
|
+
│ ├── gemini-cli/SKILL.md ← Gemini delegation patterns
|
|
92
|
+
│ ├── copilot-cli/SKILL.md ← Copilot delegation patterns
|
|
93
|
+
│ ├── claude-code/SKILL.md ← Claude delegation patterns
|
|
94
|
+
│ ├── aider/SKILL.md ← Aider delegation patterns
|
|
95
|
+
│ ├── kimi-cli/SKILL.md ← Kimi delegation patterns
|
|
96
|
+
│ └── cursor-cli/SKILL.md ← Cursor delegation patterns
|
|
97
|
+
└── opencode.json ← Permissions + /delegate commands
|
|
44
98
|
```
|
|
45
99
|
|
|
46
|
-
|
|
100
|
+
---
|
|
47
101
|
|
|
48
|
-
|
|
102
|
+
## How It Works
|
|
103
|
+
|
|
104
|
+
Each generated skill file teaches OpenCode:
|
|
105
|
+
|
|
106
|
+
| Section | What it contains |
|
|
107
|
+
|:--------|:-----------------|
|
|
108
|
+
| **When to delegate** | Task types the agent excels at |
|
|
109
|
+
| **How to invoke** | Exact CLI commands for non-interactive use |
|
|
110
|
+
| **Delegation patterns** | Bash patterns for capturing output |
|
|
111
|
+
| **Important notes** | Auth requirements, flags, gotchas |
|
|
112
|
+
|
|
113
|
+
The master **`sdlc-orchestrator`** skill provides a routing table that maps task types to the best agent:
|
|
114
|
+
|
|
115
|
+
| Task Type | Routed To |
|
|
116
|
+
|:----------|:----------|
|
|
117
|
+
| Large codebase analysis, research, documentation | Gemini CLI |
|
|
118
|
+
| GitHub PRs, issues, code review, repo management | Copilot CLI |
|
|
119
|
+
| Complex refactoring, architecture changes, debugging | Claude Code |
|
|
120
|
+
| Incremental changes with git commits, multi-model | Aider |
|
|
121
|
+
| Front-end development, UI components, styling | Kimi CLI |
|
|
122
|
+
| IDE-grade coding, cloud handoff, rapid prototyping | Cursor CLI |
|
|
123
|
+
|
|
124
|
+
---
|
|
49
125
|
|
|
50
|
-
|
|
126
|
+
## Usage in OpenCode
|
|
127
|
+
|
|
128
|
+
After scaffolding, open your project with OpenCode. The skills are discovered automatically.
|
|
51
129
|
|
|
52
|
-
|
|
130
|
+
### Auto-routing — let OpenCode choose
|
|
53
131
|
|
|
54
132
|
```
|
|
55
133
|
/delegate Analyze the entire codebase and generate API documentation
|
|
56
134
|
```
|
|
57
135
|
|
|
58
|
-
OpenCode
|
|
136
|
+
> OpenCode reads the orchestrator skill, identifies this as a research/documentation task, and routes to **Gemini CLI**.
|
|
59
137
|
|
|
60
138
|
### Force a specific agent
|
|
61
139
|
|
|
62
140
|
```
|
|
63
|
-
/delegate-claude-code
|
|
64
|
-
/delegate-copilot-cli
|
|
65
|
-
/delegate-aider
|
|
66
|
-
/delegate-kimi-cli
|
|
141
|
+
/delegate-claude-code Refactor the auth module to use strategy pattern
|
|
142
|
+
/delegate-copilot-cli Create a PR for the current branch changes
|
|
143
|
+
/delegate-aider Add input validation to all API endpoints
|
|
144
|
+
/delegate-kimi-cli Build a responsive dashboard with Tailwind
|
|
145
|
+
/delegate-gemini-cli Explain how the payment system works across all services
|
|
146
|
+
/delegate-cursor-cli Prototype a new CLI tool for data migration
|
|
67
147
|
```
|
|
68
148
|
|
|
69
|
-
### Natural language
|
|
149
|
+
### Natural language — no commands needed
|
|
70
150
|
|
|
71
|
-
|
|
151
|
+
Just describe your task. OpenCode loads the orchestrator skill and routes automatically:
|
|
72
152
|
|
|
73
153
|
```
|
|
74
154
|
> Use Gemini to research how the payment system works across all microservices
|
|
@@ -76,49 +156,72 @@ You don't even need the commands. Just describe your task and OpenCode will load
|
|
|
76
156
|
> Ask Aider to add tests for the auth module, commit each test separately
|
|
77
157
|
```
|
|
78
158
|
|
|
79
|
-
|
|
159
|
+
### Multi-agent workflows
|
|
80
160
|
|
|
81
|
-
|
|
161
|
+
Chain agents for complex SDLC workflows:
|
|
82
162
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
-
|
|
86
|
-
|
|
87
|
-
-
|
|
163
|
+
```
|
|
164
|
+
1. /delegate-gemini-cli Analyze the requirements and existing auth code
|
|
165
|
+
2. /delegate-claude-code Implement the new OAuth2 flow based on Gemini's analysis
|
|
166
|
+
3. /delegate-kimi-cli Build the login UI components
|
|
167
|
+
4. /delegate-aider Add integration tests, commit each one
|
|
168
|
+
5. /delegate-copilot-cli Create a PR with a detailed description
|
|
169
|
+
```
|
|
88
170
|
|
|
89
|
-
|
|
171
|
+
---
|
|
90
172
|
|
|
91
173
|
## Re-running
|
|
92
174
|
|
|
93
|
-
|
|
94
|
-
-
|
|
95
|
-
|
|
96
|
-
|
|
175
|
+
```bash
|
|
176
|
+
npx sdlc-subagents
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Safe to run multiple times. It will:
|
|
180
|
+
|
|
181
|
+
- Update skill files with the latest templates
|
|
182
|
+
- Merge new config into existing `opencode.json` without overwriting your customizations
|
|
183
|
+
- Re-detect installed CLIs and update status
|
|
184
|
+
|
|
185
|
+
---
|
|
97
186
|
|
|
98
187
|
## Installing the Sub-Agent CLIs
|
|
99
188
|
|
|
100
|
-
|
|
189
|
+
Skills are generated for **all agents** regardless of installation status. Install any agent when you're ready:
|
|
101
190
|
|
|
102
191
|
```bash
|
|
103
|
-
# Gemini CLI
|
|
192
|
+
# Gemini CLI — Google's 1M token context agent
|
|
104
193
|
npm install -g @google/gemini-cli
|
|
105
194
|
|
|
106
|
-
# GitHub Copilot CLI
|
|
195
|
+
# GitHub Copilot CLI — GitHub-native workflow agent
|
|
107
196
|
npm install -g @github/copilot
|
|
108
197
|
|
|
109
|
-
# Claude Code
|
|
198
|
+
# Claude Code — Anthropic's deep reasoning agent
|
|
110
199
|
npm install -g @anthropic-ai/claude-code
|
|
111
200
|
|
|
112
|
-
# Aider
|
|
201
|
+
# Aider — Model-agnostic pair programmer
|
|
113
202
|
pipx install aider-chat
|
|
114
203
|
|
|
115
|
-
# Kimi CLI
|
|
204
|
+
# Kimi CLI — Moonshot's long-context agent
|
|
116
205
|
uv tool install --python 3.13 kimi-cli
|
|
117
206
|
|
|
118
|
-
# Cursor CLI
|
|
207
|
+
# Cursor CLI — IDE-grade terminal agent
|
|
119
208
|
curl https://cursor.sh/cli -fsS | bash
|
|
120
209
|
```
|
|
121
210
|
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Requirements
|
|
214
|
+
|
|
215
|
+
- **Node.js** >= 18
|
|
216
|
+
- **OpenCode** — [install from opencode.ai](https://opencode.ai)
|
|
217
|
+
- At least one sub-agent CLI installed (or install later)
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Contributing
|
|
222
|
+
|
|
223
|
+
Contributions are welcome! If you'd like to add support for a new coding agent CLI or improve the delegation skills, please open an issue or PR.
|
|
224
|
+
|
|
122
225
|
## License
|
|
123
226
|
|
|
124
|
-
MIT
|
|
227
|
+
[MIT](./LICENSE) — Roy Zalta
|
package/dist/index.js
CHANGED
|
@@ -44,7 +44,7 @@ var AGENTS = [
|
|
|
44
44
|
id: "aider",
|
|
45
45
|
name: "Aider",
|
|
46
46
|
command: "aider",
|
|
47
|
-
installCommand: "
|
|
47
|
+
installCommand: "curl -LsSf https://aider.chat/install.sh | sh",
|
|
48
48
|
description: "Model-agnostic AI pair programming tool that works with any LLM and auto-commits changes to git",
|
|
49
49
|
bestFor: "Pair programming, incremental changes with auto-commits, working with any LLM provider, architect mode for complex changes",
|
|
50
50
|
nonInteractiveFlag: '--message "PROMPT" --yes',
|
|
@@ -81,6 +81,43 @@ var yellow = (s) => `\x1B[33m${s}\x1B[0m`;
|
|
|
81
81
|
var red = (s) => `\x1B[31m${s}\x1B[0m`;
|
|
82
82
|
var dim = (s) => `\x1B[2m${s}\x1B[0m`;
|
|
83
83
|
var cyan = (s) => `\x1B[36m${s}\x1B[0m`;
|
|
84
|
+
var bgGreen = (s) => `\x1B[42m\x1B[30m${s}\x1B[0m`;
|
|
85
|
+
var bgYellow = (s) => `\x1B[43m\x1B[30m${s}\x1B[0m`;
|
|
86
|
+
var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
87
|
+
function createSpinner(text) {
|
|
88
|
+
let frame = 0;
|
|
89
|
+
let interval = null;
|
|
90
|
+
return {
|
|
91
|
+
start() {
|
|
92
|
+
process.stdout.write("\x1B[?25l");
|
|
93
|
+
interval = setInterval(() => {
|
|
94
|
+
const spinner = cyan(SPINNER_FRAMES[frame % SPINNER_FRAMES.length]);
|
|
95
|
+
process.stdout.write(`\r ${spinner} ${text}`);
|
|
96
|
+
frame++;
|
|
97
|
+
}, 80);
|
|
98
|
+
},
|
|
99
|
+
succeed(msg) {
|
|
100
|
+
if (interval) clearInterval(interval);
|
|
101
|
+
process.stdout.write(`\r ${green("\u2714")} ${msg}\x1B[K
|
|
102
|
+
`);
|
|
103
|
+
process.stdout.write("\x1B[?25h");
|
|
104
|
+
},
|
|
105
|
+
fail(msg) {
|
|
106
|
+
if (interval) clearInterval(interval);
|
|
107
|
+
process.stdout.write(`\r ${red("\u2716")} ${msg}\x1B[K
|
|
108
|
+
`);
|
|
109
|
+
process.stdout.write("\x1B[?25h");
|
|
110
|
+
},
|
|
111
|
+
stop() {
|
|
112
|
+
if (interval) clearInterval(interval);
|
|
113
|
+
process.stdout.write("\x1B[?25h");
|
|
114
|
+
process.stdout.write("\x1B[K");
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function sleep(ms) {
|
|
119
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
120
|
+
}
|
|
84
121
|
var __filename = fileURLToPath(import.meta.url);
|
|
85
122
|
var __dirname = dirname(__filename);
|
|
86
123
|
var TEMPLATES_DIR = resolve(__dirname, "..", "templates");
|
|
@@ -166,109 +203,142 @@ function mergeInstructions(existing, additions) {
|
|
|
166
203
|
const set = /* @__PURE__ */ new Set([...existing, ...additions]);
|
|
167
204
|
return [...set];
|
|
168
205
|
}
|
|
206
|
+
function progressBar(current, total, width = 20) {
|
|
207
|
+
const filled = Math.round(current / total * width);
|
|
208
|
+
const empty = width - filled;
|
|
209
|
+
const bar = "\u2588".repeat(filled) + "\u2591".repeat(empty);
|
|
210
|
+
const pct = Math.round(current / total * 100);
|
|
211
|
+
return `${dim("[")}${green(bar)}${dim("]")} ${dim(`${pct}%`)}`;
|
|
212
|
+
}
|
|
213
|
+
function printBanner() {
|
|
214
|
+
const banner = `
|
|
215
|
+
${bold(cyan("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"))}
|
|
216
|
+
${bold(cyan("\u2551"))} ${bold(cyan("\u2551"))}
|
|
217
|
+
${bold(cyan("\u2551"))} ${bold("\u26A1 SDLC Sub-Agents")} ${bold(cyan("\u2551"))}
|
|
218
|
+
${bold(cyan("\u2551"))} ${dim("Multi-Agent Orchestrator for OpenCode")} ${bold(cyan("\u2551"))}
|
|
219
|
+
${bold(cyan("\u2551"))} ${bold(cyan("\u2551"))}
|
|
220
|
+
${bold(cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"))}
|
|
221
|
+
`;
|
|
222
|
+
console.log(banner);
|
|
223
|
+
}
|
|
169
224
|
async function main() {
|
|
170
225
|
const targetDir = process.cwd();
|
|
171
|
-
console.
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
);
|
|
175
|
-
console.log();
|
|
176
|
-
console.log(dim(" Detecting installed coding agent CLIs..."));
|
|
177
|
-
console.log();
|
|
226
|
+
console.clear();
|
|
227
|
+
printBanner();
|
|
228
|
+
const stepSpinner = createSpinner("Scanning for installed coding agent CLIs...");
|
|
229
|
+
stepSpinner.start();
|
|
178
230
|
const installed = detectInstalledAgents();
|
|
179
231
|
const found = [];
|
|
180
232
|
const missing = [];
|
|
181
233
|
for (const agent of AGENTS) {
|
|
182
234
|
if (installed.get(agent.id)) {
|
|
183
235
|
found.push(agent);
|
|
236
|
+
} else {
|
|
237
|
+
missing.push(agent);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
await sleep(800);
|
|
241
|
+
stepSpinner.succeed(`Scanned ${bold(String(AGENTS.length))} coding agent CLIs`);
|
|
242
|
+
console.log();
|
|
243
|
+
for (const agent of AGENTS) {
|
|
244
|
+
const isInstalled = installed.get(agent.id);
|
|
245
|
+
if (isInstalled) {
|
|
184
246
|
console.log(
|
|
185
|
-
` ${green("
|
|
247
|
+
` ${green("\u25CF")} ${bold(agent.name)} ${dim(`(${agent.command})`)} ${green("installed")}`
|
|
186
248
|
);
|
|
187
249
|
} else {
|
|
188
|
-
missing.push(agent);
|
|
189
250
|
console.log(
|
|
190
|
-
` ${red("
|
|
251
|
+
` ${red("\u25CB")} ${bold(agent.name)} ${dim(`(${agent.command})`)} ${red("not found")}`
|
|
191
252
|
);
|
|
192
253
|
}
|
|
254
|
+
await sleep(150);
|
|
193
255
|
}
|
|
194
256
|
console.log();
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
257
|
+
const summaryParts = [];
|
|
258
|
+
if (found.length > 0)
|
|
259
|
+
summaryParts.push(bgGreen(` ${found.length} found `));
|
|
260
|
+
if (missing.length > 0)
|
|
261
|
+
summaryParts.push(bgYellow(` ${missing.length} missing `));
|
|
262
|
+
console.log(` ${summaryParts.join(" ")}`);
|
|
198
263
|
console.log();
|
|
199
|
-
|
|
264
|
+
const totalFiles = AGENTS.length + 1;
|
|
265
|
+
let fileCount = 0;
|
|
200
266
|
const skillsDir = ".agents/skills";
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
);
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
orchestratorContent
|
|
208
|
-
);
|
|
209
|
-
console.log(
|
|
210
|
-
` ${green("+")} ${orchResult} ${cyan(`${skillsDir}/sdlc-orchestrator/SKILL.md`)}`
|
|
211
|
-
);
|
|
267
|
+
const fileSpinner = createSpinner("Writing skill files...");
|
|
268
|
+
fileSpinner.start();
|
|
269
|
+
const orchestratorContent = readTemplate("skills/sdlc-orchestrator/SKILL.md");
|
|
270
|
+
writeFile(targetDir, `${skillsDir}/sdlc-orchestrator/SKILL.md`, orchestratorContent);
|
|
271
|
+
fileCount++;
|
|
272
|
+
await sleep(200);
|
|
212
273
|
for (const agent of AGENTS) {
|
|
213
274
|
const content = readTemplate(`skills/${agent.id}/SKILL.md`);
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
const status = installed.get(agent.id) ? green("+") : yellow("~");
|
|
220
|
-
console.log(
|
|
221
|
-
` ${status} ${result} ${cyan(`${skillsDir}/${agent.id}/SKILL.md`)}`
|
|
275
|
+
writeFile(targetDir, `${skillsDir}/${agent.id}/SKILL.md`, content);
|
|
276
|
+
fileCount++;
|
|
277
|
+
fileSpinner.stop();
|
|
278
|
+
process.stdout.write(
|
|
279
|
+
`\r ${cyan(SPINNER_FRAMES[fileCount % SPINNER_FRAMES.length])} Writing skill files... ${progressBar(fileCount, totalFiles)}`
|
|
222
280
|
);
|
|
281
|
+
await sleep(200);
|
|
223
282
|
}
|
|
283
|
+
process.stdout.write(`\r\x1B[K`);
|
|
284
|
+
console.log(` ${green("\u2714")} Created ${bold(String(totalFiles))} skill files in ${cyan(skillsDir + "/")}`);
|
|
224
285
|
console.log();
|
|
225
|
-
|
|
286
|
+
const configSpinner = createSpinner("Configuring opencode.json...");
|
|
287
|
+
configSpinner.start();
|
|
226
288
|
const opencodeJson = generateOpencodeJson(targetDir, installed);
|
|
227
289
|
const jsonResult = writeFile(targetDir, "opencode.json", opencodeJson);
|
|
228
|
-
|
|
290
|
+
await sleep(500);
|
|
291
|
+
configSpinner.succeed(`${jsonResult === "created" ? "Created" : "Updated"} ${cyan("opencode.json")} with permissions & commands`);
|
|
229
292
|
console.log();
|
|
230
|
-
console.log(bold(" Done!") + " Your project is now configured.");
|
|
231
|
-
console.log();
|
|
232
|
-
console.log(dim(" What was created:"));
|
|
233
293
|
console.log(
|
|
234
|
-
` ${
|
|
294
|
+
` ${bold(green("\u2714 Setup complete!"))}`
|
|
235
295
|
);
|
|
236
|
-
|
|
296
|
+
console.log();
|
|
297
|
+
console.log(dim(" \u2500\u2500\u2500 Files Created \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
298
|
+
console.log();
|
|
299
|
+
console.log(` ${cyan("\u{1F4C1} .agents/skills/")}`);
|
|
300
|
+
console.log(` ${dim("\u251C\u2500\u2500")} ${cyan("sdlc-orchestrator/")} ${dim("\u2190 master routing skill")}`);
|
|
301
|
+
for (let i = 0; i < AGENTS.length; i++) {
|
|
302
|
+
const agent = AGENTS[i];
|
|
303
|
+
const isLast = i === AGENTS.length - 1;
|
|
304
|
+
const prefix = isLast ? "\u2514\u2500\u2500" : "\u251C\u2500\u2500";
|
|
305
|
+
const status = installed.get(agent.id) ? green("\u25CF") : yellow("\u25CB");
|
|
237
306
|
console.log(
|
|
238
|
-
`
|
|
307
|
+
` ${dim(prefix)} ${status} ${cyan(`${agent.id}/`)} ${dim(`\u2190 ${agent.bestFor.split(",")[0].trim()}`)}`
|
|
239
308
|
);
|
|
240
309
|
}
|
|
241
|
-
console.log(
|
|
242
|
-
` ${dim("2.")} ${cyan("opencode.json")} ${dim("\u2014 permissions + /delegate commands")}`
|
|
243
|
-
);
|
|
244
310
|
console.log();
|
|
245
|
-
console.log(
|
|
246
|
-
console.log(
|
|
247
|
-
` ${dim(">")} OpenCode will automatically discover the skills and`
|
|
248
|
-
);
|
|
249
|
-
console.log(
|
|
250
|
-
` know how to delegate to each sub-agent based on task type.`
|
|
251
|
-
);
|
|
311
|
+
console.log(` ${cyan("\u{1F4C4} opencode.json")} ${dim("\u2190 permissions + /delegate commands")}`);
|
|
252
312
|
console.log();
|
|
253
|
-
console.log(
|
|
254
|
-
console.log(
|
|
255
|
-
|
|
256
|
-
);
|
|
313
|
+
console.log(dim(" \u2500\u2500\u2500 Usage \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
314
|
+
console.log();
|
|
315
|
+
console.log(` OpenCode auto-discovers skills and routes tasks to agents.`);
|
|
316
|
+
console.log();
|
|
317
|
+
console.log(` ${bold("Commands:")}`);
|
|
318
|
+
console.log(` ${cyan("/delegate")} ${dim("............")} auto-route to best agent`);
|
|
257
319
|
for (const agent of AGENTS) {
|
|
320
|
+
const pad = ".".repeat(Math.max(1, 20 - agent.id.length));
|
|
258
321
|
console.log(
|
|
259
|
-
` ${cyan(`/delegate-${agent.id}`)} ${dim(
|
|
322
|
+
` ${cyan(`/delegate-${agent.id}`)} ${dim(pad)} ${dim(agent.name)}`
|
|
260
323
|
);
|
|
261
324
|
}
|
|
262
325
|
if (missing.length > 0) {
|
|
263
326
|
console.log();
|
|
264
|
-
console.log(
|
|
327
|
+
console.log(dim(" \u2500\u2500\u2500 Install Missing CLIs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
328
|
+
console.log();
|
|
265
329
|
for (const agent of missing) {
|
|
330
|
+
console.log(` ${yellow("\u25B8")} ${bold(agent.name)}`);
|
|
266
331
|
console.log(` ${dim("$")} ${agent.installCommand}`);
|
|
332
|
+
console.log();
|
|
267
333
|
}
|
|
334
|
+
console.log(
|
|
335
|
+
dim(" Run this command again after installing to update detection.")
|
|
336
|
+
);
|
|
268
337
|
}
|
|
269
338
|
console.log();
|
|
270
339
|
}
|
|
271
340
|
main().catch((err) => {
|
|
341
|
+
process.stdout.write("\x1B[?25h");
|
|
272
342
|
console.error(red(`Error: ${err instanceof Error ? err.message : err}`));
|
|
273
343
|
process.exit(1);
|
|
274
344
|
});
|
package/package.json
CHANGED