cli-five 0.1.5 → 0.2.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/README.md CHANGED
@@ -2,21 +2,38 @@
2
2
 
3
3
  > **Code Like I'm Five** — scaffold a 5-agent VS Code Copilot team into any repo.
4
4
 
5
+ ## Two ways to install
6
+
7
+ ### Full setup (recommended for teams)
8
+
5
9
  ```bash
6
10
  npx cli-five init
7
11
  ```
8
12
 
9
- That's it. Run it in any folder. It interviews you, scaffolds `.github/agents/` + project memory files, searches skills.sh for relevant skills, and tells you what to do next.
13
+ Interviews you, scaffolds agents + memory files + stack-specific instructions, discovers skills from **awesome-copilot** and **skills.sh**, and tells you what to do next.
14
+
15
+ ### Quick plugin install (personal use)
16
+
17
+ ```
18
+ copilot plugin install idusortus/cli-five
19
+ ```
20
+
21
+ Installs the 5 agents to your Copilot profile. No project config, no interview — just the agents with sensible defaults.
10
22
 
11
23
  ## What you get
12
24
 
13
25
  ```
14
26
  your-repo/
15
27
  ├── .github/
16
- │ ├── agents/ # 5 agents: Orchestrator, Planner, Coder, Designer, Reviewer
28
+ │ ├── agents/ # 5 agents with handoffs + subagent delegation
29
+ │ │ ├── orchestrator.agent.md # 📋 Plan 💻 Code 🎨 Design 🔍 Review
30
+ │ │ ├── planner.agent.md # 🎯 Execute 💻 Code Directly
31
+ │ │ ├── coder.agent.md # 🔍 Review 🎯 Back to Orchestrator
32
+ │ │ ├── designer.agent.md # 🔍 Review 🎯 Back to Orchestrator
33
+ │ │ └── reviewer.agent.md # 🎯 Back to Orchestrator 💻 Fix Issues
17
34
  │ ├── copilot-instructions.md # Persona + project mandates from interview
18
- │ ├── instructions/ # Empty — populate via /agent-customization in chat
19
- │ └── skills/ # Empty — populate via skills.sh
35
+ │ ├── instructions/ # Stack-specific coding guidelines
36
+ │ └── skills/ # Installed skills from awesome-copilot + skills.sh
20
37
  ├── AGENTS.md # Tool-agnostic project context (agents.md standard)
21
38
  ├── PROJECT.md # Long-form vision (rarely changes)
22
39
  ├── STATE.md # Cross-session status (changes constantly)
@@ -25,6 +42,15 @@ your-repo/
25
42
  └── histories/ # Per-agent accumulated learnings
26
43
  ```
27
44
 
45
+ ## Orchestration modes
46
+
47
+ The Orchestrator supports **both** delegation patterns:
48
+
49
+ - **Handoff buttons** — Click `📋 Plan`, `💻 Code`, `🎨 Design`, or `🔍 Review` to manually transition between agents with pre-filled context.
50
+ - **Subagent delegation** — Ask the Orchestrator to handle a complex task and it calls Planner → Coder → Reviewer autonomously.
51
+
52
+ Each specialist also has handoffs: Coder/Designer → Reviewer, Reviewer → Coder (fix loop), and everyone → back to Orchestrator.
53
+
28
54
  ## Commands
29
55
 
