cli-five 0.2.9 → 0.2.11

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
@@ -116,7 +116,9 @@ cli-five searches **two sources** for skills matching your detected stack:
116
116
  | **awesome-copilot** | Skills, instructions, agents, plugins from the GitHub community | 30k+ |
117
117
  | **skills.sh** | Curated skill repos (Vercel, Anthropic, Microsoft, etc.) | — |
118
118
 
119
- Recommendations show with source attribution and are pre-selected for one-click install. After installation, you get breadcrumbs for ongoing discovery:
119
+ Recommendations show with source attribution. Only cli-five core skills are pre-selected; suggested skills from skills.sh and awesome-copilot require manual selection (press Space) before install. After installation, you get breadcrumbs for ongoing discovery:
120
+
121
+ Take time to read each installed skill so you understand what it does and can catch overlap or conflicts before they affect your workflow.
120
122
 
121
123
  - **Suggest skill** — `copilot plugin install awesome-copilot@suggest` (AI-driven repo analysis)
122
124
  - **MCP server** — `awesome-copilot-mcp` for programmatic search from any agent
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cli-five",
3
- "version": "0.2.9",
3
+ "version": "0.2.11",
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": {
@@ -2,66 +2,55 @@ import kleur from 'kleur';
2
2
  import prompts from 'prompts';
3
3
 
4
4
  // ── Preset stacks ─────────────────────────────────────────────────────
