cli-five 0.2.12 → 0.2.15
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/README.md +101 -25
- package/package.json +14 -3
- package/plugin-agents/designer.agent.md +2 -2
- package/plugin-agents/planner.agent.md +1 -1
- package/src/cli.mjs +21 -3
- package/src/commands/doctor.mjs +82 -15
- package/src/commands/init.mjs +73 -24
- package/src/steps/confirm.mjs +2 -0
- package/src/steps/detect.mjs +4 -0
- package/src/steps/interview.mjs +40 -34
- package/src/steps/platform.mjs +196 -0
- package/src/steps/scaffold.mjs +135 -34
- package/src/util/agents.mjs +63 -11
- package/src/util/models.mjs +148 -0
- package/src/util/platforms.mjs +25 -0
- package/templates/AGENTS.md.tmpl +2 -0
- package/templates/opencode/agents/coder.md +74 -0
- package/templates/opencode/agents/designer.md +65 -0
- package/templates/opencode/agents/orchestrator.md +92 -0
- package/templates/opencode/agents/planner.md +76 -0
- package/templates/opencode/agents/reviewer.md +94 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# cli-five
|
|
2
2
|
|
|
3
|
-
> **Code Like I'm Five** — scaffold a 5-agent
|
|
3
|
+
> **Code Like I'm Five** — scaffold a 5-agent AI team into any repo.
|
|
4
4
|
|
|
5
5
|
## Two ways to install
|
|
6
6
|
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
npx cli-five init
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
Interviews you, scaffolds agents + memory files + stack-specific instructions, discovers skills
|
|
13
|
+
Interviews you, lets you pick a target platform and model provider, scaffolds agents + memory files + stack-specific instructions, discovers skills, and tells you what to do next.
|
|
14
14
|
|
|
15
|
-
### Quick plugin install (personal use)
|
|
15
|
+
### Quick plugin install (personal use, Copilot only)
|
|
16
16
|
|
|
17
17
|
```
|
|
18
18
|
copilot plugin install idusortus/cli-five
|
|
@@ -20,20 +20,34 @@ copilot plugin install idusortus/cli-five
|
|
|
20
20
|
|
|
21
21
|
Installs the 5 agents to your Copilot profile. No project config, no interview — just the agents with the same autonomous contracts shipped by the scaffolded templates.
|
|
22
22
|
|
|
23
|
+
## Supported platforms
|
|
24
|
+
|
|
25
|
+
cli-five can scaffold for:
|
|
26
|
+
|
|
27
|
+
- **GitHub Copilot** — `.github/agents/*.agent.md` + `copilot-instructions.md`
|
|
28
|
+
- **OpenCode** — `.opencode/agents/*.md` + `opencode.json`
|
|
29
|
+
|
|
30
|
+
Both platforms can optionally include a **CodeGraph** MCP server and instructions.
|
|
31
|
+
|
|
32
|
+
Run `npx cli-five init` and choose your platform. If you want both, run it again in the same repo.
|
|
33
|
+
|
|
23
34
|
## What you get
|
|
24
35
|
|
|
36
|
+
### GitHub Copilot layout
|
|
37
|
+
|
|
25
38
|
```
|
|
26
39
|
your-repo/
|
|
27
40
|
├── .github/
|
|
28
41
|
│ ├── agents/ # 5 agents — Orchestrator delegates autonomously
|
|
29
|
-
│ │ ├── orchestrator.agent.md
|
|
30
|
-
│ │ ├── planner.agent.md
|
|
31
|
-
│ │ ├── coder.agent.md
|
|
32
|
-
│ │ ├── designer.agent.md
|
|
33
|
-
│ │ └── reviewer.agent.md
|
|
42
|
+
│ │ ├── orchestrator.agent.md
|
|
43
|
+
│ │ ├── planner.agent.md
|
|
44
|
+
│ │ ├── coder.agent.md
|
|
45
|
+
│ │ ├── designer.agent.md
|
|
46
|
+
│ │ └── reviewer.agent.md
|
|
34
47
|
│ ├── copilot-instructions.md # Persona + project mandates from interview
|
|
35
48
|
│ ├── instructions/ # Stack-specific coding guidelines
|
|
36
49
|
│ └── skills/ # Installed skills from awesome-copilot + skills.sh
|
|
50
|
+
├── .vscode/mcp.json # CodeGraph MCP server (optional)
|
|
37
51
|
├── AGENTS.md # Tool-agnostic project context (agents.md standard)
|
|
38
52
|
├── PROJECT.md # Long-form vision (rarely changes)
|
|
39
53
|
├── STATE.md # Cross-session status (changes constantly)
|
|
@@ -42,9 +56,31 @@ your-repo/
|
|
|
42
56
|
└── histories/ # Per-agent accumulated learnings
|
|
43
57
|
```
|
|
44
58
|
|
|
59
|
+
### OpenCode layout
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
your-repo/
|
|
63
|
+
├── .opencode/
|
|
64
|
+
│ └── agents/ # 5 agents — Orchestrator delegates autonomously
|
|
65
|
+
│ ├── orchestrator.md
|
|
66
|
+
│ ├── planner.md
|
|
67
|
+
│ ├── coder.md
|
|
68
|
+
│ ├── designer.md
|
|
69
|
+
│ └── reviewer.md
|
|
70
|
+
├── opencode.json # Project config, model defaults, CodeGraph MCP (optional)
|
|
71
|
+
├── .github/instructions/ # Stack-specific coding guidelines
|
|
72
|
+
├── .github/skills/ # Installed skills
|
|
73
|
+
├── AGENTS.md # Project rules + optional CodeGraph block
|
|
74
|
+
├── PROJECT.md
|
|
75
|
+
├── STATE.md
|
|
76
|
+
├── decisions.md
|
|
77
|
+
├── agent-diary.md
|
|
78
|
+
└── histories/
|
|
79
|
+
```
|
|
80
|
+
|
|
45
81
|
## How it works
|
|
46
82
|
|
|
47
|
-
Select the **Orchestrator** agent
|
|
83
|
+
Select the **Orchestrator** agent and describe what you want. The Orchestrator autonomously calls Planner → Coder/Designer → Reviewer without any manual handoff clicks.
|
|
48
84
|
|
|
49
85
|
```
|
|
50
86
|
User: implement from plan.md
|
|
@@ -53,13 +89,13 @@ Orchestrator → [calls Planner] → [calls Coder] → [calls Reviewer] → done
|
|
|
53
89
|
|
|
54
90
|
No buttons. No "click here to continue". Just results.
|
|
55
91
|
|
|
56
|
-
The plugin agents and scaffolded `.github/agents/*.agent.md` templates are intentionally kept in sync. The repository test suite
|
|
92
|
+
The plugin agents and scaffolded `.github/agents/*.agent.md` templates are intentionally kept in sync. The repository test suite checks that parity so the quick-install path does not quietly degrade.
|
|
57
93
|
|
|
58
94
|
## Commands
|
|
59
95
|
|
|
60
96
|
```bash
|
|
61
97
|
npx cli-five init # interview + scaffold + skill discovery
|
|
62
|
-
npx cli-five doctor # validate an existing setup
|
|
98
|
+
npx cli-five doctor # validate an existing cli-five setup
|
|
63
99
|
npx cli-five list-stacks # show detectable tech stacks
|
|
64
100
|
npx cli-five help
|
|
65
101
|
```
|
|
@@ -72,34 +108,69 @@ npx cli-five help
|
|
|
72
108
|
| `--force` | Overwrite without confirmation (use with `--yes`) |
|
|
73
109
|
| `--dry-run` | Print actions, write nothing |
|
|
74
110
|
| `--no-skills` | Skip skills.sh discovery step |
|
|
75
|
-
| `--
|
|
111
|
+
| `--no-codegraph` | Skip CodeGraph MCP + instructions |
|
|
112
|
+
| `--target <t>` | Target platform: `copilot` or `opencode` (default: `copilot`) |
|
|
113
|
+
| `--provider <p>` | Model provider: `copilot`, `opencode`, `opencode-go` (default: platform default) |
|
|
114
|
+
| `--cost-mode <m>` | Set cost mode for Copilot: `premium`, `cheap`, or `mixed` |
|
|
115
|
+
| `--doc <file>` | Read project docs to pre-fill interview (repeatable) |
|
|
76
116
|
| `--cwd <path>` | Run against a different directory |
|
|
77
117
|
|
|
78
118
|
## What `init` does
|
|
79
119
|
|
|
80
120
|
1. **Detect** — fingerprints stack (Node/TS, Python, .NET, Kotlin, Rust, Go, etc.). Brownfield-aware.
|
|
81
|
-
2. **
|
|
82
|
-
3. **
|
|
83
|
-
4. **
|
|
84
|
-
5. **
|
|
85
|
-
6. **
|
|
86
|
-
7. **
|
|
87
|
-
8. **
|
|
121
|
+
2. **Choose platform** — GitHub Copilot or OpenCode, with optional CodeGraph pairing.
|
|
122
|
+
3. **git init** — if needed. Asks first.
|
|
123
|
+
4. **Overwrite gate** — double-confirms ("Proceed?" then "R U Sure?"). Only `--force --yes` bypasses.
|
|
124
|
+
5. **Project info** — name, one-liner, stack, frameworks, goals, constraints, persona toggle.
|
|
125
|
+
6. **Model configuration** — pick a provider and optionally override each agent's model.
|
|
126
|
+
7. **Scaffold** — writes platform-specific files. Swaps `model:` per provider/selection.
|
|
127
|
+
8. **Skill discovery** — multi-source discovery from **awesome-copilot** and **skills.sh**.
|
|
128
|
+
9. **Custom instructions** — generates stack-specific `.instructions.md` files for detected languages.
|
|
129
|
+
10. **Next steps** — platform-specific instructions. No button-clicking required.
|
|
130
|
+
|
|
131
|
+
## Model providers
|
|
132
|
+
|
|
133
|
+
During `init` you can choose the model provider and optionally customize each agent's model.
|
|
88
134
|
|
|
89
|
-
|
|
135
|
+
| Provider | Platform | Example model |
|
|
136
|
+
|---|---|---|
|
|
137
|
+
| GitHub Copilot | Copilot | `Claude Sonnet 4.6 (copilot)` |
|
|
138
|
+
| OpenCode Zen | OpenCode | `opencode/gpt-5.3-codex` |
|
|
139
|
+
| OpenCode Go | OpenCode | `opencode-go/qwen3.8-max` |
|
|
140
|
+
|
|
141
|
+
`--yes` uses the provider's defaults. `--provider opencode-go --yes` skips the provider prompt.
|
|
142
|
+
|
|
143
|
+
### Copilot cost modes
|
|
90
144
|
|
|
91
145
|
| Agent | `premium` (1x–3x) | `cheap` (0x) | `mixed` |
|
|
92
146
|
|---|---|---|---|
|
|
93
147
|
| Orchestrator | Claude Sonnet 4.6 | GPT-4.1 | GPT-4.1 |
|
|
94
148
|
| Planner | Claude Opus 4.6 | GPT-4o | GPT-4o |
|
|
95
149
|
| Coder | GPT-5.3-Codex | GPT-4.1 | GPT-5.3-Codex |
|
|
96
|
-
| Designer |
|
|
97
|
-
| Reviewer | Claude
|
|
150
|
+
| Designer | Gemini 3.1 Pro (Preview) | GPT-4o | GPT-4o |
|
|
151
|
+
| Reviewer | Claude Sonnet 4.6 | GPT-5 mini | Claude Sonnet 4.6 |
|
|
98
152
|
|
|
99
153
|
Override from CLI: `npx cli-five init --cost-mode cheap`
|
|
100
|
-
Change anytime by editing the `model:` line in
|
|
154
|
+
Change anytime by editing the `model:` line in the agent files.
|
|
155
|
+
|
|
156
|
+
## CodeGraph
|
|
101
157
|
|
|
102
|
-
|
|
158
|
+
CodeGraph adds a local, graph-backed codebase context server. When enabled, cli-five:
|
|
159
|
+
|
|
160
|
+
- Registers the CodeGraph MCP server in `opencode.json` (OpenCode) or `.vscode/mcp.json` (Copilot).
|
|
161
|
+
- Adds a marker-fenced CodeGraph section to `AGENTS.md`.
|
|
162
|
+
- Tells you to run `codegraph init` to index the project.
|
|
163
|
+
|
|
164
|
+
cli-five does **not** install or run the CodeGraph CLI automatically. After scaffolding:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
npm i -g @colbymchenry/codegraph
|
|
168
|
+
codegraph init
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Required settings
|
|
172
|
+
|
|
173
|
+
### GitHub Copilot
|
|
103
174
|
|
|
104
175
|
```jsonc
|
|
105
176
|
{
|
|
@@ -107,6 +178,10 @@ Change anytime by editing the `model:` line in `.github/agents/*.agent.md`.
|
|
|
107
178
|
}
|
|
108
179
|
```
|
|
109
180
|
|
|
181
|
+
### OpenCode
|
|
182
|
+
|
|
183
|
+
No extra settings required. Project agents live in `.opencode/agents/` and the project config in `opencode.json`.
|
|
184
|
+
|
|
110
185
|
## Skill discovery
|
|
111
186
|
|
|
112
187
|
cli-five searches **two sources** for skills matching your detected stack:
|
|
@@ -127,7 +202,7 @@ Take time to read each installed skill so you understand what it does and can ca
|
|
|
127
202
|
## What this is not
|
|
128
203
|
|
|
129
204
|
- **Not a runtime.** Once scaffolded, your repo doesn't depend on `cli-five`. You can uninstall the package and the agents still work.
|
|
130
|
-
- **Not a workflow engine.** No `/plan-phase`, no `/ship`, no 50 slash commands. Use `/agent-customization` in Copilot Chat to extend.
|
|
205
|
+
- **Not a workflow engine.** No `/plan-phase`, no `/ship`, no 50 slash commands. Use `/agent-customization` in Copilot Chat or OpenCode commands to extend.
|
|
131
206
|
- **Not Ralph.** No issue-polling daemons, no autonomous loops, no crypto tokens.
|
|
132
207
|
|
|
133
208
|
## Why the name
|
|
@@ -144,6 +219,7 @@ ELI5 → CLI5. Code Like I'm Five. Five agents. Get it? Yeah, it's a stretch. Bu
|
|
|
144
219
|
|
|
145
220
|
- The plugin install path and the scaffolded project path are both supported and now validated against each other.
|
|
146
221
|
- `npm test` includes agent integrity checks in addition to the existing skill-step tests.
|
|
222
|
+
- Google Antigravity AGY CLI support is planned but not implemented yet.
|
|
147
223
|
|
|
148
224
|
## Local development
|
|
149
225
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cli-five",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "Code Like I'm Five — scaffold a 5-agent
|
|
3
|
+
"version": "0.2.15",
|
|
4
|
+
"description": "Code Like I'm Five — scaffold a 5-agent AI team (GitHub Copilot or OpenCode) into any repo.",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/idusortus/cli-five.git"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/idusortus/cli-five#readme",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/idusortus/cli-five/issues"
|
|
13
|
+
},
|
|
6
14
|
"bin": {
|
|
7
15
|
"cli-five": "bin/cli-five.mjs"
|
|
8
16
|
},
|
|
@@ -24,6 +32,8 @@
|
|
|
24
32
|
},
|
|
25
33
|
"keywords": [
|
|
26
34
|
"copilot",
|
|
35
|
+
"opencode",
|
|
36
|
+
"codegraph",
|
|
27
37
|
"vscode",
|
|
28
38
|
"agents",
|
|
29
39
|
"scaffold",
|
|
@@ -33,6 +43,7 @@
|
|
|
33
43
|
"dependencies": {
|
|
34
44
|
"kleur": "^4.1.5",
|
|
35
45
|
"prompts": "^2.4.2",
|
|
36
|
-
"skills": "^1.5.0"
|
|
46
|
+
"skills": "^1.5.0",
|
|
47
|
+
"yaml": "^2.8.3"
|
|
37
48
|
}
|
|
38
49
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: Designer
|
|
3
3
|
description: "Handles all UI/UX design tasks. Use when: creating screens, layouts, theming, navigation flows, design systems."
|
|
4
|
-
model:
|
|
4
|
+
model: Gemini 3.1 Pro (Preview) (copilot)
|
|
5
5
|
tools: ['read', 'edit', 'search', 'web', 'io.github.upstash/context7/*', 'vscode/memory']
|
|
6
6
|
agents: []
|
|
7
7
|
---
|
|
@@ -10,7 +10,7 @@ agents: []
|
|
|
10
10
|
|
|
11
11
|
| Mode | Model | Premium Cost |
|
|
12
12
|
|---|---|---|
|
|
13
|
-
| **Default** |
|
|
13
|
+
| **Default** | Gemini 3.1 Pro (Preview) (copilot) | 1x |
|
|
14
14
|
| **Cheap** | GPT-4o | 0x (free) |
|
|
15
15
|
|
|
16
16
|
To switch: change the `model` key in frontmatter above.
|
|
@@ -13,7 +13,7 @@ You create plans. You do NOT write code.
|
|
|
13
13
|
|
|
14
14
|
| Mode | Model | Premium Cost |
|
|
15
15
|
|---|---|---|
|
|
16
|
-
| **Default** | Claude
|
|
16
|
+
| **Default** | Claude Opus 4.6 | 3x |
|
|
17
17
|
| **Cheap** | GPT-4o | 0x (free) |
|
|
18
18
|
|
|
19
19
|
To switch: change the `model` key in frontmatter above.
|
package/src/cli.mjs
CHANGED
|
@@ -8,13 +8,13 @@ import { listStacks } from './commands/list-stacks.mjs';
|
|
|
8
8
|
import { STACK_SIGNATURES } from './steps/detect.mjs';
|
|
9
9
|
|
|
10
10
|
const HELP = `${kleur.bold('cli-five')} ${kleur.gray('— Code Like I\'m Five')}
|
|
11
|
-
Scaffold a 5-agent
|
|
11
|
+
Scaffold a 5-agent AI team into any repo.
|
|
12
12
|
|
|
13
13
|
${kleur.bold('Usage')}
|
|
14
14
|
npx cli-five <command> [options]
|
|
15
15
|
|
|
16
16
|
${kleur.bold('Commands')}
|
|
17
|
-
init Interview + scaffold
|
|
17
|
+
init Interview + scaffold agents + project memory files
|
|
18
18
|
doctor Validate an existing cli-five setup
|
|
19
19
|
list-stacks Show detectable tech stacks
|
|
20
20
|
help Show this message
|
|
@@ -26,6 +26,9 @@ ${kleur.bold('Flags')}
|
|
|
26
26
|
--no-skills Skip the skills.sh discovery step
|
|
27
27
|
--doc <file> Read project docs to pre-fill interview (repeatable)
|
|
28
28
|
--cost-mode <m> Override cost mode (premium, cheap, mixed) — skips interview question
|
|
29
|
+
--target <t> Target platform: copilot or opencode (default: copilot)
|
|
30
|
+
--provider <p> Model provider: copilot, opencode, opencode-go (default: platform default)
|
|
31
|
+
--no-codegraph Skip CodeGraph MCP + instructions
|
|
29
32
|
--cwd <path> Run against a directory other than the current one
|
|
30
33
|
--version, -v Print version and exit
|
|
31
34
|
`;
|
|
@@ -60,15 +63,30 @@ export async function run(argv) {
|
|
|
60
63
|
}
|
|
61
64
|
|
|
62
65
|
function parse(argv) {
|
|
63
|
-
const out = {
|
|
66
|
+
const out = {
|
|
67
|
+
_: [],
|
|
68
|
+
yes: false,
|
|
69
|
+
force: false,
|
|
70
|
+
dryRun: false,
|
|
71
|
+
skills: true,
|
|
72
|
+
codegraph: true,
|
|
73
|
+
docs: [],
|
|
74
|
+
costMode: null,
|
|
75
|
+
target: null,
|
|
76
|
+
provider: null,
|
|
77
|
+
cwd: process.cwd(),
|
|
78
|
+
};
|
|
64
79
|
for (let i = 0; i < argv.length; i++) {
|
|
65
80
|
const a = argv[i];
|
|
66
81
|
if (a === '--yes' || a === '-y') out.yes = true;
|
|
67
82
|
else if (a === '--force') out.force = true;
|
|
68
83
|
else if (a === '--dry-run') out.dryRun = true;
|
|
69
84
|
else if (a === '--no-skills') out.skills = false;
|
|
85
|
+
else if (a === '--no-codegraph') out.codegraph = false;
|
|
70
86
|
else if (a === '--doc') out.docs.push(argv[++i]);
|
|
71
87
|
else if (a === '--cost-mode') out.costMode = argv[++i];
|
|
88
|
+
else if (a === '--target') out.target = argv[++i];
|
|
89
|
+
else if (a === '--provider') out.provider = argv[++i];
|
|
72
90
|
else if (a === '--cwd') out.cwd = argv[++i];
|
|
73
91
|
else if (a === '--help' || a === '-h') out._.push('help');
|
|
74
92
|
else if (a === '--version' || a === '-v') out._.push('--version');
|
package/src/commands/doctor.mjs
CHANGED
|
@@ -2,9 +2,15 @@ import { existsSync, readFileSync } from 'node:fs';
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import kleur from 'kleur';
|
|
4
4
|
import { log } from '../util/log.mjs';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
AGENT_FILES,
|
|
7
|
+
OPENCODE_AGENT_FILES,
|
|
8
|
+
validateAgentSource,
|
|
9
|
+
validateOpenCodeAgentSource,
|
|
10
|
+
} from '../util/agents.mjs';
|
|
11
|
+
import { PLATFORM_COPILOT, PLATFORM_OPENCODE } from '../util/platforms.mjs';
|
|
6
12
|
|
|
7
|
-
const
|
|
13
|
+
const COPILOT_REQUIRED = [
|
|
8
14
|
'.github/copilot-instructions.md',
|
|
9
15
|
'.github/agents/orchestrator.agent.md',
|
|
10
16
|
'.github/agents/planner.agent.md',
|
|
@@ -17,6 +23,19 @@ const REQUIRED = [
|
|
|
17
23
|
'agent-diary.md',
|
|
18
24
|
];
|
|
19
25
|
|
|
26
|
+
const OPENCODE_REQUIRED = [
|
|
27
|
+
'opencode.json',
|
|
28
|
+
'.opencode/agents/orchestrator.md',
|
|
29
|
+
'.opencode/agents/planner.md',
|
|
30
|
+
'.opencode/agents/coder.md',
|
|
31
|
+
'.opencode/agents/designer.md',
|
|
32
|
+
'.opencode/agents/reviewer.md',
|
|
33
|
+
'PROJECT.md',
|
|
34
|
+
'STATE.md',
|
|
35
|
+
'decisions.md',
|
|
36
|
+
'agent-diary.md',
|
|
37
|
+
];
|
|
38
|
+
|
|
20
39
|
const OPTIONAL = [
|
|
21
40
|
'.github/instructions',
|
|
22
41
|
'.github/skills',
|
|
@@ -26,11 +45,15 @@ const OPTIONAL = [
|
|
|
26
45
|
|
|
27
46
|
export async function doctor(args) {
|
|
28
47
|
const cwd = args.cwd;
|
|
48
|
+
const platform = detectPlatform(cwd);
|
|
29
49
|
log.raw(kleur.bold().magenta('\ncli-five doctor') + kleur.gray(` ${cwd}`));
|
|
50
|
+
log.info(`Detected platform: ${kleur.bold(platform)}`);
|
|
30
51
|
let fail = 0;
|
|
31
52
|
|
|
53
|
+
const required = platform === PLATFORM_OPENCODE ? OPENCODE_REQUIRED : COPILOT_REQUIRED;
|
|
54
|
+
|
|
32
55
|
log.step('Required');
|
|
33
|
-
for (const p of
|
|
56
|
+
for (const p of required) {
|
|
34
57
|
const ok = existsSync(join(cwd, p));
|
|
35
58
|
if (ok) log.ok(p);
|
|
36
59
|
else {
|
|
@@ -40,22 +63,60 @@ export async function doctor(args) {
|
|
|
40
63
|
}
|
|
41
64
|
|
|
42
65
|
log.step('Agent integrity');
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
66
|
+
if (platform === PLATFORM_OPENCODE) {
|
|
67
|
+
for (const file of OPENCODE_AGENT_FILES) {
|
|
68
|
+
const relPath = join('.opencode', 'agents', file);
|
|
69
|
+
const fullPath = join(cwd, relPath);
|
|
70
|
+
if (!existsSync(fullPath)) continue;
|
|
47
71
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
72
|
+
const errors = validateOpenCodeAgentSource(readFileSync(fullPath, 'utf8'), file);
|
|
73
|
+
if (errors.length === 0) {
|
|
74
|
+
log.ok(relPath);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
log.err(relPath);
|
|
79
|
+
for (const error of errors) {
|
|
80
|
+
log.raw(kleur.red(` - ${error}`));
|
|
81
|
+
}
|
|
82
|
+
fail++;
|
|
52
83
|
}
|
|
84
|
+
} else {
|
|
85
|
+
for (const file of AGENT_FILES) {
|
|
86
|
+
const relPath = join('.github', 'agents', file);
|
|
87
|
+
const fullPath = join(cwd, relPath);
|
|
88
|
+
if (!existsSync(fullPath)) continue;
|
|
89
|
+
|
|
90
|
+
const errors = validateAgentSource(readFileSync(fullPath, 'utf8'), file);
|
|
91
|
+
if (errors.length === 0) {
|
|
92
|
+
log.ok(relPath);
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
log.err(relPath);
|
|
97
|
+
for (const error of errors) {
|
|
98
|
+
log.raw(kleur.red(` - ${error}`));
|
|
99
|
+
}
|
|
100
|
+
fail++;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
53
103
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
104
|
+
if (platform === PLATFORM_OPENCODE) {
|
|
105
|
+
log.step('OpenCode config');
|
|
106
|
+
const opencodePath = join(cwd, 'opencode.json');
|
|
107
|
+
if (existsSync(opencodePath)) {
|
|
108
|
+
try {
|
|
109
|
+
const cfg = JSON.parse(readFileSync(opencodePath, 'utf8'));
|
|
110
|
+
if (cfg.mcp?.codegraph) {
|
|
111
|
+
log.ok('opencode.json has CodeGraph MCP entry');
|
|
112
|
+
} else {
|
|
113
|
+
log.warn('opencode.json missing CodeGraph MCP entry (ok if CodeGraph disabled)');
|
|
114
|
+
}
|
|
115
|
+
} catch (err) {
|
|
116
|
+
log.err(`opencode.json is not valid JSON: ${err.message}`);
|
|
117
|
+
fail++;
|
|
118
|
+
}
|
|
57
119
|
}
|
|
58
|
-
fail++;
|
|
59
120
|
}
|
|
60
121
|
|
|
61
122
|
log.step('Optional');
|
|
@@ -72,3 +133,9 @@ export async function doctor(args) {
|
|
|
72
133
|
process.exit(1);
|
|
73
134
|
}
|
|
74
135
|
}
|
|
136
|
+
|
|
137
|
+
function detectPlatform(cwd) {
|
|
138
|
+
if (existsSync(join(cwd, '.opencode', 'agents'))) return PLATFORM_OPENCODE;
|
|
139
|
+
if (existsSync(join(cwd, '.github', 'agents', 'orchestrator.agent.md'))) return PLATFORM_COPILOT;
|
|
140
|
+
return PLATFORM_COPILOT;
|
|
141
|
+
}
|
package/src/commands/init.mjs
CHANGED
|
@@ -9,21 +9,30 @@ import { interview } from '../steps/interview.mjs';
|
|
|
9
9
|
import { scaffold, summarize } from '../steps/scaffold.mjs';
|
|
10
10
|
import { skillDiscovery } from '../steps/skills.mjs';
|
|
11
11
|
import { instructionGeneration } from '../steps/instructions.mjs';
|
|
12
|
+
import { choosePlatform, chooseModels } from '../steps/platform.mjs';
|
|
12
13
|
import { isGitRepo, gitInit } from '../util/git.mjs';
|
|
14
|
+
import { platformLabel } from '../util/platforms.mjs';
|
|
13
15
|
|
|
14
16
|
export async function init(args) {
|
|
15
17
|
const cwd = args.cwd;
|
|
16
18
|
log.raw(kleur.bold().magenta('\ncli-five init') + kleur.gray(` ${cwd}`));
|
|
17
19
|
|
|
18
20
|
// 1. Detect
|
|
19
|
-
log.step('1/
|
|
21
|
+
log.step('1/8 Detect workspace');
|
|
20
22
|
const detected = detect(cwd);
|
|
21
23
|
log.info(`Project: ${kleur.bold(detected.projectName)}`);
|
|
22
24
|
log.info(`Mode: ${detected.isBrownfield ? kleur.yellow('brownfield') : kleur.green('greenfield')}`);
|
|
23
25
|
if (detected.stacks.length) log.info(`Stack: ${detected.stacks.map((s) => s.label).join(', ')}`);
|
|
24
26
|
if (!detected.hasGit) log.warn('Not a git repository.');
|
|
25
27
|
|
|
26
|
-
// 2.
|
|
28
|
+
// 2. Platform + CodeGraph
|
|
29
|
+
log.step('2/8 Choose platform');
|
|
30
|
+
const { platform, codegraph } = await choosePlatform(args);
|
|
31
|
+
log.info(`Target: ${kleur.bold(platformLabel(platform))}`);
|
|
32
|
+
if (codegraph) log.info(`CodeGraph: ${kleur.green('enabled')}`);
|
|
33
|
+
else log.info('CodeGraph: disabled');
|
|
34
|
+
|
|
35
|
+
// 3. git init if needed
|
|
27
36
|
if (!detected.hasGit) {
|
|
28
37
|
if (args.yes || (await ask('Run `git init`?', true))) {
|
|
29
38
|
gitInit(cwd);
|
|
@@ -33,8 +42,8 @@ export async function init(args) {
|
|
|
33
42
|
}
|
|
34
43
|
}
|
|
35
44
|
|
|
36
|
-
//
|
|
37
|
-
log.step('
|
|
45
|
+
// 4. Overwrite gate
|
|
46
|
+
log.step('3/8 Confirm overwrites');
|
|
38
47
|
const ok = await confirmOverwriteIfNeeded(detected, args);
|
|
39
48
|
if (!ok) {
|
|
40
49
|
log.warn('Aborted. Nothing written.');
|
|
@@ -42,8 +51,8 @@ export async function init(args) {
|
|
|
42
51
|
}
|
|
43
52
|
if (!detected.hasAgents && !detected.hasCopilotInstructions) log.dim('No collisions.');
|
|
44
53
|
|
|
45
|
-
//
|
|
46
|
-
log.step('
|
|
54
|
+
// 5. Input mode — docs or manual interview
|
|
55
|
+
log.step('4/8 Project info');
|
|
47
56
|
let docHints;
|
|
48
57
|
|
|
49
58
|
if (args.docs.length > 0) {
|
|
@@ -64,7 +73,15 @@ export async function init(args) {
|
|
|
64
73
|
if (docHints.oneLiner) log.dim(` → description: ${docHints.oneLiner}`);
|
|
65
74
|
}
|
|
66
75
|
|
|
67
|
-
//
|
|
76
|
+
// 6. Model configuration
|
|
77
|
+
log.step('5/8 Model configuration');
|
|
78
|
+
const modelConfig = await chooseModels(platform, args);
|
|
79
|
+
log.info(`Provider: ${kleur.bold(modelConfig.provider)}`);
|
|
80
|
+
if (modelConfig.customized) log.info('Models: customized');
|
|
81
|
+
else log.info('Models: defaults');
|
|
82
|
+
|
|
83
|
+
// 7. Interview (pre-filled from docs if available, otherwise manual)
|
|
84
|
+
args.__platform = platform;
|
|
68
85
|
const answers = await interview(detected, args, docHints);
|
|
69
86
|
|
|
70
87
|
// CLI --cost-mode override
|
|
@@ -72,24 +89,31 @@ export async function init(args) {
|
|
|
72
89
|
answers.costMode = args.costMode;
|
|
73
90
|
}
|
|
74
91
|
|
|
92
|
+
// Attach platform/model choices to answers so scaffold can use them.
|
|
93
|
+
answers.platform = platform;
|
|
94
|
+
answers.codegraph = codegraph;
|
|
95
|
+
answers.provider = modelConfig.provider;
|
|
96
|
+
answers.modelMap = modelConfig.modelMap;
|
|
97
|
+
answers.customizedModels = modelConfig.customized;
|
|
98
|
+
|
|
75
99
|
if (answers.presetId && answers.presetId !== 'custom') {
|
|
76
100
|
log.info(`Preset: ${answers.presetId}`);
|
|
77
101
|
}
|
|
78
102
|
if (answers.frameworks.length) log.info(`Stack: ${answers.stack.join(', ')} + ${answers.frameworks.join(', ')}`);
|
|
79
103
|
|
|
80
|
-
//
|
|
81
|
-
log.step('
|
|
104
|
+
// 8. Scaffold
|
|
105
|
+
log.step('6/8 Scaffold');
|
|
82
106
|
const written = scaffold({ cwd, answers, args });
|
|
83
107
|
if (args.dryRun) log.warn('--dry-run: no files written. Plan:');
|
|
84
108
|
log.raw(summarize(written, cwd));
|
|
85
109
|
if (!args.dryRun) log.ok(`Wrote ${written.length} files.`);
|
|
86
110
|
|
|
87
|
-
//
|
|
88
|
-
log.step('
|
|
111
|
+
// 9. Skill discovery
|
|
112
|
+
log.step('7/8 Skill discovery');
|
|
89
113
|
await skillDiscovery({ cwd, answers, args });
|
|
90
114
|
|
|
91
|
-
//
|
|
92
|
-
log.step('
|
|
115
|
+
// 10. Custom instructions
|
|
116
|
+
log.step('8/8 Custom instructions');
|
|
93
117
|
const instrWritten = await instructionGeneration({ cwd, answers, args });
|
|
94
118
|
if (instrWritten && instrWritten.length > 0) {
|
|
95
119
|
if (args.dryRun) log.warn('--dry-run: instruction plan:');
|
|
@@ -99,7 +123,7 @@ export async function init(args) {
|
|
|
99
123
|
if (!args.dryRun) log.ok(`Wrote ${instrWritten.length} instruction file${instrWritten.length > 1 ? 's' : ''}.`);
|
|
100
124
|
}
|
|
101
125
|
|
|
102
|
-
//
|
|
126
|
+
// 11. Next steps
|
|
103
127
|
printNextSteps(answers);
|
|
104
128
|
}
|
|
105
129
|
|
|
@@ -110,15 +134,29 @@ async function ask(message, initial = false) {
|
|
|
110
134
|
|
|
111
135
|
function printNextSteps(answers) {
|
|
112
136
|
const hasDocs = answers.docFiles?.length > 0;
|
|
137
|
+
const platform = answers.platform || 'copilot';
|
|
138
|
+
const codegraph = answers.codegraph;
|
|
113
139
|
|
|
114
140
|
log.raw('');
|
|
115
141
|
log.raw(kleur.bold().green('Done. Next steps:'));
|
|
116
142
|
log.raw('');
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
143
|
+
|
|
144
|
+
if (platform === 'opencode') {
|
|
145
|
+
log.raw(` 1. Install the CodeGraph CLI if you haven't:`);
|
|
146
|
+
log.raw(kleur.gray(` npm i -g @colbymchenry/codegraph`));
|
|
147
|
+
log.raw(` 2. Index this project with CodeGraph:`);
|
|
148
|
+
log.raw(kleur.gray(` codegraph init`));
|
|
149
|
+
log.raw(` 3. Run OpenCode from this directory:`);
|
|
150
|
+
log.raw(kleur.gray(` opencode`));
|
|
151
|
+
log.raw(` 4. Select ${kleur.bold('Orchestrator')} and describe what you want built.`);
|
|
152
|
+
} else {
|
|
153
|
+
log.raw(` 1. Open this folder in VS Code Insiders.`);
|
|
154
|
+
log.raw(` 2. Enable Copilot subagent invocations (settings.json):`);
|
|
155
|
+
log.raw(kleur.gray(` "chat.subagents.allowInvocationsFromSubagents": true`));
|
|
156
|
+
log.raw(` 3. Open Copilot Chat — select an agent from the dropdown (${kleur.bold('not')} @mention).`);
|
|
157
|
+
log.raw(` 4. Select ${kleur.bold('Orchestrator')} — it routes tasks autonomously to Planner, Coder, Designer, and Reviewer.`);
|
|
158
|
+
}
|
|
159
|
+
|
|
122
160
|
log.raw(` 5. ${hasDocs ? 'Kickoff prompt (paste this into Orchestrator):' : 'Start building:'}`);
|
|
123
161
|
if (hasDocs) {
|
|
124
162
|
const docList = answers.docFiles.join(', ');
|
|
@@ -129,11 +167,22 @@ function printNextSteps(answers) {
|
|
|
129
167
|
}
|
|
130
168
|
log.raw(` 6. Review generated instruction files in .github/instructions/.`);
|
|
131
169
|
log.raw(kleur.gray(` Edit applyTo globs and guidelines to fit your project.`));
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
170
|
+
|
|
171
|
+
if (codegraph) {
|
|
172
|
+
log.raw('');
|
|
173
|
+
log.raw(kleur.dim(' CodeGraph is configured. Remember to run `codegraph init` before asking agents to explore the codebase.'));
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (platform === 'copilot') {
|
|
177
|
+
log.raw('');
|
|
178
|
+
log.raw(kleur.dim(' Quick plugin install (personal, no project config):'));
|
|
179
|
+
log.raw(kleur.dim(' copilot plugin install idusortus/cli-five'));
|
|
180
|
+
log.raw('');
|
|
181
|
+
log.raw(kleur.dim('Edit cost mode anytime by changing `model:` in .github/agents/*.agent.md.'));
|
|
182
|
+
} else {
|
|
183
|
+
log.raw('');
|
|
184
|
+
log.raw(kleur.dim('Edit agent models anytime by changing `model:` in .opencode/agents/*.md.'));
|
|
185
|
+
}
|
|
137
186
|
log.raw('');
|
|
138
187
|
}
|
|
139
188
|
|
package/src/steps/confirm.mjs
CHANGED
|
@@ -34,5 +34,7 @@ function collideList(detected) {
|
|
|
34
34
|
const out = [];
|
|
35
35
|
if (detected.hasAgents) out.push('.github/agents/');
|
|
36
36
|
if (detected.hasCopilotInstructions) out.push('.github/copilot-instructions.md');
|
|
37
|
+
if (detected.hasOpencodeAgents) out.push('.opencode/agents/');
|
|
38
|
+
if (detected.hasOpencodeConfig) out.push('opencode.json');
|
|
37
39
|
return out;
|
|
38
40
|
}
|