30
56
  ```bash
@@ -51,9 +77,10 @@ npx cli-five help
51
77
  2. **git init** — if needed. Asks first.
52
78
  3. **Overwrite gate** — double-confirms ("Proceed?" then "R U Sure?"). Only `--force --yes` bypasses.
53
79
  4. **Interview** — name, one-liner, stack, frameworks, goals, constraints, cost mode, persona toggle.
54
- 5. **Scaffold** — writes 18 files. Substitutes answers into templates. Swaps `model:` per cost mode.
55
- 6. **Skill discovery** — queries skills.sh via `npx skills find <term>` per detected stack. Recommends known-good skills, offers multiselect install, and launches interactive browser.
56
- 7. **Next steps** — tells you to run `/agent-customization` for stack-specific instructions.
80
+ 5. **Scaffold** — writes 18 files. Substitutes answers into templates. Swaps `model:` per cost mode. Adds `handoffs:` to all agents.
81
+ 6. **Skill discovery** — the hero feature. Multi-source discovery from **awesome-copilot** (30k+ ★ community marketplace) and **skills.sh**. Color-coded recommendations, source attribution, multiselect install, and post-install breadcrumbs with copy-paste commands for the awesome-copilot suggestion skill and MCP server.
82
+ 7. **Custom instructions** — generates stack-specific `.instructions.md` files for detected languages.
83
+ 8. **Next steps** — tells you to use handoff buttons or autonomous mode, offers plugin install shortcut.
57
84
 
58
85
  ## Cost modes
59
86
 
@@ -76,6 +103,21 @@ Change anytime by editing the `model:` line in `.github/agents/*.agent.md`.
76
103
  }
77
104
  ```
78
105
 
106
+ ## Skill discovery
107
+
108
+ cli-five searches **two sources** for skills matching your detected stack:
109
+
110
+ | Source | What it has | Stars |
111
+ |---|---|---|
112
+ | **awesome-copilot** | Skills, instructions, agents, plugins from the GitHub community | 30k+ |
113
+ | **skills.sh** | Curated skill repos (Vercel, Anthropic, Microsoft, etc.) | — |
114
+
115
+ Recommendations show with source attribution and are pre-selected for one-click install. After installation, you get breadcrumbs for ongoing discovery:
116
+
117
+ - **Suggest skill** — `copilot plugin install awesome-copilot@suggest` (AI-driven repo analysis)
118
+ - **MCP server** — `awesome-copilot-mcp` for programmatic search from any agent
119
+ - **CLI browser** — `npx skills find` for interactive search
120
+
79
121
  ## What this is not
80
122
 
81
123
  - **Not a runtime.** Once scaffolded, your repo doesn't depend on `cli-five`. You can uninstall the package and the agents still work.
@@ -95,8 +137,8 @@ ELI5 → CLI5. Code Like I'm Five. Five agents. Get it? Yeah, it's a stretch. Bu
95
137
  ## Local development
96
138
 
97
139
  ```bash
98
- git clone https://github.com/idusortus/squad-mine
99
- cd squad-mine
140
+ git clone https://github.com/idusortus/cli-five
141
+ cd cli-five
100
142
  npm install
101
143
  node bin/cli-five.mjs init --cwd /tmp/test-target
102
144
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cli-five",
3
- "version": "0.1.5",
3
+ "version": "0.2.1",
4
4
  "description": "Code Like I'm Five — scaffold a 5-agent VS Code Copilot team into any repo.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -10,6 +10,8 @@
10
10
  "bin",
11
11
  "src",
12
12
  "templates",
13
+ "plugin-agents",
14
+ "plugin.json",
13
15
  "README.md",
14
16
  "LICENSE"
15
17
  ],
@@ -0,0 +1,33 @@
1
+ ---
2
+ name: Coder
3
+ description: "Writes production code following workspace conventions. Use when: implementing features, fixing bugs, writing tests."
4
+ model: GPT-5.3-Codex (copilot)
5
+ tools: ['vscode', 'execute', 'read', 'github/*', 'edit', 'search', 'web', 'vscode/memory', 'todo']
6
+ agents: []
7
+ handoffs:
8
+ - label: "🔍 Review"
9
+ agent: Reviewer
10
+ prompt: "Review the changes I just made for correctness and conventions."
11
+ send: false
12
+ - label: "🎯 Back to Orchestrator"
13
+ agent: Orchestrator
14
+ prompt: "Implementation complete. Coordinate next steps."
15
+ send: false
16
+ ---
17
+
18
+ ## Mandatory Coding Principles
19
+
20
+ 1. **Structure** — Consistent layout. Group by feature. Shared patterns over duplication.
21
+ 2. **Architecture** — Flat, explicit code. No clever patterns or unnecessary indirection.
22
+ 3. **Functions** — Linear control flow. Small-to-medium functions. Pass state explicitly.
23
+ 4. **Naming** — Descriptive-but-simple names. Comment only for invariants or assumptions.
24
+ 5. **Logging** — Detailed, structured logs at key boundaries. Explicit errors.
25
+ 6. **Regenerability** — Any file can be rewritten from scratch without breaking the system.
26
+ 7. **Platform** — Use framework conventions directly and simply.
27
+ 8. **Quality** — Deterministic, testable behavior. Simple, focused tests.
28
+
29
+ ## Rules
30
+
31
+ - Follow existing patterns in the codebase
32
+ - Your final message MUST list every file created or modified
33
+ - Include build/test status if you ran them
@@ -0,0 +1,29 @@
1
+ ---
2
+ name: Designer
3
+ description: "Handles all UI/UX design tasks. Use when: creating screens, layouts, theming, navigation flows, design systems."
4
+ model: Claude Opus 4.6 (copilot)
5
+ tools: ['read', 'edit', 'search', 'web', 'vscode/memory']
6
+ agents: []
7
+ handoffs:
8
+ - label: "🔍 Review"
9
+ agent: Reviewer
10
+ prompt: "Review the UI changes for accessibility, conventions, and design quality."
11
+ send: false
12
+ - label: "🎯 Back to Orchestrator"
13
+ agent: Orchestrator
14
+ prompt: "Design work complete. Coordinate next steps."
15
+ send: false
16
+ ---
17
+
18
+ ## Design Principles
19
+
20
+ - Accessibility first: contrast ratios, touch targets, screen reader support
21
+ - Minimal cognitive load
22
+ - Platform conventions over custom patterns
23
+ - Responsive/adaptive layouts
24
+ - Use the project's designated design system and component library
25
+
26
+ ## Rules
27
+
28
+ - Your final message MUST list every UI file created or modified
29
+ - Include design decisions and accessibility choices applied
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: Orchestrator
3
+ description: "Coordinates multi-agent workflows. Delegates to Planner, Coder, Designer, and Reviewer. Use when: complex multi-step tasks, cross-cutting changes, feature implementation."
4
+ model: Claude Sonnet 4.6 (copilot)
5
+ tools: ['read/readFile', 'agent', 'vscode/memory', 'github/*']
6
+ agents: ['Planner', 'Coder', 'Designer', 'Reviewer']
7
+ handoffs:
8
+ - label: "📋 Plan"
9
+ agent: Planner
10
+ prompt: "Research the codebase and create an implementation plan for this task."
11
+ send: false
12
+ - label: "💻 Code"
13
+ agent: Coder
14
+ prompt: "Implement the approved plan."
15
+ send: false
16
+ - label: "🎨 Design"
17
+ agent: Designer
18
+ prompt: "Design the UI components described in the plan."
19
+ send: false
20
+ - label: "🔍 Review"
21
+ agent: Reviewer
22
+ prompt: "Review the implementation for correctness, conventions, and architecture."
23
+ send: false
24
+ ---
25
+
26
+ You are a project orchestrator. You break down complex requests into tasks and delegate to specialist subagents. You coordinate work but NEVER implement anything yourself.
27
+
28
+ ## Agents
29
+
30
+ | Agent | Role |
31
+ |---|---|
32
+ | **Planner** | Research codebase, check docs, create implementation plans |
33
+ | **Coder** | Write code, fix bugs, implement features |
34
+ | **Designer** | UI/UX design, layouts, theming |
35
+ | **Reviewer** | Review agent output for correctness and conventions |
36
+
37
+ ## Execution Model
38
+
39
+ 1. **Get the Plan** — Call Planner unless a plan is already in context or the task is trivial.
40
+ 2. **Parse Into Phases** — Group non-overlapping files into parallel phases. Dependencies go sequential.
41
+ 3. **Execute Each Phase** — Call appropriate agents. Never assign overlapping files to parallel tasks.
42
+ 4. **Review (MANDATORY)** — Call Reviewer. Max 2 fix-review rounds.
43
+ 5. **Report** — Summarize what was completed and the review verdict.
44
+
45
+ ## Rules
46
+
47
+ - Delegate WHAT (outcomes), never HOW (implementation details).
48
+ - Never assign overlapping files to agents in the same phase.
49
+ - Never implement anything yourself — you are a router, not a worker.
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: Planner
3
+ description: "Creates implementation plans by researching the codebase, consulting documentation, and identifying edge cases."
4
+ model: Claude Opus 4.6 (copilot)
5
+ tools: ['read', 'search', 'web', 'vscode/memory']
6
+ user-invocable: false
7
+ handoffs:
8
+ - label: "🎯 Execute Plan"
9
+ agent: Orchestrator
10
+ prompt: "Plan is ready. Execute it phase by phase."
11
+ send: false
12
+ - label: "💻 Code Directly"
13
+ agent: Coder
14
+ prompt: "Implement this plan."
15
+ send: false
16
+ ---
17
+
18
+ # Planning Agent
19
+
20
+ You create plans. You do NOT write code.
21
+
22
+ ## Workflow
23
+
24
+ 1. **Research**: Search the codebase thoroughly. Read relevant files. Find existing patterns.
25
+ 2. **Verify**: Use web tools to check documentation for libraries/APIs involved.
26
+ 3. **Consider**: Identify edge cases, error states, and implicit requirements.
27
+ 4. **Plan**: Output WHAT needs to happen, not HOW to code it.
28
+
29
+ ## Output Format
30
+
31
+ - **Summary** (one paragraph)
32
+ - **Implementation steps** (ordered), each with file assignments and dependencies
33
+ - **Edge cases** to handle
34
+ - **Open questions** (if any)
35
+ - **Suggested phase grouping** (which steps can be parallelized)
36
+
37
+ ## Rules
38
+
39
+ - Never skip documentation checks for external APIs
40
+ - Note uncertainties — don't hide them
41
+ - Match existing codebase patterns
@@ -0,0 +1,52 @@
1
+ ---
2
+ name: Reviewer
3
+ description: "Reviews code and agent output for correctness, convention compliance, and architectural alignment."
4
+ model: Claude Opus 4.6 (copilot)
5
+ tools: ['read', 'search', 'web', 'vscode/memory']
6
+ agents: []
7
+ user-invocable: true
8
+ handoffs:
9
+ - label: "🎯 Back to Orchestrator"
10
+ agent: Orchestrator
11
+ prompt: "Review complete. See verdict above. Coordinate fixes or proceed."
12
+ send: false
13
+ - label: "💻 Fix Issues"
14
+ agent: Coder
15
+ prompt: "Fix the issues identified in the review above."
16
+ send: false
17
+ ---
18
+
19
+ ## Identity
20
+
21
+ You are a code reviewer. You do NOT write code, fix things, or make changes. You READ, SEARCH, JUDGE, and REPORT.
22
+
23
+ ## Review Checklist
24
+
25
+ 1. **Workspace instructions** — Verify compliance with `.github/instructions/`
26
+ 2. **Architecture docs** — Verify component placement and boundaries
27
+ 3. **General quality** — OWASP Top 10, no leaked secrets, error handling, testability
28
+
29
+ ## Review Output Format
30
+
31
+ ```
32
+ ## Review Summary
33
+ **Verdict:** PASS | PASS WITH NOTES | NEEDS CHANGES | REJECT
34
+
35
+ ### Critical (must fix)
36
+ - [ ] Finding with file reference and line number
37
+
38
+ ### Warnings (should fix)
39
+ - [ ] Finding with file reference and line number
40
+
41
+ ### Notes
42
+ - Observations and suggestions
43
+
44
+ ### What was done well
45
+ - Positive observations
46
+ ```
47
+
48
+ ## Rules
49
+
50
+ - NEVER approve code you haven't read
51
+ - Be specific: file path, line number, what's wrong, what should change
52
+ - If the code is good, say so. Don't invent problems.
package/plugin.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "cli-five",
3
+ "description": "5-agent orchestration squad for GitHub Copilot — Orchestrator, Planner, Coder, Designer, Reviewer.",
4
+ "version": "0.2.0",
5
+ "author": {
6
+ "name": "idusortus"
7
+ },
8
+ "agents": "plugin-agents/",
9
+ "repository": "https://github.com/idusortus/cli-five"
10
+ }
@@ -49,6 +49,11 @@ export async function init(args) {
49
49
  answers.costMode = args.costMode;
50
50
  }
51
51
 
52
+ if (answers.presetId && answers.presetId !== 'custom') {
53
+ log.info(`Preset: ${answers.presetId}`);
54
+ }
55
+ if (answers.frameworks.length) log.info(`Stack: ${answers.stack.join(', ')} + ${answers.frameworks.join(', ')}`);
56
+
52
57
  // 5. Scaffold
53
58
  log.step('4/6 Scaffold');
54
59
  const written = scaffold({ cwd, answers, args });
@@ -88,11 +93,15 @@ function printNextSteps(answers) {
88
93
  log.raw(` 2. Enable Copilot subagent invocations (settings.json):`);
89
94
  log.raw(kleur.gray(` "chat.subagents.allowInvocationsFromSubagents": true`));
90
95
  log.raw(` 3. Open Copilot Chat — select an agent from the dropdown (${kleur.bold('not')} @mention).`);
91
- log.raw(` 4. Select ${kleur.bold('Orchestrator')} from the dropdown, then ask:`);
92
- log.raw(kleur.gray(` read PROJECT.md and propose Phase 1.`));
93
- log.raw(` 5. Review generated instruction files in .github/instructions/.`);
96
+ log.raw(` 4. Select ${kleur.bold('Orchestrator')} — use handoff buttons or ask it to delegate:`);
97
+ log.raw(kleur.gray(` 📋 Plan 💻 Code 🎨 Design 🔍 Review`));
98
+ log.raw(` 5. Or go autonomous:`);
99
+ log.raw(kleur.gray(` read PROJECT.md and implement Phase 1.`));
100
+ log.raw(` 6. Review generated instruction files in .github/instructions/.`);
94
101
  log.raw(kleur.gray(` Edit applyTo globs and guidelines to fit your project.`));
95
- log.raw(kleur.gray(` Installed skills are in .agents/skills/ (from skills.sh).`));
102
+ log.raw('');
103
+ log.raw(kleur.dim(' Quick plugin install (personal, no project config):'));
104
+ log.raw(kleur.dim(' copilot plugin install idusortus/cli-five'));
96
105
  log.raw('');
97
106
  log.raw(kleur.dim('Edit cost mode anytime by changing `model:` in .github/agents/*.agent.md.'));
98
107
  log.raw('');
@@ -1,5 +1,69 @@
1
1
  import prompts from 'prompts';
2
2
 
3
+ // ── Preset stacks ─────────────────────────────────────────────────────
4
+ // Chosen for: LLM familiarity, low setup friction, minimal config,
5
+ // copy-paste quickstart, broad hosting support.
6
+ // Research via Context7: Next.js, Vite+React, Express, Hono all score
7
+ // 80+ benchmark with high snippet counts and well-indexed docs.
8
+ const STACK_PRESETS = [
9
+ {
10
+ title: 'Next.js (TypeScript)',
11
+ value: 'nextjs',
12
+ description: 'Full-stack React. App Router, TypeScript, Tailwind. `npx create-next-app`',
13
+ stack: ['Node + TypeScript'],
14
+ frameworks: ['Next.js', 'React', 'Tailwind CSS'],
15
+ quickstart: 'npx create-next-app@latest . --yes && npm run dev',
16
+ },
17
+ {
18
+ title: 'Vite + React (TypeScript)',
19
+ value: 'vite-react',
20
+ description: 'SPA frontend. Lightning-fast HMR. `npm create vite`',
21
+ stack: ['Node + TypeScript'],
22
+ frameworks: ['Vite', 'React', 'TypeScript'],
23
+ quickstart: 'npm create vite@latest . -- --template react-ts && npm i && npm run dev',
24
+ },
25
+ {
26
+ title: 'Express API (TypeScript)',
27
+ value: 'express',
28
+ description: 'REST API server. Minimal, well-known, huge ecosystem.',
29
+ stack: ['Node + TypeScript'],
30
+ frameworks: ['Express', 'TypeScript'],
31
+ quickstart: 'npm init -y && npm i express typescript tsx @types/express && npx tsx src/index.ts',
32
+ },
33
+ {
34
+ title: 'Hono API (TypeScript)',
35
+ value: 'hono',
36
+ description: 'Ultrafast, Web Standards. Works on Node, Bun, Deno, Cloudflare.',
37
+ stack: ['Node + TypeScript'],
38
+ frameworks: ['Hono', 'TypeScript'],
39
+ quickstart: 'npm create hono@latest . && npm i && npm run dev',
40
+ },
41
+ {
42
+ title: 'Vite + Vue (TypeScript)',
43
+ value: 'vite-vue',
44
+ description: 'SPA frontend with Vue 3 + Composition API.',
45
+ stack: ['Node + TypeScript'],
46
+ frameworks: ['Vite', 'Vue', 'TypeScript'],
47
+ quickstart: 'npm create vite@latest . -- --template vue-ts && npm i && npm run dev',
48
+ },
49
+ {
50
+ title: 'Python + FastAPI',
51
+ value: 'fastapi',
52
+ description: 'Modern Python API with type hints and auto-docs.',
53
+ stack: ['Python'],
54
+ frameworks: ['FastAPI', 'Pydantic', 'Uvicorn'],
55
+ quickstart: 'pip install fastapi uvicorn && uvicorn main:app --reload',
56
+ },
57
+ {
58
+ title: 'Custom (freeform)',
59
+ value: 'custom',
60
+ description: 'Enter your own stack and frameworks manually.',
61
+ stack: [],
62
+ frameworks: [],
63
+ quickstart: '',
64
+ },
65
+ ];
66
+
3
67
  const COST_MODES = [
4
68
  { title: 'Premium (default)', value: 'premium', description: 'Sonnet/Opus/Codex. Best quality, real cost.' },
5
69
  { title: 'Cheap (0x)', value: 'cheap', description: 'GPT-4.1 / GPT-4o / GPT-5 mini. Free tier-friendly.' },
@@ -13,7 +77,8 @@ export async function interview(detected, args) {
13
77
  throw new Error('Interview cancelled. Nothing was written.');
14
78
  };
15
79
 
16
- const answers = await prompts(
80
+ // ── Basic info ────────────────────────────────────────────────────
81
+ const basic = await prompts(
17
82
  [
18
83
  {
19
84
  type: 'text',
@@ -27,20 +92,61 @@ export async function interview(detected, args) {
27
92
  message: 'One-line description (becomes PROJECT.md vision)',
28
93
  initial: '',
29
94
  },
30
- {
31
- type: 'list',
32
- name: 'stack',
33
- message: 'Tech stack (comma separated)',
34
- initial: detected.stacks.map((s) => s.label).join(', '),
35
- separator: ',',
36
- },
37
- {
38
- type: 'list',
39
- name: 'frameworks',
40
- message: 'Frameworks / key libraries (comma separated, optional)',
41
- initial: '',
42
- separator: ',',
43
- },
95
+ ],
96
+ { onCancel },
97
+ );
98
+
99
+ // ── Stack preset or freeform ──────────────────────────────────────
100
+ // If detection already found a stack, show it as initial hint
101
+ const detectedLabel = detected.stacks.map((s) => s.label).join(', ');
102
+
103
+ const { preset } = await prompts(
104
+ {
105
+ type: 'select',
106
+ name: 'preset',
107
+ message: detectedLabel
108
+ ? `Stack preset (detected: ${detectedLabel})`
109
+ : 'Stack preset — pick one or go freeform',
110
+ choices: STACK_PRESETS,
111
+ initial: 0,
112
+ },
113
+ { onCancel },
114
+ );
115
+
116
+ let stackAnswers;
117
+ const chosenPreset = STACK_PRESETS.find((p) => p.value === preset);
118
+
119
+ if (preset === 'custom') {
120
+ // Freeform: user types whatever they want
121
+ stackAnswers = await prompts(
122
+ [
123
+ {
124
+ type: 'list',
125
+ name: 'stack',
126
+ message: 'Tech stack (comma separated)',
127
+ initial: detectedLabel,
128
+ separator: ',',
129
+ },
130
+ {
131
+ type: 'list',
132
+ name: 'frameworks',
133
+ message: 'Frameworks / key libraries (comma separated)',
134
+ initial: '',
135
+ separator: ',',
136
+ },
137
+ ],
138
+ { onCancel },
139
+ );
140
+ } else {
141
+ stackAnswers = {
142
+ stack: chosenPreset.stack,
143
+ frameworks: chosenPreset.frameworks,
144
+ };
145
+ }
146
+
147
+ // ── Remaining questions ───────────────────────────────────────────
148
+ const rest = await prompts(
149
+ [
44
150
  {
45
151
  type: 'text',
46
152
  name: 'goals',
@@ -68,19 +174,31 @@ export async function interview(detected, args) {
68
174
  { onCancel },
69
175
  );
70
176
 
71
- return normalize({ ...defaults(detected), ...answers });
177
+ return normalize({
178
+ ...defaults(detected),
179
+ ...basic,
180
+ ...stackAnswers,
181
+ ...rest,
182
+ presetId: preset,
183
+ quickstart: chosenPreset?.quickstart || '',
184
+ });
72
185
  }
73
186
 
187
+ /** Default stack is Next.js + TypeScript when nothing detected and --yes. */
74
188
  function defaults(detected) {
189
+ const hasDetected = detected.stacks.length > 0;
190
+ const fallback = STACK_PRESETS[0]; // Next.js (TypeScript)
75
191
  return {
76
192
  projectName: detected.projectName,
77
193
  oneLiner: '',
78
- stack: detected.stacks.map((s) => s.label),
79
- frameworks: [],
194
+ stack: hasDetected ? detected.stacks.map((s) => s.label) : fallback.stack,
195
+ frameworks: hasDetected ? [] : fallback.frameworks,
80
196
  goals: '',
81
197
  constraints: '',
82
198
  costMode: 'premium',
83
199
  snark: true,
200
+ presetId: hasDetected ? 'custom' : fallback.value,
201
+ quickstart: hasDetected ? '' : fallback.quickstart,
84
202
  };
85
203
  }