5
- // Chosen for: LLM familiarity, low setup friction, minimal config,
6
- // copy-paste quickstart, broad hosting support.
7
- // Research via Context7: Next.js, Vite+React, Express, Hono all score
8
- // 80+ benchmark with high snippet counts and well-indexed docs.
5
+ // Curated defaults for fast project bootstrap with optional freeform mode.
9
6
  const STACK_PRESETS = [
10
7
  {
11
- title: 'Next.js + Supabase PWA (TypeScript)',
12
- value: 'nextjs-supabase',
13
- description: 'Next.js 15 static export, React 19, Tailwind v4, Supabase, SWR, Vercel hosting, PWA.',
14
- stack: ['Node + TypeScript'],
15
- frameworks: ['Next.js', 'React', 'Tailwind CSS', 'Supabase', 'SWR'],
16
- quickstart: 'npx create-next-app@latest . --yes && npm i @supabase/supabase-js swr date-fns clsx && npm run dev',
8
+ title: 'SPA: Vanilla HTML/CSS/JS + CDN',
9
+ value: 'spa-vanilla-cdn',
10
+ description: 'No build step. Browser-native app with CDN-loaded libraries.',
11
+ stack: ['HTML + CSS + JavaScript'],
12
+ frameworks: ['CDN (no bundler)'],
13
+ quickstart: 'mkdir -p public && printf "<!doctype html><html><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><title>SPA</title></head><body><div id=\"app\"></div><script src=\"./app.js\"></script></body></html>" > public/index.html && printf "document.getElementById(\"app\").textContent = \"Hello SPA\";" > public/app.js',
17
14
  },
18
15
  {
19
- title: 'Next.js (TypeScript)',
20
- value: 'nextjs',
21
- description: 'Full-stack React. App Router, TypeScript, Tailwind. `npx create-next-app`',
22
- stack: ['Node + TypeScript'],
23
- frameworks: ['Next.js', 'React', 'Tailwind CSS'],
24
- quickstart: 'npx create-next-app@latest . --yes && npm run dev',
25
- },
26
- {
27
- title: 'Vite + React (TypeScript)',
28
- value: 'vite-react',
29
- description: 'SPA frontend. Lightning-fast HMR. `npm create vite`',
30
- stack: ['Node + TypeScript'],
31
- frameworks: ['Vite', 'React', 'TypeScript'],
32
- quickstart: 'npm create vite@latest . -- --template react-ts && npm i && npm run dev',
16
+ title: 'SPA: React + Vite',
17
+ value: 'spa-react-vite',
18
+ description: 'React single-page app powered by Vite.',
19
+ stack: ['Node + JavaScript'],
20
+ frameworks: ['React', 'Vite'],
21
+ quickstart: 'pnpm create vite@latest . --template react && pnpm install && pnpm dev',
33
22
  },
34
23
  {
35
- title: 'Express API (TypeScript)',
36
- value: 'express',
37
- description: 'REST API server. Minimal, well-known, huge ecosystem.',
38
- stack: ['Node + TypeScript'],
39
- frameworks: ['Express', 'TypeScript'],
40
- quickstart: 'npm init -y && npm i express typescript tsx @types/express && npx tsx src/index.ts',
24
+ title: 'Web+DB: Python Flask + SQLite',
25
+ value: 'webdb-flask-sqlite',
26
+ description: 'Server-rendered web app with Flask and local SQLite storage.',
27
+ stack: ['Python'],
28
+ frameworks: ['Flask', 'SQLite'],
29
+ quickstart: 'python -m venv .venv && source .venv/bin/activate && pip install flask && python app.py',
41
30
  },
42
31
  {
43
- title: 'Hono API (TypeScript)',
44
- value: 'hono',
45
- description: 'Ultrafast, Web Standards. Works on Node, Bun, Deno, Cloudflare.',
46
- stack: ['Node + TypeScript'],
47
- frameworks: ['Hono', 'TypeScript'],
48
- quickstart: 'npm create hono@latest . && npm i && npm run dev',
32
+ title: 'Web+DB: Node.js + Express + SQLite',
33
+ value: 'webdb-express-sqlite',
34
+ description: 'Node web app with Express and SQLite.',
35
+ stack: ['Node + JavaScript'],
36
+ frameworks: ['Express', 'SQLite'],
37
+ quickstart: 'pnpm init && pnpm add express sqlite3 && node server.js',
49
38
  },
50
39
  {
51
- title: 'Vite + Vue (TypeScript)',
52
- value: 'vite-vue',
53
- description: 'SPA frontend with Vue 3 + Composition API.',
40
+ title: 'Stack: Next.js + Prisma + SQLite',
41
+ value: 'stack-next-prisma-sqlite',
42
+ description: 'Full-stack Next.js with Prisma ORM and SQLite.',
54
43
  stack: ['Node + TypeScript'],
55
- frameworks: ['Vite', 'Vue', 'TypeScript'],
56
- quickstart: 'npm create vite@latest . -- --template vue-ts && npm i && npm run dev',
44
+ frameworks: ['Next.js', 'Prisma', 'SQLite', 'React'],
45
+ quickstart: 'pnpm create next-app@latest . --ts --eslint --app --src-dir --import-alias "@/*" && pnpm add prisma @prisma/client && pnpm prisma init --datasource-provider sqlite && pnpm dev',
57
46
  },
58
47
  {
59
- title: 'Python + FastAPI',
60
- value: 'fastapi',
61
- description: 'Modern Python API with type hints and auto-docs.',
62
- stack: ['Python'],
63
- frameworks: ['FastAPI', 'Pydantic', 'Uvicorn'],
64
- quickstart: 'pip install fastapi uvicorn && uvicorn main:app --reload',
48
+ title: 'Stack: FastAPI + React/Vite',
49
+ value: 'stack-fastapi-react-vite',
50
+ description: 'FastAPI backend paired with a React/Vite frontend.',
51
+ stack: ['Python', 'Node + JavaScript'],
52
+ frameworks: ['FastAPI', 'React', 'Vite'],
53
+ quickstart: 'python -m venv .venv && source .venv/bin/activate && pip install fastapi uvicorn && pnpm create vite@latest web --template react && cd web && pnpm install && pnpm dev',
65
54
  },
66
55
  {
67
56
  title: 'Custom (freeform)',
@@ -200,10 +189,10 @@ export async function interview(detected, args, docHints = {}) {
200
189
  });
201
190
  }
