cli-five 0.1.0
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 +106 -0
- package/bin/cli-five.mjs +8 -0
- package/package.json +35 -0
- package/src/cli.mjs +65 -0
- package/src/commands/doctor.mjs +54 -0
- package/src/commands/init.mjs +87 -0
- package/src/commands/list-stacks.mjs +13 -0
- package/src/steps/confirm.mjs +38 -0
- package/src/steps/detect.mjs +64 -0
- package/src/steps/interview.mjs +98 -0
- package/src/steps/scaffold.mjs +139 -0
- package/src/steps/skills.mjs +162 -0
- package/src/util/fs.mjs +49 -0
- package/src/util/git.mjs +12 -0
- package/src/util/log.mjs +11 -0
- package/templates/.github/agents/coder.agent.md +59 -0
- package/templates/.github/agents/designer.agent.md +56 -0
- package/templates/.github/agents/orchestrator.agent.md +79 -0
- package/templates/.github/agents/planner.agent.md +69 -0
- package/templates/.github/agents/reviewer.agent.md +88 -0
- package/templates/.github/copilot-instructions.md.tmpl +28 -0
- package/templates/.github/instructions/README.md +14 -0
- package/templates/.github/skills/README.md +14 -0
- package/templates/AGENTS.md.tmpl +25 -0
- package/templates/PROJECT.md.tmpl +27 -0
- package/templates/STATE.md.tmpl +22 -0
- package/templates/agent-diary.md.tmpl +5 -0
- package/templates/decisions.md.tmpl +15 -0
- package/templates/histories/coder.md +5 -0
- package/templates/histories/designer.md +5 -0
- package/templates/histories/orchestrator.md +5 -0
- package/templates/histories/planner.md +5 -0
- package/templates/histories/reviewer.md +5 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { log } from '../util/log.mjs';
|
|
3
|
+
import { readTemplate, render, writeFile, listFilesRecursive, relTo } from '../util/fs.mjs';
|
|
4
|
+
import { templatePath } from '../util/fs.mjs';
|
|
5
|
+
import { readFileSync } from 'node:fs';
|
|
6
|
+
|
|
7
|
+
const AGENT_FILES = [
|
|
8
|
+
'orchestrator.agent.md',
|
|
9
|
+
'planner.agent.md',
|
|
10
|
+
'coder.agent.md',
|
|
11
|
+
'designer.agent.md',
|
|
12
|
+
'reviewer.agent.md',
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
const HISTORY_FILES = ['orchestrator.md', 'planner.md', 'coder.md', 'designer.md', 'reviewer.md'];
|
|
16
|
+
|
|
17
|
+
const MODEL_MAP = {
|
|
18
|
+
premium: {
|
|
19
|
+
Orchestrator: 'Claude Sonnet 4.6 (copilot)',
|
|
20
|
+
Planner: 'Claude Opus 4.6 (copilot)',
|
|
21
|
+
Coder: 'GPT-5.3-Codex (copilot)',
|
|
22
|
+
Designer: 'Claude Opus 4.6 (copilot)',
|
|
23
|
+
Reviewer: 'Claude Opus 4.6 (copilot)',
|
|
24
|
+
},
|
|
25
|
+
cheap: {
|
|
26
|
+
Orchestrator: 'GPT-4.1 (copilot)',
|
|
27
|
+
Planner: 'GPT-4o (copilot)',
|
|
28
|
+
Coder: 'GPT-4.1 (copilot)',
|
|
29
|
+
Designer: 'GPT-4o (copilot)',
|
|
30
|
+
Reviewer: 'GPT-5 mini (copilot)',
|
|
31
|
+
},
|
|
32
|
+
mixed: {
|
|
33
|
+
Orchestrator: 'GPT-4.1 (copilot)',
|
|
34
|
+
Planner: 'GPT-4o (copilot)',
|
|
35
|
+
Coder: 'GPT-5.3-Codex (copilot)',
|
|
36
|
+
Designer: 'GPT-4o (copilot)',
|
|
37
|
+
Reviewer: 'Claude Opus 4.6 (copilot)',
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export function scaffold({ cwd, answers, args }) {
|
|
42
|
+
const vars = buildVars(answers);
|
|
43
|
+
const written = [];
|
|
44
|
+
|
|
45
|
+
// Agents (with model swap per cost mode)
|
|
46
|
+
for (const file of AGENT_FILES) {
|
|
47
|
+
const src = readFileSync(templatePath('.github', 'agents', file), 'utf8');
|
|
48
|
+
const swapped = swapModel(src, MODEL_MAP[answers.costMode]);
|
|
49
|
+
written.push(writeFile(join(cwd, '.github', 'agents', file), swapped, args));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// copilot-instructions.md (templated)
|
|
53
|
+
const ci = render(readTemplate('.github', 'copilot-instructions.md.tmpl'), vars);
|
|
54
|
+
written.push(writeFile(join(cwd, '.github', 'copilot-instructions.md'), ci, args));
|
|
55
|
+
|
|
56
|
+
// Empty containers ready for /agent-customization
|
|
57
|
+
written.push(
|
|
58
|
+
writeFile(
|
|
59
|
+
join(cwd, '.github', 'instructions', 'README.md'),
|
|
60
|
+
readTemplate('.github', 'instructions', 'README.md'),
|
|
61
|
+
args,
|
|
62
|
+
),
|
|
63
|
+
);
|
|
64
|
+
written.push(
|
|
65
|
+
writeFile(join(cwd, '.github', 'skills', 'README.md'), readTemplate('.github', 'skills', 'README.md'), args),
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
// Project root memory primitives (GSD-inspired)
|
|
69
|
+
for (const tmpl of [
|
|
70
|
+
'AGENTS.md.tmpl',
|
|
71
|
+
'PROJECT.md.tmpl',
|
|
72
|
+
'STATE.md.tmpl',
|
|
73
|
+
'decisions.md.tmpl',
|
|
74
|
+
'agent-diary.md.tmpl',
|
|
75
|
+
]) {
|
|
76
|
+
const out = render(readTemplate(tmpl), vars);
|
|
77
|
+
const target = tmpl.replace(/\.tmpl$/, '');
|
|
78
|
+
written.push(writeFile(join(cwd, target), out, args));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Per-agent histories
|
|
82
|
+
for (const file of HISTORY_FILES) {
|
|
83
|
+
written.push(writeFile(join(cwd, 'histories', file), readTemplate('histories', file), args));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return written;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function buildVars(a) {
|
|
90
|
+
return {
|
|
91
|
+
PROJECT_NAME: a.projectName,
|
|
92
|
+
ONE_LINER: a.oneLiner || 'TODO — write a one-line vision statement.',
|
|
93
|
+
STACK: a.stack.length ? a.stack.join(', ') : 'Not yet declared.',
|
|
94
|
+
FRAMEWORKS: a.frameworks.length ? a.frameworks.join(', ') : 'None declared.',
|
|
95
|
+
GOALS: a.goals || 'TODO — declare the primary goal.',
|
|
96
|
+
CONSTRAINTS: a.constraints || 'None declared.',
|
|
97
|
+
COST_MODE: a.costMode,
|
|
98
|
+
DATE: new Date().toISOString().slice(0, 10),
|
|
99
|
+
PERSONA_BLOCK: a.snark ? PERSONA_BLOCK : '',
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function swapModel(src, modelByAgent) {
|
|
104
|
+
// Replace the YAML `model:` line based on the `name:` immediately above/around it.
|
|
105
|
+
const lines = src.split('\n');
|
|
106
|
+
let agentName = null;
|
|
107
|
+
for (let i = 0; i < lines.length; i++) {
|
|
108
|
+
const m = /^name:\s*(.+?)\s*$/.exec(lines[i]);
|
|
109
|
+
if (m) {
|
|
110
|
+
agentName = m[1];
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (agentName && /^model:\s*/.test(lines[i])) {
|
|
114
|
+
const newModel = modelByAgent[agentName];
|
|
115
|
+
if (newModel) lines[i] = `model: ${newModel}`;
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return lines.join('\n');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const PERSONA_BLOCK = `# Persona
|
|
123
|
+
- Expert dev with no-bullshit attitude. Direct, harsh, pragmatic.
|
|
124
|
+
- Favor simplicity over complexity. Get shit done.
|
|
125
|
+
- Prioritize maintainability and readability.
|
|
126
|
+
- Be critical. Call out bad practices and tech debt.
|
|
127
|
+
- Snarky, dry humor. Keep it real and keep it moving.
|
|
128
|
+
|
|
129
|
+
`;
|
|
130
|
+
|
|
131
|
+
export function summarize(written, cwd) {
|
|
132
|
+
const lines = [];
|
|
133
|
+
for (const w of written) {
|
|
134
|
+
lines.push(` ${w.written ? '+' : '~'} ${relTo(cwd, w.path)}`);
|
|
135
|
+
}
|
|
136
|
+
return lines.join('\n');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export { listFilesRecursive };
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import prompts from 'prompts';
|
|
2
|
+
import { spawn, execFileSync } from 'node:child_process';
|
|
3
|
+
import { log } from '../util/log.mjs';
|
|
4
|
+
|
|
5
|
+
// Well-known skill repos matched by stack term → repo + suggested skill names
|
|
6
|
+
const SKILL_CATALOG = [
|
|
7
|
+
{ terms: ['*'], repo: 'anthropics/skills', skills: ['frontend-design', 'skill-creator'] },
|
|
8
|
+
{ terms: ['*'], repo: 'vercel-labs/agent-skills', skills: ['vercel-react-best-practices', 'web-design-guidelines'] },
|
|
9
|
+
{ terms: ['node', 'typescript', 'react', 'next'], repo: 'vercel-labs/agent-skills', skills: ['vercel-composition-patterns'] },
|
|
10
|
+
{ terms: ['python'], repo: 'anthropics/skills', skills: ['python-best-practices'] },
|
|
11
|
+
{ terms: ['dotnet', '.net'], repo: 'microsoft/azure-skills', skills: ['microsoft-foundry'] },
|
|
12
|
+
{ terms: ['android', 'kotlin'], repo: 'anthropics/skills', skills: ['frontend-design'] },
|
|
13
|
+
{ terms: ['rust'], repo: 'anthropics/skills', skills: ['code-review'] },
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
export async function skillDiscovery({ cwd, answers, args }) {
|
|
17
|
+
if (!args.skills) {
|
|
18
|
+
log.dim('Skipping skills discovery (--no-skills).');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (args.yes) {
|
|
22
|
+
log.dim('Non-interactive mode — skipping skills picker. Run `npx skills find` later.');
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
log.raw('');
|
|
27
|
+
log.raw('Skill discovery powered by skills.sh (Vercel)');
|
|
28
|
+
|
|
29
|
+
// 1. Build recommendations from catalog based on stack
|
|
30
|
+
const recs = buildRecommendations(answers);
|
|
31
|
+
if (recs.length === 0) {
|
|
32
|
+
log.dim('No stack-specific recommendations found.');
|
|
33
|
+
} else {
|
|
34
|
+
log.raw('');
|
|
35
|
+
log.raw(` ${pad('Skill', 36)} ${pad('Repo', 36)}`);
|
|
36
|
+
log.raw(` ${'─'.repeat(36)} ${'─'.repeat(36)}`);
|
|
37
|
+
for (const r of recs) {
|
|
38
|
+
log.raw(` ${pad(r.skill, 36)} ${pad(r.repo, 36)}`);
|
|
39
|
+
}
|
|
40
|
+
log.raw('');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// 2. Offer interactive search per stack term
|
|
44
|
+
const terms = suggestSearches(answers);
|
|
45
|
+
if (terms.length > 0) {
|
|
46
|
+
log.dim(`Suggested searches: ${terms.map((t) => `"${t}"`).join(', ')}`);
|
|
47
|
+
log.raw('');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 3. Offer to launch interactive find for each term
|
|
51
|
+
for (const term of terms) {
|
|
52
|
+
const { go } = await prompts({
|
|
53
|
+
type: 'confirm',
|
|
54
|
+
name: 'go',
|
|
55
|
+
message: `Search skills.sh for "${term}"?`,
|
|
56
|
+
initial: true,
|
|
57
|
+
});
|
|
58
|
+
if (go) {
|
|
59
|
+
await runInteractive('npx', ['-y', 'skills', 'find', term], cwd);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// 4. Offer to install from well-known repos
|
|
64
|
+
if (recs.length > 0) {
|
|
65
|
+
const { install } = await prompts({
|
|
66
|
+
type: 'multiselect',
|
|
67
|
+
name: 'install',
|
|
68
|
+
message: 'Install recommended skills?',
|
|
69
|
+
choices: recs.map((r) => ({
|
|
70
|
+
title: `${r.skill} (${r.repo})`,
|
|
71
|
+
value: r,
|
|
72
|
+
selected: false,
|
|
73
|
+
})),
|
|
74
|
+
hint: 'Space to select, Enter to confirm',
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
if (install && install.length > 0) {
|
|
78
|
+
// Group by repo
|
|
79
|
+
const byRepo = new Map();
|
|
80
|
+
for (const r of install) {
|
|
81
|
+
if (!byRepo.has(r.repo)) byRepo.set(r.repo, []);
|
|
82
|
+
byRepo.get(r.repo).push(r.skill);
|
|
83
|
+
}
|
|
84
|
+
for (const [repo, skills] of byRepo) {
|
|
85
|
+
const skillArgs = skills.flatMap((s) => ['--skill', s]);
|
|
86
|
+
log.info(`Installing from ${repo}: ${skills.join(', ')}`);
|
|
87
|
+
await runInteractive(
|
|
88
|
+
'npx',
|
|
89
|
+
['-y', 'skills', 'add', repo, ...skillArgs, '-a', 'github-copilot'],
|
|
90
|
+
cwd,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// 5. Offer freeform catch-all
|
|
97
|
+
const { freeform } = await prompts({
|
|
98
|
+
type: 'confirm',
|
|
99
|
+
name: 'freeform',
|
|
100
|
+
message: 'Launch the full interactive skills browser?',
|
|
101
|
+
initial: false,
|
|
102
|
+
});
|
|
103
|
+
if (freeform) {
|
|
104
|
+
await runInteractive('npx', ['-y', 'skills', 'find'], cwd);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
log.dim('Done. Run `npx skills find` anytime to discover more.');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function buildRecommendations(a) {
|
|
111
|
+
const stackLower = (a.stack || []).map((s) => s.toLowerCase());
|
|
112
|
+
const fwLower = (a.frameworks || []).map((f) => f.toLowerCase());
|
|
113
|
+
const all = [...stackLower, ...fwLower];
|
|
114
|
+
const seen = new Set();
|
|
115
|
+
const out = [];
|
|
116
|
+
|
|
117
|
+
for (const entry of SKILL_CATALOG) {
|
|
118
|
+
const matches = entry.terms.includes('*') || entry.terms.some((t) => all.some((s) => s.includes(t)));
|
|
119
|
+
if (!matches) continue;
|
|
120
|
+
for (const skill of entry.skills) {
|
|
121
|
+
const key = `${entry.repo}/${skill}`;
|
|
122
|
+
if (seen.has(key)) continue;
|
|
123
|
+
seen.add(key);
|
|
124
|
+
out.push({ repo: entry.repo, skill });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return out;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function suggestSearches(a) {
|
|
131
|
+
const out = new Set();
|
|
132
|
+
for (const s of a.stack || []) {
|
|
133
|
+
const t = s.toLowerCase();
|
|
134
|
+
if (t.includes('node') || t.includes('typescript')) out.add('typescript');
|
|
135
|
+
if (t.includes('python')) out.add('python');
|
|
136
|
+
if (t.includes('.net') || t.includes('dotnet')) out.add('dotnet');
|
|
137
|
+
if (t.includes('kotlin') || t.includes('android')) out.add('android');
|
|
138
|
+
if (t.includes('rust')) out.add('rust');
|
|
139
|
+
if (t.includes('go')) out.add('go');
|
|
140
|
+
if (t.includes('ruby')) out.add('ruby');
|
|
141
|
+
if (t.includes('php')) out.add('php');
|
|
142
|
+
}
|
|
143
|
+
for (const f of a.frameworks || []) out.add(f.toLowerCase());
|
|
144
|
+
if (out.size === 0) out.add('best-practices');
|
|
145
|
+
return [...out];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function pad(s, n) {
|
|
149
|
+
return (s || '').padEnd(n);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function runInteractive(cmd, args, cwd) {
|
|
153
|
+
return new Promise((resolve) => {
|
|
154
|
+
const proc = spawn(cmd, args, { cwd, stdio: 'inherit' });
|
|
155
|
+
proc.on('exit', () => resolve());
|
|
156
|
+
proc.on('error', (err) => {
|
|
157
|
+
log.warn(`Could not launch \`${cmd} ${args.join(' ')}\`: ${err.message}`);
|
|
158
|
+
log.dim('Install/run it manually later. See https://skills.sh');
|
|
159
|
+
resolve();
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
}
|
package/src/util/fs.mjs
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync, readFileSync, existsSync, readdirSync, statSync } from 'node:fs';
|
|
2
|
+
import { dirname, join, relative } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
|
|
5
|
+
const HERE = fileURLToPath(new URL('.', import.meta.url));
|
|
6
|
+
export const PKG_ROOT = join(HERE, '..', '..');
|
|
7
|
+
export const TEMPLATES_DIR = join(PKG_ROOT, 'templates');
|
|
8
|
+
|
|
9
|
+
export function templatePath(...segments) {
|
|
10
|
+
return join(TEMPLATES_DIR, ...segments);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function readTemplate(...segments) {
|
|
14
|
+
return readFileSync(templatePath(...segments), 'utf8');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function writeFile(targetPath, contents, { dryRun = false } = {}) {
|
|
18
|
+
if (dryRun) return { written: false, path: targetPath };
|
|
19
|
+
mkdirSync(dirname(targetPath), { recursive: true });
|
|
20
|
+
writeFileSync(targetPath, contents);
|
|
21
|
+
return { written: true, path: targetPath };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function fileExists(p) {
|
|
25
|
+
return existsSync(p);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function listFilesRecursive(dir) {
|
|
29
|
+
const out = [];
|
|
30
|
+
if (!existsSync(dir)) return out;
|
|
31
|
+
for (const name of readdirSync(dir)) {
|
|
32
|
+
const full = join(dir, name);
|
|
33
|
+
const st = statSync(full);
|
|
34
|
+
if (st.isDirectory()) out.push(...listFilesRecursive(full));
|
|
35
|
+
else out.push(full);
|
|
36
|
+
}
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function relTo(base, p) {
|
|
41
|
+
return relative(base, p);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function render(tmpl, vars) {
|
|
45
|
+
return tmpl.replace(/\{\{\s*([A-Z0-9_]+)\s*\}\}/g, (_m, key) => {
|
|
46
|
+
const v = vars[key];
|
|
47
|
+
return v === undefined || v === null ? '' : String(v);
|
|
48
|
+
});
|
|
49
|
+
}
|
package/src/util/git.mjs
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
|
|
5
|
+
export function isGitRepo(cwd) {
|
|
6
|
+
return existsSync(join(cwd, '.git'));
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function gitInit(cwd) {
|
|
10
|
+
const res = spawnSync('git', ['init', '--quiet'], { cwd, stdio: 'inherit' });
|
|
11
|
+
if (res.status !== 0) throw new Error('git init failed');
|
|
12
|
+
}
|
package/src/util/log.mjs
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import kleur from 'kleur';
|
|
2
|
+
|
|
3
|
+
export const log = {
|
|
4
|
+
info: (msg) => process.stdout.write(`${kleur.cyan('●')} ${msg}\n`),
|
|
5
|
+
ok: (msg) => process.stdout.write(`${kleur.green('✓')} ${msg}\n`),
|
|
6
|
+
warn: (msg) => process.stdout.write(`${kleur.yellow('!')} ${msg}\n`),
|
|
7
|
+
err: (msg) => process.stderr.write(`${kleur.red('✗')} ${msg}\n`),
|
|
8
|
+
step: (msg) => process.stdout.write(`\n${kleur.bold().magenta('▸')} ${kleur.bold(msg)}\n`),
|
|
9
|
+
dim: (msg) => process.stdout.write(`${kleur.gray(msg)}\n`),
|
|
10
|
+
raw: (msg) => process.stdout.write(`${msg}\n`),
|
|
11
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Coder
|
|
3
|
+
description: "Writes production code following workspace conventions. Use when: implementing features, fixing bugs, writing tests, creating modules."
|
|
4
|
+
model: GPT-5.3-Codex (copilot)
|
|
5
|
+
tools: ['vscode', 'execute', 'read', 'io.github.upstash/context7/*', 'github/*', 'edit', 'search', 'web', 'vscode/memory', 'todo']
|
|
6
|
+
agents: []
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Model Selection
|
|
10
|
+
|
|
11
|
+
| Mode | Model | Premium Cost |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| **Default** | GPT-5.3-Codex | 1x |
|
|
14
|
+
| **Cheap** | GPT-4.1 | 0x (free) |
|
|
15
|
+
|
|
16
|
+
To switch: change the `model` key in frontmatter above.
|
|
17
|
+
|
|
18
|
+
## Subagent Output Contract
|
|
19
|
+
|
|
20
|
+
When invoked by the Orchestrator, only your **final message** is returned. Internal tool results, build output, and earlier turns are invisible.
|
|
21
|
+
|
|
22
|
+
**Your response MUST contain:**
|
|
23
|
+
- A list of every file created or modified (absolute paths)
|
|
24
|
+
- A concise summary of what each change does
|
|
25
|
+
- Build/test status if you ran them
|
|
26
|
+
- Any blockers, assumptions, or deviations from the assigned task
|
|
27
|
+
|
|
28
|
+
Do not say "see the diff above" — the caller cannot see your internal turns.
|
|
29
|
+
|
|
30
|
+
## Required Reading
|
|
31
|
+
|
|
32
|
+
ALWAYS use context7 MCP Server to read relevant documentation before implementation. Your training data is stale — verify, don't assume.
|
|
33
|
+
|
|
34
|
+
Before writing code, read (if they exist):
|
|
35
|
+
- `decisions.md` — prior team decisions
|
|
36
|
+
- `histories/coder.md` — your accumulated learnings
|
|
37
|
+
- `.github/copilot-instructions.md` or `AGENTS.md` — project mandates
|
|
38
|
+
- All `.github/instructions/*.instructions.md` matching the languages involved
|
|
39
|
+
- All relevant `.github/skills/*/SKILL.md` or `skills/*/SKILL.md`
|
|
40
|
+
|
|
41
|
+
## Mandatory Coding Principles
|
|
42
|
+
|
|
43
|
+
1. **Structure** — Consistent project layout. Group by feature. Simple entry points. Shared patterns over duplication.
|
|
44
|
+
2. **Architecture** — Flat, explicit code. No clever patterns, metaprogramming, or unnecessary indirection. Minimize coupling.
|
|
45
|
+
3. **Functions** — Linear control flow. Small-to-medium functions. Pass state explicitly. No globals.
|
|
46
|
+
4. **Naming** — Descriptive-but-simple names. Comment only for invariants, assumptions, or external requirements.
|
|
47
|
+
5. **Logging** — Detailed, structured logs at key boundaries. Explicit, informative errors.
|
|
48
|
+
6. **Regenerability** — Any file can be rewritten from scratch without breaking the system. Prefer declarative configuration.
|
|
49
|
+
7. **Platform** — Use framework conventions directly and simply without over-abstracting.
|
|
50
|
+
8. **Modifications** — Follow existing patterns. Prefer full-file rewrites over micro-edits unless told otherwise.
|
|
51
|
+
9. **Quality** — Deterministic, testable behavior. Simple, focused tests.
|
|
52
|
+
|
|
53
|
+
## Decisions
|
|
54
|
+
|
|
55
|
+
After making an implementation decision that affects future work, append it to `decisions.md`.
|
|
56
|
+
|
|
57
|
+
## History
|
|
58
|
+
|
|
59
|
+
After completing a task, if you learned something non-obvious about this project (build quirks, API gotchas, pattern preferences), append it to `histories/coder.md`.
|
|
@@ -0,0 +1,56 @@
|
|
|
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', 'io.github.upstash/context7/*', 'vscode/memory']
|
|
6
|
+
agents: []
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Model Selection
|
|
10
|
+
|
|
11
|
+
| Mode | Model | Premium Cost |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| **Default** | Claude Opus 4.6 | 3x |
|
|
14
|
+
| **Cheap** | GPT-4o | 0x (free) |
|
|
15
|
+
|
|
16
|
+
To switch: change the `model` key in frontmatter above.
|
|
17
|
+
|
|
18
|
+
## Subagent Output Contract
|
|
19
|
+
|
|
20
|
+
When invoked by the Orchestrator, only your **final message** is returned. Internal tool results and earlier turns are invisible.
|
|
21
|
+
|
|
22
|
+
**Your response MUST contain:**
|
|
23
|
+
- A list of every UI file created or modified (absolute paths)
|
|
24
|
+
- Design decisions made and accessibility/UX choices applied
|
|
25
|
+
- Any open design questions or follow-ups
|
|
26
|
+
|
|
27
|
+
Do not reference "the layout above" — re-state inline.
|
|
28
|
+
|
|
29
|
+
## Required Reading
|
|
30
|
+
|
|
31
|
+
Before design work, read (if they exist):
|
|
32
|
+
- `decisions.md` — prior team decisions
|
|
33
|
+
- `histories/designer.md` — your accumulated learnings
|
|
34
|
+
- `.github/copilot-instructions.md` or `AGENTS.md` — project mandates
|
|
35
|
+
- All `.github/instructions/*.instructions.md` matching UI file types
|
|
36
|
+
- All relevant `.github/skills/*/SKILL.md` or `skills/*/SKILL.md`
|
|
37
|
+
|
|
38
|
+
## Identity
|
|
39
|
+
|
|
40
|
+
Do not let anyone tell you how to do your job. Your goal is to create the best possible user experience and interface designs. Focus on usability, accessibility, and aesthetics.
|
|
41
|
+
|
|
42
|
+
## Design Principles
|
|
43
|
+
|
|
44
|
+
- Accessibility first: contrast ratios, touch targets, screen reader support
|
|
45
|
+
- Minimal cognitive load
|
|
46
|
+
- Platform conventions over custom patterns
|
|
47
|
+
- Responsive/adaptive layouts
|
|
48
|
+
- Use the project's designated design system and component library
|
|
49
|
+
|
|
50
|
+
## Decisions
|
|
51
|
+
|
|
52
|
+
After making a design decision that affects future work, append it to `decisions.md`.
|
|
53
|
+
|
|
54
|
+
## History
|
|
55
|
+
|
|
56
|
+
After completing a task, if you learned something non-obvious about this project's UI patterns or constraints, append it to `histories/designer.md`.
|
|
@@ -0,0 +1,79 @@
|
|
|
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
|
+
---
|
|
8
|
+
|
|
9
|
+
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.
|
|
10
|
+
|
|
11
|
+
## Model Selection
|
|
12
|
+
|
|
13
|
+
| Mode | Model | Premium Cost |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| **Default** | Claude Sonnet 4.6 | 1x |
|
|
16
|
+
| **Cheap** | GPT-4.1 | 0x (free) |
|
|
17
|
+
|
|
18
|
+
To switch: change the `model` key in frontmatter above.
|
|
19
|
+
|
|
20
|
+
## Agents
|
|
21
|
+
|
|
22
|
+
| Agent | Role | Tools |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| **Planner** | Research codebase, check docs, create implementation plans | Read-only + web |
|
|
25
|
+
| **Coder** | Write code, fix bugs, implement features | Edit + execute |
|
|
26
|
+
| **Designer** | UI/UX design, layouts, theming | Edit + web |
|
|
27
|
+
| **Reviewer** | Review agent output for correctness, conventions, architecture | Read-only |
|
|
28
|
+
|
|
29
|
+
## Required Reading
|
|
30
|
+
|
|
31
|
+
Before any task, read (if they exist):
|
|
32
|
+
- `decisions.md` — prior team decisions
|
|
33
|
+
- `histories/orchestrator.md` — your accumulated learnings about this project
|
|
34
|
+
- `.github/copilot-instructions.md` or `AGENTS.md` — project context and mandates
|
|
35
|
+
|
|
36
|
+
## Execution Model
|
|
37
|
+
|
|
38
|
+
### Step 1: Get the Plan
|
|
39
|
+
Call the Planner with the user's request. The Planner returns implementation steps with file assignments. **Skip if a plan is already in context** or the request is trivial (single-file fix, typo, refactor — plan inline and proceed).
|
|
40
|
+
|
|
41
|
+
**Subagent output contract:** Only the subagent's final message is returned. Internal tool results, reads, searches, and earlier turns are invisible. If a subagent returns a meta-comment ("the plan is above", "see the diff") instead of the actual deliverable, re-prompt demanding inline output, or fall back to direct tool use.
|
|
42
|
+
|
|
43
|
+
### Step 2: Parse Into Phases
|
|
44
|
+
Group steps into phases. Non-overlapping files = same phase (parallel). Overlapping files or dependencies = different phases (sequential). Always end with a Review phase.
|
|
45
|
+
|
|
46
|
+
### Step 3: Execute Each Phase
|
|
47
|
+
Call appropriate agents. Assign each agent explicit files — never overlapping files to parallel tasks. Report progress after each phase.
|
|
48
|
+
|
|
49
|
+
### Step 4: Review (MANDATORY)
|
|
50
|
+
Call the Reviewer. Verdict handling:
|
|
51
|
+
- **PASS / PASS WITH NOTES:** Proceed to report.
|
|
52
|
+
- **NEEDS CHANGES:** Call Coder to fix, then Reviewer again. **Maximum 2 fix-review rounds.**
|
|
53
|
+
- **REJECT:** Report to user immediately. Do not attempt fixes.
|
|
54
|
+
|
|
55
|
+
### Step 5: Report
|
|
56
|
+
Summarize what was completed and the review verdict.
|
|
57
|
+
|
|
58
|
+
## Constraint Budgets
|
|
59
|
+
|
|
60
|
+
Maintain visible counters in responses:
|
|
61
|
+
- `📊 Fix-review rounds: {n}/2`
|
|
62
|
+
- `📊 Clarifying questions: {n}/3`
|
|
63
|
+
|
|
64
|
+
When exhausted, state it and proceed with current information.
|
|
65
|
+
|
|
66
|
+
## Decisions
|
|
67
|
+
|
|
68
|
+
After making a routing or architectural decision that affects future work, append it to `decisions.md` at the workspace root.
|
|
69
|
+
|
|
70
|
+
## History
|
|
71
|
+
|
|
72
|
+
After completing a task, if you learned something non-obvious about this project, append it to `histories/orchestrator.md`.
|
|
73
|
+
|
|
74
|
+
## Rules
|
|
75
|
+
|
|
76
|
+
- Delegate WHAT (outcomes), never HOW (implementation details).
|
|
77
|
+
- Never assign overlapping files to agents in the same phase.
|
|
78
|
+
- Never implement anything yourself — you are a router, not a worker.
|
|
79
|
+
- Always include phase number when delegating.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Planner
|
|
3
|
+
description: "Creates implementation plans by researching the codebase, consulting documentation, and identifying edge cases. Use when: planning features, architectural decisions, or complex multi-file changes."
|
|
4
|
+
model: Claude Opus 4.6 (copilot)
|
|
5
|
+
tools: ['read', 'search', 'web', 'io.github.upstash/context7/*', 'vscode/memory']
|
|
6
|
+
user-invocable: false
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Planning Agent
|
|
10
|
+
|
|
11
|
+
You create plans. You do NOT write code.
|
|
12
|
+
|
|
13
|
+
## Model Selection
|
|
14
|
+
|
|
15
|
+
| Mode | Model | Premium Cost |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| **Default** | Claude Opus 4.6 | 3x |
|
|
18
|
+
| **Cheap** | GPT-4o | 0x (free) |
|
|
19
|
+
|
|
20
|
+
To switch: change the `model` key in frontmatter above.
|
|
21
|
+
|
|
22
|
+
## Required Reading
|
|
23
|
+
|
|
24
|
+
Before planning, read (if they exist):
|
|
25
|
+
- `decisions.md` — prior team decisions that constrain this plan
|
|
26
|
+
- `histories/planner.md` — your accumulated learnings about this project
|
|
27
|
+
- `.github/copilot-instructions.md` or `AGENTS.md` — project context and mandates
|
|
28
|
+
- All files in `.github/instructions/` matching the task's languages/frameworks
|
|
29
|
+
- All relevant skills in `.github/skills/` or `skills/`
|
|
30
|
+
|
|
31
|
+
## Workflow
|
|
32
|
+
|
|
33
|
+
1. **Research**: Search the codebase thoroughly. Read relevant files. Find existing patterns.
|
|
34
|
+
2. **Verify**: Use context7 and web tools to check documentation for libraries/APIs involved. Don't assume — verify. Your training data is stale.
|
|
35
|
+
3. **Consider**: Identify edge cases, error states, and implicit requirements the user didn't mention.
|
|
36
|
+
4. **Plan**: Output WHAT needs to happen, not HOW to code it.
|
|
37
|
+
|
|
38
|
+
## Output Format
|
|
39
|
+
|
|
40
|
+
- **Summary** (one paragraph)
|
|
41
|
+
- **Implementation steps** (ordered), each with:
|
|
42
|
+
- Description of the outcome
|
|
43
|
+
- File assignments (which files are created or modified)
|
|
44
|
+
- Dependencies on other steps
|
|
45
|
+
- **Edge cases** to handle
|
|
46
|
+
- **Open questions** (if any)
|
|
47
|
+
- **Suggested phase grouping** (which steps can be parallelized)
|
|
48
|
+
|
|
49
|
+
## Subagent Output Contract
|
|
50
|
+
|
|
51
|
+
When invoked by the Orchestrator, only your **final message** is returned. Internal tool results and earlier turns are invisible.
|
|
52
|
+
|
|
53
|
+
**Your response MUST contain the complete plan inline.** Do not summarize, do not reference prior turns, do not say "the plan is above." Re-emit every section in your final message. If truncated, flag it explicitly.
|
|
54
|
+
|
|
55
|
+
## Decisions
|
|
56
|
+
|
|
57
|
+
After making a planning decision that constrains future work, append it to `decisions.md`.
|
|
58
|
+
|
|
59
|
+
## History
|
|
60
|
+
|
|
61
|
+
After completing a plan, if you learned something non-obvious about this project's structure, patterns, or constraints, append it to `histories/planner.md`.
|
|
62
|
+
|
|
63
|
+
## Rules
|
|
64
|
+
|
|
65
|
+
- Never skip documentation checks for external APIs
|
|
66
|
+
- Consider what the user needs but didn't ask for
|
|
67
|
+
- Note uncertainties — don't hide them
|
|
68
|
+
- Match existing codebase patterns
|
|
69
|
+
- Assign files to steps for parallelization
|