86
204
 
@@ -94,6 +94,7 @@ function buildVars(a) {
94
94
  FRAMEWORKS: a.frameworks.length ? a.frameworks.join(', ') : 'None declared.',
95
95
  GOALS: a.goals || 'TODO — declare the primary goal.',
96
96
  CONSTRAINTS: a.constraints || 'None declared.',
97
+ QUICKSTART: a.quickstart || 'TODO — add install + run commands here.',
97
98
  COST_MODE: a.costMode,
98
99
  DATE: new Date().toISOString().slice(0, 10),
99
100
  PERSONA_BLOCK: a.snark ? PERSONA_BLOCK : '',
@@ -1,11 +1,43 @@
1
1
  import prompts from 'prompts';
2
+ import kleur from 'kleur';
2
3
  import { spawn, execFileSync } from 'node:child_process';
3
4
  import { existsSync, mkdirSync, readdirSync, renameSync, rmSync } from 'node:fs';
4
5
  import { join, dirname } from 'node:path';
5
6
  import { createRequire } from 'node:module';
6
7
  import { log } from '../util/log.mjs';
7
8
 
8
- // Well-known skill repos matched by stack term → repo + suggested skill names
9
+ // ── Awesome-copilot catalog (github/awesome-copilot) ──────────────────
10
+ // Curated subset mapped by stack term → { name, description, type }
11
+ const AWESOME_CATALOG = [
12
+ // Universal
13
+ { terms: ['*'], name: 'frontend-design', desc: 'Production-grade UI design', type: 'skill', source: 'awesome-copilot' },
14
+ { terms: ['*'], name: 'conventional-commit', desc: 'Commit message standards', type: 'skill', source: 'awesome-copilot' },
15
+ { terms: ['*'], name: 'documentation-writer', desc: 'Generate project docs', type: 'skill', source: 'awesome-copilot' },
16
+ { terms: ['*'], name: 'mermaid-diagrams', desc: 'Create software diagrams', type: 'skill', source: 'awesome-copilot' },
17
+ // JavaScript / TypeScript / React / Next
18
+ { terms: ['node', 'typescript', 'javascript'], name: 'typescript', desc: 'TypeScript best practices', type: 'instruction', source: 'awesome-copilot' },
19
+ { terms: ['react', 'next'], name: 'reactjs', desc: 'React patterns & conventions', type: 'instruction', source: 'awesome-copilot' },
20
+ { terms: ['next'], name: 'nextjs', desc: 'Next.js patterns', type: 'instruction', source: 'awesome-copilot' },
21
+ { terms: ['node', 'typescript', 'react', 'next'], name: 'playwright-tester', desc: 'E2E testing with Playwright', type: 'skill', source: 'awesome-copilot' },
22
+ // Python
23
+ { terms: ['python', 'django', 'flask', 'fastapi'], name: 'python', desc: 'Python best practices', type: 'instruction', source: 'awesome-copilot' },
24
+ { terms: ['django'], name: 'django', desc: 'Django conventions', type: 'instruction', source: 'awesome-copilot' },
25
+ { terms: ['fastapi'], name: 'fastapi', desc: 'FastAPI patterns', type: 'instruction', source: 'awesome-copilot' },
26
+ // .NET
27
+ { terms: ['dotnet', '.net', 'csharp', 'c#'], name: 'dotnet', desc: '.NET conventions', type: 'instruction', source: 'awesome-copilot' },
28
+ // Rust
29
+ { terms: ['rust'], name: 'rust', desc: 'Rust best practices', type: 'instruction', source: 'awesome-copilot' },
30
+ // Go
31
+ { terms: ['go', 'golang'], name: 'go', desc: 'Go conventions', type: 'instruction', source: 'awesome-copilot' },
32
+ // Mobile
33
+ { terms: ['swift', 'ios'], name: 'swift', desc: 'Swift/iOS patterns', type: 'instruction', source: 'awesome-copilot' },
34
+ { terms: ['kotlin', 'android'], name: 'kotlin', desc: 'Kotlin/Android patterns', type: 'instruction', source: 'awesome-copilot' },
35
+ // DevOps / Infra
36
+ { terms: ['docker', 'kubernetes', 'devops'], name: 'docker', desc: 'Docker best practices', type: 'instruction', source: 'awesome-copilot' },
37
+ { terms: ['terraform'], name: 'terraform', desc: 'Terraform conventions', type: 'instruction', source: 'awesome-copilot' },
38
+ ];
39
+
40
+ // Well-known skill repos matched by stack term → repo + suggested skill names (skills.sh)
9
41
  const SKILL_CATALOG = [
10
42
  { terms: ['*'], repo: 'anthropics/skills', skills: ['frontend-design', 'skill-creator'] },
11
43
  { terms: ['*'], repo: 'vercel-labs/agent-skills', skills: ['vercel-react-best-practices', 'web-design-guidelines'] },
@@ -109,6 +141,8 @@ export async function skillDiscovery({ cwd, answers, args }) {
109
141
  if (!env) {
110
142
  log.warn('Cannot run skills CLI: no bundled binary, pnpm, or npx found.');
111
143
  log.warn('Install Node.js (includes npx) or pnpm, then re-run.');
144
+ // Still show awesome-copilot recs (they don't need skills CLI)
145
+ await showAwesomeCopilotOnly(answers);
112
146
  return;
113
147
  }
114
148
 
@@ -133,71 +167,132 @@ export async function skillDiscovery({ cwd, answers, args }) {
133
167
  log.ok(`Running skills via ${env.label}`);
134
168
  log.raw('');
135
169
 
136
- // ── Skill discovery ─────────────────────────────────────────────────
137
-
138
- // 1. Build recommendations from catalog based on stack
139
- const recs = buildRecommendations(answers);
140
- if (recs.length === 0) {
141
- log.dim('No stack-specific recommendations found.');
142
- } else {
143
- log.raw(` ${pad('Skill', 36)} ${pad('Repo', 36)}`);
144
- log.raw(` ${'─'.repeat(36)} ${'─'.repeat(36)}`);
145
- for (const r of recs) {
146
- log.raw(` ${pad(r.skill, 36)} ${pad(r.repo, 36)}`);
147
- }
148
- log.raw('');
149
- }
170
+ // ── Build recommendations from BOTH sources ─────────────────────────
171
+ const awesomeRecs = buildAwesomeRecommendations(answers);
172
+ const skillsShRecs = buildRecommendations(answers);
150
173
 
151
- // 2. Offer interactive search per stack term
174
+ // ── Display hero section ────────────────────────────────────────────
175
+ displayHeroRecommendations(awesomeRecs, skillsShRecs, answers);
176
+
177
+ // ── Combined picker ─────────────────────────────────────────────────
152
178
  const terms = suggestSearches(answers);
179
+
180
+ // Search skills.sh for additional results
181
+ const allFound = [];
153
182
  if (terms.length > 0) {
154
183
  log.dim(`Suggested searches: ${terms.map((t) => `"${t}"`).join(', ')}`);
155
184
  log.raw('');
185
+
186
+ for (const term of terms) {
187
+ const { go } = await prompts({
188
+ type: 'confirm',
189
+ name: 'go',
190
+ message: `Search skills.sh for "${term}"?`,
191
+ initial: true,
192
+ });
193
+ if (go) {
194
+ const output = await runSkillsCapture(env, ['find', term], cwd);
195
+ allFound.push(...parseSkillRefs(output));
196
+ }
197
+ }
156
198
  }
157
199
 
158
- for (const term of terms) {
159
- const { go } = await prompts({
160
- type: 'confirm',
161
- name: 'go',
162
- message: `Search skills.sh for "${term}"?`,
163
- initial: true,
200
+ // Build combined skill picker — awesome recs + catalog recs + search results
201
+ const seen = new Set();
202
+ const choices = [];
203
+
204
+ // Awesome-copilot recs first (hero placement)
205
+ for (const r of awesomeRecs) {
206
+ const key = `awesome:${r.name}`;
207
+ if (seen.has(key)) continue;
208
+ seen.add(key);
209
+ choices.push({
210
+ title: `${kleur.cyan('⬡')} ${r.name} ${kleur.dim(`(${r.desc})`)} ${kleur.cyan('← awesome-copilot')}`,
211
+ value: { source: 'awesome', name: r.name, type: r.type },
212
+ selected: true,
213
+ });
214
+ }
215
+
216
+ // skills.sh catalog recs
217
+ for (const r of skillsShRecs) {
218
+ const ref = `${r.repo}@${r.skill}`;
219
+ if (seen.has(ref)) continue;
220
+ seen.add(ref);
221
+ choices.push({
222
+ title: `${kleur.yellow('◆')} ${r.skill} ${kleur.dim(`(${r.repo})`)} ${kleur.yellow('← skills.sh')}`,
223
+ value: { source: 'skillssh', ref, repo: r.repo, skill: r.skill },
224
+ selected: true,
225
+ });
226
+ }
227
+
228
+ // skills.sh search results
229
+ for (const r of allFound) {
230
+ if (seen.has(r.ref)) continue;
231
+ seen.add(r.ref);
232
+ choices.push({
233
+ title: `${kleur.yellow('◆')} ${r.ref} ${kleur.dim(`— ${r.installs}`)} ${kleur.yellow('← skills.sh')}`,
234
+ value: { source: 'skillssh', ref: r.ref },
235
+ selected: false,
164
236
  });
165
- if (go) {
166
- await runSkills(env, ['find', term], cwd);
167
- }
168
237
  }
169
238
 
170
- // 3. Offer to install from well-known repos
171
- if (recs.length > 0) {
172
- const { install } = await prompts({
239
+ if (choices.length > 0) {
240
+ log.raw('');
241
+ const { toInstall } = await prompts({
173
242
  type: 'multiselect',
174
- name: 'install',
175
- message: 'Install recommended skills?',
176
- choices: recs.map((r) => ({
177
- title: `${r.skill} (${r.repo})`,
178
- value: r,
179
- selected: false,
180
- })),
181
- hint: 'Space to select, Enter to confirm',
243
+ name: 'toInstall',
244
+ message: 'Select skills to install',
245
+ choices,
246
+ hint: 'Space to toggle, Enter to confirm',
182
247
  });
183
248
 
184
- if (install && install.length > 0) {
185
- const byRepo = new Map();
186
- for (const r of install) {
187
- if (!byRepo.has(r.repo)) byRepo.set(r.repo, []);
188
- byRepo.get(r.repo).push(r.skill);
249
+ if (toInstall && toInstall.length > 0) {
250
+ // Separate awesome-copilot entries from skills.sh entries
251
+ const awesomeItems = toInstall.filter((i) => i.source === 'awesome');
252
+ const skillsShItems = toInstall.filter((i) => i.source === 'skillssh');
253
+
254
+ // Install awesome-copilot skills/instructions via npx skills (they're in the registry too)
255
+ if (awesomeItems.length > 0) {
256
+ log.raw('');
257
+ log.info(`${kleur.cyan('awesome-copilot')} resources selected: ${awesomeItems.map((i) => i.name).join(', ')}`);
258
+ log.dim('These will be installed via skills CLI from the awesome-copilot registry.');
259
+ for (const item of awesomeItems) {
260
+ log.info(`Installing ${item.name} (${item.type})...`);
261
+ await runSkills(env, ['add', `awesome-copilot@${item.name}`, '-a', 'github-copilot'], cwd);
262
+ }
189
263
  }
190
- for (const [repo, skills] of byRepo) {
191
- const skillArgs = skills.flatMap((s) => ['--skill', s]);
192
- log.info(`Installing from ${repo}: ${skills.join(', ')}`);
193
- await runSkills(env, ['add', repo, ...skillArgs, '-a', 'github-copilot'], cwd);
264
+
265
+ // Install skills.sh entries
266
+ if (skillsShItems.length > 0) {
267
+ const byRepo = new Map();
268
+ const standalone = [];
269
+
270
+ for (const item of skillsShItems) {
271
+ if (item.repo) {
272
+ if (!byRepo.has(item.repo)) byRepo.set(item.repo, []);
273
+ byRepo.get(item.repo).push(item.skill);
274
+ } else {
275
+ standalone.push(item.ref);
276
+ }
277
+ }
278
+
279
+ for (const [repo, skills] of byRepo) {
280
+ const skillArgs = skills.flatMap((s) => ['--skill', s]);
281
+ log.info(`Installing from ${repo}: ${skills.join(', ')}`);
282
+ await runSkills(env, ['add', repo, ...skillArgs, '-a', 'github-copilot'], cwd);
283
+ }
284
+
285
+ for (const ref of standalone) {
286
+ log.info(`Installing ${ref}...`);
287
+ await runSkills(env, ['add', ref, '-a', 'github-copilot'], cwd);
288
+ }
194
289
  }
195
290
 
196
291
  await relocateSkills(cwd);
197
292
  }
198
293
  }
199
294
 
200
- // 4. Offer freeform catch-all
295
+ // Offer freeform catch-all
201
296
  const { freeform } = await prompts({
202
297
  type: 'confirm',
203
298
  name: 'freeform',
@@ -209,7 +304,100 @@ export async function skillDiscovery({ cwd, answers, args }) {
209
304
  await relocateSkills(cwd);
210
305
  }
211
306
 
212
- log.dim('Done. Run `npx skills find` anytime to discover more.');
307
+ // ── Post-install breadcrumbs (THE HERO FINISH) ──────────────────────
308
+ printBreadcrumbs();
309
+ }
310
+
311
+ // ── Hero display ──────────────────────────────────────────────────────
312
+
313
+ function displayHeroRecommendations(awesomeRecs, skillsShRecs, answers) {
314
+ const stackLabel = [...(answers.stack || []), ...(answers.frameworks || [])].join(', ') || 'general';
315
+
316
+ log.raw('');
317
+ log.raw(kleur.bold().cyan(' ╔══════════════════════════════════════════════════════════════════╗'));
318
+ log.raw(kleur.bold().cyan(' ║') + kleur.bold(' 📦 RECOMMENDED FOR YOUR STACK: ') + kleur.bold().white(stackLabel) + pad('', Math.max(0, 30 - stackLabel.length)) + kleur.bold().cyan(' ║'));
319
+ log.raw(kleur.bold().cyan(' ╚══════════════════════════════════════════════════════════════════╝'));
320
+
321
+ if (awesomeRecs.length > 0) {
322
+ log.raw('');
323
+ log.raw(kleur.cyan(' ⬡ Source: awesome-copilot') + kleur.dim(' (github/awesome-copilot · 30k+ ★)'));
324
+ log.raw(kleur.dim(' ─────────────────────────────────────────────────────────'));
325
+ for (const r of awesomeRecs) {
326
+ const typeTag = kleur.dim(`[${r.type}]`);
327
+ log.raw(` ${kleur.green('✓')} ${pad(r.name, 28)} ${pad(r.desc, 32)} ${typeTag}`);
328
+ }
329
+ }
330
+
331
+ if (skillsShRecs.length > 0) {
332
+ log.raw('');
333
+ log.raw(kleur.yellow(' ◆ Source: skills.sh') + kleur.dim(' (skills.sh registry)'));
334
+ log.raw(kleur.dim(' ─────────────────────────────────────────────────────────'));
335
+ for (const r of skillsShRecs) {
336
+ log.raw(` ${kleur.green('✓')} ${pad(r.skill, 28)} ${kleur.dim(r.repo)}`);
337
+ }
338
+ }
339
+
340
+ log.raw('');
341
+ }
342
+
343
+ /** Fallback when skills CLI is unavailable — show awesome-copilot recs as copy-paste commands */
344
+ async function showAwesomeCopilotOnly(answers) {
345
+ const recs = buildAwesomeRecommendations(answers);
346
+ if (recs.length === 0) return;
347
+
348
+ log.raw('');
349
+ log.info('Cannot install skills automatically, but here are recommendations:');
350
+ displayHeroRecommendations(recs, [], answers);
351
+ log.raw(kleur.dim(' Install manually in VS Code Chat:'));
352
+ for (const r of recs) {
353
+ log.raw(` ${kleur.white(`copilot plugin install awesome-copilot@${r.name}`)}`);
354
+ }
355
+ log.raw('');
356
+ printBreadcrumbs();
357
+ }
358
+
359
+ // ── Post-install breadcrumbs ──────────────────────────────────────────
360
+
361
+ function printBreadcrumbs() {
362
+ log.raw('');
363
+ log.raw(kleur.bold().green(' ┌──────────────────────────────────────────────────────────────────┐'));
364
+ log.raw(kleur.bold().green(' │') + kleur.bold(' 🎯 KEEP DISCOVERING — paste into VS Code / Copilot Chat: ') + kleur.bold().green('│'));
365
+ log.raw(kleur.bold().green(' ├──────────────────────────────────────────────────────────────────┤'));
366
+ log.raw(kleur.bold().green(' │') + ' ' + kleur.bold().green('│'));
367
+ log.raw(kleur.bold().green(' │') + ' Install the awesome-copilot suggestion skill: ' + kleur.bold().green('│'));
368
+ log.raw(kleur.bold().green(' │') + kleur.white(' copilot plugin install awesome-copilot@suggest ') + kleur.bold().green('│'));
369
+ log.raw(kleur.bold().green(' │') + ' ' + kleur.bold().green('│'));
370
+ log.raw(kleur.bold().green(' │') + ' Add awesome-copilot MCP for ongoing search: ' + kleur.bold().green('│'));
371
+ log.raw(kleur.bold().green(' │') + kleur.white(' Add to .vscode/mcp.json: ') + kleur.bold().green('│'));
372
+ log.raw(kleur.bold().green(' │') + kleur.dim(' "awesome-copilot": { ') + kleur.bold().green('│'));
373
+ log.raw(kleur.bold().green(' │') + kleur.dim(' "command": "npx", ') + kleur.bold().green('│'));
374
+ log.raw(kleur.bold().green(' │') + kleur.dim(' "args": ["-y", "awesome-copilot-mcp"] ') + kleur.bold().green('│'));
375
+ log.raw(kleur.bold().green(' │') + kleur.dim(' } ') + kleur.bold().green('│'));
376
+ log.raw(kleur.bold().green(' │') + ' ' + kleur.bold().green('│'));
377
+ log.raw(kleur.bold().green(' │') + ' Browse skills anytime: ' + kleur.bold().green('│'));
378
+ log.raw(kleur.bold().green(' │') + kleur.white(' npx skills find ') + kleur.bold().green('│'));
379
+ log.raw(kleur.bold().green(' │') + ' ' + kleur.bold().green('│'));
380
+ log.raw(kleur.bold().green(' └──────────────────────────────────────────────────────────────────┘'));
381
+ log.raw('');
382
+ }
383
+
384
+ // ── Awesome-copilot recommendation builder ────────────────────────────
385
+
386
+ function buildAwesomeRecommendations(a) {
387
+ const stackLower = (a.stack || []).map((s) => s.toLowerCase());
388
+ const fwLower = (a.frameworks || []).map((f) => f.toLowerCase());
389
+ const all = [...stackLower, ...fwLower];
390
+ const seen = new Set();
391
+ const out = [];
392
+
393
+ for (const entry of AWESOME_CATALOG) {
394
+ const matches = entry.terms.includes('*') || entry.terms.some((t) => all.some((s) => s.includes(t)));
395
+ if (!matches) continue;
396
+ if (seen.has(entry.name)) continue;
397
+ seen.add(entry.name);
398
+ out.push({ name: entry.name, desc: entry.desc, type: entry.type, source: entry.source });
399
+ }
400
+ return out;
213
401
  }
214
402
 
215
403
  // ── Relocation ─────────────────────────────────────────────────────────
@@ -330,3 +518,44 @@ function runInteractive(cmd, args, cwd) {
330
518
  });
331
519
  });
332
520
  }
521
+
522
+ /** Run skills CLI, capture stdout/stderr while echoing to the terminal. */
523
+ function runSkillsCapture(env, skillsArgs, cwd) {
524
+ const { cmd, args } = env.runner(skillsArgs);
525
+ return new Promise((resolve) => {
526
+ let output = '';
527
+ const proc = spawn(cmd, args, { cwd, stdio: ['inherit', 'pipe', 'pipe'] });
528
+ proc.stdout.on('data', (chunk) => {
529
+ const text = chunk.toString();
530
+ process.stdout.write(text);
531
+ output += text;
532
+ });
533
+ proc.stderr.on('data', (chunk) => {
534
+ const text = chunk.toString();
535
+ process.stderr.write(text);
536
+ output += text;
537
+ });
538
+ proc.on('exit', () => resolve(output));
539
+ proc.on('error', (err) => {
540
+ log.warn(`Could not launch \`${cmd} ${args.join(' ')}\`: ${err.message}`);
541
+ resolve('');
542
+ });
543
+ });
544
+ }
545
+
546
+ function stripAnsi(str) {
547
+ // eslint-disable-next-line no-control-regex
548
+ return str.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, '');
549
+ }
550
+
551
+ /** Extract owner/repo@skill refs from `skills find <term>` output. */
552
+ function parseSkillRefs(output) {
553
+ const clean = stripAnsi(output);
554
+ const regex = /^(\S+\/\S+@\S+)\s+(.+?installs)/gm;
555
+ const results = [];
556
+ let match;
557
+ while ((match = regex.exec(clean))) {
558
+ results.push({ ref: match[1], installs: match[2].trim() });
559
+ }
560
+ return results;
561
+ }
@@ -4,6 +4,15 @@ description: "Writes production code following workspace conventions. Use when:
4
4
  model: GPT-5.3-Codex (copilot)
5
5
  tools: ['vscode', 'execute', 'read', 'io.github.upstash/context7/*', 'github/*', 'edit', 'search', 'web', 'vscode/memory', 'todo']
6
6
  agents: []
7
+ handoffs:
8
+ - label: "🔍 Review"
9
+ agent: Reviewer
10
+ prompt: "Review the changes I just made for correctness and conventions."
11
+ send: false
12
+ - label: "🎯 Back to Orchestrator"
13
+ agent: Orchestrator
14
+ prompt: "Implementation complete. Coordinate next steps."
15
+ send: false
7
16
  ---
8
17
 
9
18
  ## Model Selection
@@ -54,6 +63,10 @@ Before writing code, read (if they exist):
54
63
 
55
64
  Before finishing, if any implementation choice was made (library selection, pattern choice, API approach), append an entry to `decisions.md` using the format in that file. Skip silently if no decisions were made.
56
65
 
66
+ ## README.md (MANDATORY)
67
+
68
+ After any session that adds, changes, or removes user-facing functionality, update `README.md` at the project root. The README must contain at minimum: project name & one-liner, **copy-paste quickstart commands** (install deps + run), usage notes, and tech stack. If `README.md` does not exist, create it as the FIRST file before any other work. A new developer must go from clone → running app in < 2 minutes.
69
+
57
70
  ## History (MANDATORY)
58
71
 
59
72
  Before finishing, append at least one bullet to `histories/coder.md` below the `<!-- Append entries below this line -->` marker. Record: build quirks, API gotchas, pattern preferences, file structure observations, test insights. Format: `- YYYY-MM-DD: <learning>`. Skip only if the session had zero meaningful work.
@@ -4,6 +4,15 @@ description: "Handles all UI/UX design tasks. Use when: creating screens, layout
4
4
  model: Claude Opus 4.6 (copilot)
5
5
  tools: ['read', 'edit', 'search', 'web', 'io.github.upstash/context7/*', 'vscode/memory']
6
6
  agents: []
7
+ handoffs:
8
+ - label: "🔍 Review"
9
+ agent: Reviewer
10
+ prompt: "Review the UI changes for accessibility, conventions, and design quality."
11
+ send: false
12
+ - label: "🎯 Back to Orchestrator"
13
+ agent: Orchestrator
14
+ prompt: "Design work complete. Coordinate next steps."
15
+ send: false
7
16
  ---
8
17
 
9
18
  ## Model Selection
@@ -4,6 +4,23 @@ description: "Coordinates multi-agent workflows. Delegates to Planner, Coder, De
4
4
  model: Claude Sonnet 4.6 (copilot)
5
5
  tools: ['read/readFile', 'agent', 'vscode/memory', 'github/*']
6
6
  agents: ['Planner', 'Coder', 'Designer', 'Reviewer']
7
+ handoffs:
8
+ - label: "📋 Plan"
9
+ agent: Planner
10
+ prompt: "Read PROJECT.md and STATE.md, then create an implementation plan for this task."
11
+ send: false
12
+ - label: "💻 Code"
13
+ agent: Coder
14
+ prompt: "Implement the approved plan. Read decisions.md for context."
15
+ send: false
16
+ - label: "🎨 Design"
17
+ agent: Designer
18
+ prompt: "Design the UI components described in the plan."
19
+ send: false
20
+ - label: "🔍 Review"
21
+ agent: Reviewer
22
+ prompt: "Review the implementation for correctness, conventions, and architecture."
23
+ send: false
7
24
  ---
8
25
 
9
26
  You are a project orchestrator. You break down complex requests into tasks and delegate to specialist subagents. You coordinate work but NEVER implement anything yourself.
@@ -4,6 +4,15 @@ description: "Creates implementation plans by researching the codebase, consulti
4
4
  model: Claude Opus 4.6 (copilot)
5
5
  tools: ['read', 'search', 'web', 'io.github.upstash/context7/*', 'vscode/memory']
6
6
  user-invocable: false
7
+ handoffs:
8
+ - label: "🎯 Execute Plan"
9
+ agent: Orchestrator
10
+ prompt: "Plan is ready. Execute it phase by phase."
11
+ send: false
12
+ - label: "💻 Code Directly"
13
+ agent: Coder
14
+ prompt: "Implement this plan."
15
+ send: false
7
16
  ---
8
17
 
9
18
  # Planning Agent
@@ -5,6 +5,15 @@ model: Claude Opus 4.6 (copilot)
5
5
  tools: ['read', 'search', 'web', 'vscode/memory']
6
6
  agents: []
7
7
  user-invocable: true
8
+ handoffs:
9
+ - label: "🎯 Back to Orchestrator"
10
+ agent: Orchestrator
11
+ prompt: "Review complete. See verdict above. Coordinate fixes or proceed."
12
+ send: false
13
+ - label: "💻 Fix Issues"
14
+ agent: Coder
15
+ prompt: "Fix the issues identified in the review above."
16
+ send: false
8
17
  ---
9
18
 
10
19
  ## Model Selection
@@ -23,6 +23,18 @@
23
23
  - Read `PROJECT.md`, `STATE.md`, and `decisions.md` on entry.
24
24
  - Before finishing: update `decisions.md` if any choice was made, update your `histories/<agent>.md` with at least one learning.
25
25
 
26
+ # README.md (MANDATORY)
27
+ - The project MUST have a `README.md` at the root at all times.
28
+ - After any session that adds, changes, or removes user-facing functionality, update `README.md`.
29
+ - The README must always contain at minimum:
30
+ 1. **Project name & one-liner** — what this is.
31
+ 2. **Quickstart** — exact commands to install dependencies and run the project locally (copy-paste ready, no placeholders).
32
+ 3. **Usage** — how to use the main features.
33
+ 4. **Tech stack** — languages, frameworks, key libraries.
34
+ - Keep it concise and user-friendly. A new developer should go from clone → running app in under 2 minutes.
35
+ - If the README does not exist yet, create it as the FIRST file before any other work.
36
+ - If unsure about run commands, inspect `package.json` scripts, `Makefile`, `Dockerfile`, or equivalent.
37
+
26
38
  At the end of every agent session, before stopping, append a terse session summary to `agent-diary.md`
27
39
  at the workspace root as a markdown section with format `## YYYY-MM-DD HH:MM` (24-hour time).
28
40
  Include: 2-5 sentence summary of what was accomplished, include model used.
@@ -12,6 +12,11 @@
12
12
  ## Frameworks / Key Libraries
13
13
  - {{FRAMEWORKS}}
14
14
 
15
+ ## Quickstart
16
+ ```bash
17
+ {{QUICKSTART}}
18
+ ```
19
+
15
20
  ## Hard Constraints
16
21
  {{CONSTRAINTS}}
17
22