202
191
 
203
- /** Default stack is Next.js + TypeScript when nothing detected and --yes. */
192
+ /** Default stack is first preset when nothing is detected and --yes is used. */
204
193
  function defaults(detected, docHints = {}) {
205
194
  const hasDetected = detected.stacks.length > 0;
206
- const fallback = STACK_PRESETS[0]; // Next.js (TypeScript)
195
+ const fallback = STACK_PRESETS[0];
207
196
  return {
208
197
  projectName: docHints.projectName || detected.projectName,
209
198
  oneLiner: docHints.oneLiner || '',
@@ -10,6 +10,7 @@ import { log } from '../util/log.mjs';
10
10
  // awesome-copilot skills are discovered dynamically via `skills find`.
11
11
  const AWESOME_COPILOT_REPO = 'github/awesome-copilot';
12
12
  const BREADCRUMB_BOX_WIDTH = 66;
13
+ const PNPM_INSTALL_DOCS_URL = 'https://pnpm.io/installation';
13
14
 
14
15
  // Well-known skill repos matched by stack term → repo + suggested skill names (skills.sh)
15
16
  const SKILL_CATALOG = [
@@ -22,6 +23,15 @@ const SKILL_CATALOG = [
22
23
  { terms: ['rust'], repo: 'anthropics/skills', skills: ['code-review'] },
23
24
  ];
24
25
 
26
+ // Core skills are the always-on baseline curated by cli-five.
27
+ // Stack-specific and discovered skills are suggestions and must be opted-in.
28
+ const CORE_CATALOG_SKILLS = new Set([
29
+ 'anthropics/skills@frontend-design',
30
+ 'anthropics/skills@skill-creator',
31
+ 'vercel-labs/agent-skills@vercel-react-best-practices',
32
+ 'vercel-labs/agent-skills@web-design-guidelines',
33
+ ]);
34
+
25
35
  // ── Environment detection ─────────────────────────────────────────────
26
36
 
27
37
  function resolveSkillsBin() {
@@ -113,18 +123,24 @@ export async function skillDiscovery({ cwd, answers, args }) {
113
123
 
114
124
  if (!env) {
115
125
  log.warn('Cannot run skills CLI: no bundled binary, pnpm, or npx found.');
116
- log.warn('Install Node.js (includes npx) or pnpm, then re-run.');
126
+ log.warn(`Install Node.js (includes npx) or pnpm, then re-run. ${PNPM_INSTALL_DOCS_URL}`);
117
127
  printBreadcrumbs();
118
128
  return;
119
129
  }
120
130
 
131
+ if (env.pnpmVer) {
132
+ log.ok(`pnpm detected (${env.pnpmVer}).`);
133
+ } else {
134
+ log.dim('Tip: pnpm is recommended for faster installs and stricter dependency resolution.');
135
+ }
136
+
121
137
  // Offer pnpm if the user doesn't have it
122
138
  if (shouldOfferPnpmInstall(env)) {
123
139
  const { wantPnpm } = await prompts({
124
140
  type: 'confirm',
125
141
  name: 'wantPnpm',
126
- message: 'pnpm not found. Install it? (faster, stricter deps, saves disk)',
127
- initial: false,
142
+ message: 'pnpm not found. Install it now? (recommended)',
143
+ initial: true,
128
144
  });
129
145
  if (wantPnpm) {
130
146
  try {
@@ -133,10 +149,9 @@ export async function skillDiscovery({ cwd, answers, args }) {
133
149
  env = detectEnv(cwd) || env;
134
150
  } catch (err) {
135
151
  log.warn(`pnpm install failed: ${err.message}`);
152
+ log.warn(`Install pnpm manually: ${PNPM_INSTALL_DOCS_URL}`);
136
153
  }
137
154
  }
138
- } else if (env.projectPnpm && !env.pnpmVer) {
139
- log.dim(`pnpm not found. Using ${env.label} for skill discovery.`);
140
155
  }
141
156
 
142
157
  log.ok(`Running skills via ${env.label}`);
@@ -189,19 +204,20 @@ export async function skillDiscovery({ cwd, answers, args }) {
189
204
  choices.push({
190
205
  title: `${kleur.cyan('⬡')} ${r.skill} ${kleur.dim(`(${r.installs})`)} ${kleur.cyan('← awesome-copilot')}`,
191
206
  value: { source: 'awesome', repo: r.repo, skill: r.skill, ref: r.ref },
192
- selected: true,
207
+ selected: false,
193
208
  });
194
209
  }
195
210
 
196
211
  // Static catalog recs (verified repos)
197
212
  for (const r of catalogRecs) {
198
213
  const ref = `${r.repo}@${r.skill}`;
214
+ const core = isCoreCatalogSkill(r.repo, r.skill);
199
215
  if (seen.has(ref)) continue;
200
216
  seen.add(ref);
201
217
  choices.push({
202
- title: `${kleur.yellow('◆')} ${r.skill} ${kleur.dim(`(${r.repo})`)} ${kleur.yellow('← skills.sh')}`,
218
+ title: `${kleur.yellow('◆')} ${r.skill} ${kleur.dim(`(${r.repo})`)} ${kleur.yellow(core ? '← core' : '← skills.sh (suggested)')}`,
203
219
  value: { source: 'catalog', ref, repo: r.repo, skill: r.skill },
204
- selected: true,
220
+ selected: core,
205
221
  });
206
222
  }
207
223
 
@@ -222,6 +238,8 @@ export async function skillDiscovery({ cwd, answers, args }) {
222
238
 
223
239
  if (choices.length > 0) {
224
240
  log.raw('');
241
+ log.dim('Suggested skills are not pre-selected. Press Space to install only what you need.');
242
+ log.dim('Read every installed skill so you understand behavior and catch potential conflicts early.');
225
243
  const { toInstall } = await prompts({
226
244
  type: 'multiselect',
227
245
  name: 'toInstall',
@@ -490,6 +508,10 @@ function buildRecommendations(a) {
490
508
  return out;
491
509
  }
492
510
 
511
+ function isCoreCatalogSkill(repo, skill) {
512
+ return CORE_CATALOG_SKILLS.has(`${repo}@${skill}`);
513
+ }
514
+
493
515
  function suggestSearches(a) {
494
516
  const out = new Set();
495
517
  for (const s of a.stack || []) {
@@ -535,7 +557,7 @@ function pad(s, n) {
535
557
  * and can bootstrap it via npm on PATH.
536
558
  */
537
559
  function shouldOfferPnpmInstall(env) {
538
- return Boolean(env && env.projectPnpm && !env.pnpmVer && env.npmVer);
560
+ return Boolean(env && !env.pnpmVer && env.npmVer);
539
561
  }
540
562
 
541
563
  function buildBreadcrumbBox() {
@@ -601,6 +623,7 @@ export const __testables = {
601
623
  buildBreadcrumbBox,
602
624
  detectEnv,
603
625
  formatBoxLine,
626
+ isCoreCatalogSkill,
604
627
  shouldOfferPnpmInstall,
605
628
  stripAnsi,
606
629
  };
@@ -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: Claude Opus 4.6 (copilot)
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
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: Planner
3
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)
4
+ model: Claude Sonnet 4.6 (copilot)
5
5
  tools: ['read', 'search', 'web', 'io.github.upstash/context7/*', 'vscode/memory']
6
6
  ---
7
7
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: Reviewer
3
3
  description: "Reviews code and agent output for correctness, convention compliance, and architectural alignment. Use when: code review, auditing agent work, validating against specs."
4
- model: Claude Opus 4.6 (copilot)
4
+ model: Claude Sonnet 4.6 (copilot)
5
5
  tools: ['read', 'search', 'web', 'vscode/memory']
6
6
  agents: []
7
7
  ---