@grvmithas/create-aies-kit 1.0.0 → 1.3.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/README.md CHANGED
@@ -1,44 +1,55 @@
1
1
  # @grvmithas/create-aies-kit
2
2
 
3
- Scaffold an **AIES** (AI Engineering Standard) harness into your app repo in under a minute.
3
+ Scaffold a **complete AIES harness** into your repo using **IDE-native paths** (no `.aies/` folder).
4
4
 
5
5
  ```bash
6
- npx @grvmithas/create-aies-kit
6
+ npx @grvmithas/create-aies-kit@latest \
7
+ --stack nextjs --ide cursor --role fullstack \
8
+ --maturity intermediate --goal new-product \
9
+ --model claude --data-class internal --yes
7
10
  ```
8
11
 
9
- Or non-interactive:
12
+ Then enhance for *this* repository:
10
13
 
11
14
  ```bash
12
- npx @grvmithas/create-aies-kit --stack nextjs --ide cursor --role fullstack --maturity intermediate --goal new-product --yes
15
+ npx @grvmithas/create-aies-kit@latest enhance
13
16
  ```
14
17
 
15
- ## What it writes
18
+ Then open `*/prompts/enhance-repo.prompt.md` in your IDE agent so it adapts artifacts to your conventions.
19
+
20
+ ## Layout contract
21
+
22
+ | Location | Contents |
23
+ |----------|----------|
24
+ | IDE folder (`.cursor` / `.github` / `.claude` / …) | **prompts**, **skills**, **agents** only (+ IDE rules / MCP config) |
25
+ | Repo root | `cookbook/{stack}/`, `guides/`, `mcps/`, `templates/`, `MODEL_POLICY.md`, root instruction files |
26
+
27
+ **Anti-pattern:** Nesting cookbook (or guides/MCP specs) under `.github/`. That folder is for Copilot discovery and GitHub metadata only.
28
+
29
+ ## What you get
16
30
 
17
31
  | Path | Purpose |
18
32
  |------|---------|
19
- | `.aies/` | Plan, prompts, skills, MCP/hooks stubs |
20
- | IDE rules | e.g. `.cursor/rules/aies.mdc`, `CLAUDE.md`, `.github/copilot-instructions.md` |
33
+ | `AIES.md` | Operator guide — plans, prompts, skills, MCP, enhance |
34
+ | `implementation_plan.md` | Plan of record |
35
+ | `AGENTS.md` | Multi-agent / IDE agent contract |
36
+ | `CLAUDE.md` | Root Claude / multi-IDE contract |
37
+ | `copilot-instructions.md` | Root Copilot instructions |
38
+ | `.github/copilot-instructions.md` | Copilot discovery copy |
39
+ | IDE `prompts/` `skills/` `agents/` | Lifecycle + create/enhance artifacts |
40
+ | `cookbook/{stack}/` | Full stack cookbook at **repo root** |
21
41
 
22
- ## Flags
42
+ Maturity only changes the **reading path** in `AIES.md`.
23
43
 
24
- | Flag | Values |
25
- |------|--------|
26
- | `--stack` | `react`, `nextjs`, `react-native`, `nodejs`, `nestjs`, `python`, `fastapi`, `java`, `dotnet` |
27
- | `--ide` | `cursor`, `copilot`, `claude-code`, `vscode`, `windsurf`, `continue` |
28
- | `--role` | `product-manager`, `architect`, `frontend`, `backend`, `fullstack`, `qa`, `devops`, `engineering-manager`, `ai-engineer` |
29
- | `--maturity` | `beginner`, `intermediate`, `advanced`, `enterprise` |
30
- | `--goal` | `new-product`, `existing-codebase`, `legacy-modernize`, `learn`, `browse-standards`, `explore-examples` |
31
- | `--force` | Overwrite existing files |
32
- | `--dry-run` | Print paths without writing |
33
- | `--yes` / `-y` | Skip confirmations when all flags are set |
44
+ ## MCP
34
45
 
35
- ## After install
46
+ `mcpServers` starts empty. `_aiesRecommended` holds enable-ready stubs (stack + enhance scan). Copy after human approval; never commit secrets.
36
47
 
37
- 1. Fill `.aies/implementation_plan.md`
38
- 2. Attach it in IDE chat before coding
39
- 3. Continue: https://open-ai-engineering-standards.vercel.app/workflows
48
+ Docs: https://www.ai-standards.dev/quickstart
40
49
 
41
- ## Docs
50
+ ## Changelog
42
51
 
43
- - Quick start: https://open-ai-engineering-standards.vercel.app/quickstart
44
- - Corpus: https://github.com/grvmithas/open-ai-engineering-standards
52
+ - **1.3.0** — Ephemeral `plans/{STORY_ID}-plan.md` + `reviews/{STORY_ID}-code-review.md`; agent hooks shipped; enhance-repo v2 with IDE chat invoke + deep guardrail scan (lint/style FE+BE).
53
+ - **1.2.0** — Layout fix: cookbook/guides/mcps/templates at repo root for all IDEs; `.github` holds prompts/skills/agents (+ copilot-instructions) only.
54
+ - **1.1.0** — Self-contained package (embedded corpus + generator).
55
+ - **1.0.0** — Initial publish (incomplete; do not use).
@@ -1,19 +1,38 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { mkdir, writeFile, access } from 'node:fs/promises';
3
+ import { mkdir, writeFile, access, readFile } from 'node:fs/promises';
4
4
  import { dirname, join, resolve } from 'node:path';
5
5
  import { constants } from 'node:fs';
6
- import { GOALS, ROLES, MATURITIES, IDES, STACKS, idsOf } from '../lib/options.js';
7
- import { generateStarterKit } from '../lib/scaffold.js';
6
+ import {
7
+ GOALS,
8
+ ROLES,
9
+ MATURITIES,
10
+ IDES,
11
+ MODELS,
12
+ DATA_CLASSES,
13
+ STACKS,
14
+ STACK_LABELS,
15
+ idsOf,
16
+ } from '../lib/kit-core/options.js';
17
+ import { enhanceStarterKit, generateStarterKit, layoutFor } from '../lib/kit-core/generate.js';
8
18
  import { choose, confirm } from '../lib/prompts.js';
9
19
 
10
20
  function printHelp() {
11
21
  console.log(`
12
- create-aies-kit — scaffold an AIES project harness
22
+ create-aies-kit — complete AIES harness in IDE-native paths (no .aies/)
13
23
 
14
24
  Usage:
15
25
  npx @grvmithas/create-aies-kit
16
- npx @grvmithas/create-aies-kit --stack nextjs --ide cursor --role fullstack --maturity intermediate --goal new-product --yes
26
+ npx @grvmithas/create-aies-kit --stack nextjs --ide cursor --role fullstack --maturity intermediate --goal new-product --model claude --data-class internal --yes
27
+ npx @grvmithas/create-aies-kit enhance
28
+
29
+ Install writes: AIES.md, implementation_plan.md, CLAUDE.md, AGENTS.md,
30
+ IDE prompts/skills/agents under .cursor | .github | .claude | …
31
+ plus repo-root cookbook/, guides/, mcps/, templates/ (never under .github/cookbook).
32
+
33
+
34
+ After install, run enhance (no --yes needed) to scan the repo and refresh MCP recommendations, then
35
+ run the enhance-repo prompt in your IDE.
17
36
 
18
37
  Flags:
19
38
  --stack ${idsOf(STACKS).join(' | ')}
@@ -21,28 +40,32 @@ Flags:
21
40
  --role ${idsOf(ROLES).join(' | ')}
22
41
  --maturity ${idsOf(MATURITIES).join(' | ')}
23
42
  --goal ${idsOf(GOALS).join(' | ')}
43
+ --model ${idsOf(MODELS).join(' | ')}
44
+ --data-class ${idsOf(DATA_CLASSES).join(' | ')}
24
45
  --force Overwrite existing files
25
46
  --dry-run Print files without writing
26
- --yes, -y Non-interactive when all profile flags are set
47
+ --yes, -y Non-interactive when profile flags are set
27
48
  --help, -h Show help
28
49
  `);
29
50
  }
30
51
 
31
52
  function parseArgs(argv) {
32
53
  /** @type {Record<string, string | boolean>} */
33
- const out = {};
54
+ const out = { _: [] };
34
55
  for (let i = 0; i < argv.length; i += 1) {
35
56
  const arg = argv[i];
36
57
  if (arg === '--help' || arg === '-h') out.help = true;
37
58
  else if (arg === '--force') out.force = true;
38
59
  else if (arg === '--dry-run') out.dryRun = true;
39
60
  else if (arg === '--yes' || arg === '-y') out.yes = true;
40
- else if (arg.startsWith('--') && argv[i + 1] && !argv[i + 1].startsWith('--')) {
41
- out[arg.slice(2)] = argv[i + 1];
42
- i += 1;
43
- } else if (arg.startsWith('--') && arg.includes('=')) {
61
+ else if (arg.startsWith('--') && arg.includes('=')) {
44
62
  const [k, v] = arg.slice(2).split('=');
45
63
  out[k] = v;
64
+ } else if (arg.startsWith('--') && argv[i + 1] && !argv[i + 1].startsWith('--')) {
65
+ out[arg.slice(2)] = argv[i + 1];
66
+ i += 1;
67
+ } else if (!arg.startsWith('--')) {
68
+ out._.push(arg);
46
69
  }
47
70
  }
48
71
  return out;
@@ -67,7 +90,6 @@ async function pathExists(path) {
67
90
  async function writeBundle(cwd, files, { force, dryRun }) {
68
91
  const written = [];
69
92
  const skipped = [];
70
-
71
93
  for (const [relPath, content] of Object.entries(files)) {
72
94
  const abs = join(cwd, relPath);
73
95
  const exists = await pathExists(abs);
@@ -83,49 +105,96 @@ async function writeBundle(cwd, files, { force, dryRun }) {
83
105
  await writeFile(abs, content, 'utf8');
84
106
  written.push(relPath);
85
107
  }
86
-
87
108
  return { written, skipped };
88
109
  }
89
110
 
111
+ function stackIdFromLabel(label) {
112
+ const entry = Object.entries(STACK_LABELS).find(([, v]) => v === label);
113
+ return entry?.[0];
114
+ }
115
+
116
+ async function recoverProfile(cwd, args) {
117
+ const dataClass = args['data-class'] || args.dataClass;
118
+ let profile = {
119
+ goal: args.goal,
120
+ role: args.role,
121
+ maturity: args.maturity,
122
+ ide: args.ide,
123
+ model: args.model,
124
+ dataClass,
125
+ stack: args.stack,
126
+ };
127
+
128
+ if (Object.values(profile).every(Boolean)) return profile;
129
+
130
+ try {
131
+ const aies = await readFile(join(cwd, 'AIES.md'), 'utf8');
132
+ const m = aies.match(
133
+ /\*\*Profile:\*\*\s*(\S+)\s*·\s*(\S+)\s*·\s*(\S+)\s*·\s*([^*·]+?)\s*·\s*model\s*\*\*([^*]+)\*\*\s*·\s*data\s*\*\*([^*]+)\*\*/,
134
+ );
135
+ if (m) {
136
+ const label = m[4].trim();
137
+ profile = {
138
+ goal: profile.goal || 'existing-codebase',
139
+ role: profile.role || m[1],
140
+ ide: profile.ide || m[2],
141
+ maturity: profile.maturity || m[3],
142
+ stack: profile.stack || stackIdFromLabel(label) || 'nextjs',
143
+ model: profile.model || m[5].trim(),
144
+ dataClass: profile.dataClass || m[6].trim(),
145
+ };
146
+ }
147
+ } catch {
148
+ // no AIES.md yet
149
+ }
150
+
151
+ return profile;
152
+ }
153
+
90
154
  async function main() {
91
- const args = parseArgs(process.argv.slice(2));
155
+ const rawArgv = process.argv.slice(2);
156
+ const isEnhance = rawArgv[0] === 'enhance';
157
+ const args = parseArgs(isEnhance ? rawArgv.slice(1) : rawArgv);
158
+
92
159
  if (args.help) {
93
160
  printHelp();
94
161
  return;
95
162
  }
96
163
 
97
- assertChoice('stack', args.stack, idsOf(STACKS));
98
- assertChoice('ide', args.ide, idsOf(IDES));
99
- assertChoice('role', args.role, idsOf(ROLES));
100
- assertChoice('maturity', args.maturity, idsOf(MATURITIES));
101
- assertChoice('goal', args.goal, idsOf(GOALS));
164
+ const cwd = resolve(process.cwd());
165
+ let profile = await recoverProfile(cwd, args);
102
166
 
103
- let profile = {
104
- goal: /** @type {string} */ (args.goal),
105
- role: /** @type {string} */ (args.role),
106
- maturity: /** @type {string} */ (args.maturity),
107
- ide: /** @type {string} */ (args.ide),
108
- stack: /** @type {string} */ (args.stack),
109
- };
167
+ assertChoice('stack', profile.stack, idsOf(STACKS));
168
+ assertChoice('ide', profile.ide, idsOf(IDES));
169
+ assertChoice('role', profile.role, idsOf(ROLES));
170
+ assertChoice('maturity', profile.maturity, idsOf(MATURITIES));
171
+ assertChoice('goal', profile.goal, idsOf(GOALS));
172
+ assertChoice('model', profile.model, idsOf(MODELS));
173
+ assertChoice('data-class', profile.dataClass, idsOf(DATA_CLASSES));
110
174
 
111
175
  const missing = Object.entries(profile).filter(([, v]) => !v).map(([k]) => k);
112
176
  if (missing.length > 0) {
113
177
  if (args.yes) {
114
- throw new Error(`Missing required flags in --yes mode: ${missing.join(', ')}`);
178
+ throw new Error(
179
+ `Missing required profile fields: ${missing.join(', ')}. Pass flags or run install first so AIES.md exists.`,
180
+ );
115
181
  }
116
182
  console.log('AIES starter kit — answer a few questions (or pass flags for CI).');
117
183
  if (!profile.goal) profile.goal = await choose('What is your goal?', GOALS, 'new-product');
118
184
  if (!profile.role) profile.role = await choose('What is your role?', ROLES, 'fullstack');
119
185
  if (!profile.maturity) profile.maturity = await choose('AI experience?', MATURITIES, 'intermediate');
120
186
  if (!profile.ide) profile.ide = await choose('Which IDE?', IDES, 'cursor');
187
+ if (!profile.model) profile.model = await choose('Primary model / provider?', MODELS, 'claude');
188
+ if (!profile.dataClass) profile.dataClass = await choose('Data class for this project?', DATA_CLASSES, 'internal');
121
189
  if (!profile.stack) profile.stack = await choose('Technology stack?', STACKS, 'nextjs');
122
190
  }
123
191
 
124
- const cwd = resolve(process.cwd());
125
192
  console.log(`\nTarget directory: ${cwd}`);
126
- console.log(`Profile: ${profile.stack} · ${profile.ide} · ${profile.role} · ${profile.maturity}`);
193
+ console.log(
194
+ `Mode: ${isEnhance ? 'enhance' : 'install'} · ${profile.stack} · ${profile.ide} · ${profile.role} · ${profile.maturity} · ${profile.model} · ${profile.dataClass}`,
195
+ );
127
196
 
128
- if (!args.yes && !args.dryRun) {
197
+ if (!args.yes && !args.dryRun && !isEnhance) {
129
198
  const ok = await confirm('Write AIES harness files here?', true);
130
199
  if (!ok) {
131
200
  console.log('Cancelled.');
@@ -134,29 +203,38 @@ async function main() {
134
203
  }
135
204
  }
136
205
 
137
- const bundle = generateStarterKit(profile);
206
+ const bundle = isEnhance ? enhanceStarterKit(cwd, profile) : generateStarterKit(profile);
207
+ // enhance always overwrites generated harness files so MCP recommendations refresh
208
+ const force = Boolean(args.force) || isEnhance;
138
209
  const { written, skipped } = await writeBundle(cwd, bundle.files, {
139
- force: Boolean(args.force),
210
+ force,
140
211
  dryRun: Boolean(args.dryRun),
141
212
  });
142
213
 
143
214
  if (args.dryRun) {
144
- console.log('\nDry run — would write:');
145
- written.forEach(f => console.log(` ${f}`));
215
+ console.log(`\nDry run — would write ${written.length} file(s):`);
216
+ written.slice(0, 40).forEach(f => console.log(` ${f}`));
217
+ if (written.length > 40) console.log(` … +${written.length - 40} more`);
146
218
  } else {
147
- console.log(`\nWrote ${written.length} file(s):`);
148
- written.forEach(f => console.log(` ✓ ${f}`));
219
+ console.log(`\nWrote ${written.length} file(s).`);
220
+ written.slice(0, 25).forEach(f => console.log(` ✓ ${f}`));
221
+ if (written.length > 25) console.log(` … +${written.length - 25} more`);
149
222
  }
150
223
 
151
224
  if (skipped.length > 0) {
152
- console.log(`\nSkipped ${skipped.length} existing file(s) (use --force to overwrite):`);
153
- skipped.forEach(f => console.log(` · ${f}`));
225
+ console.log(`\nSkipped ${skipped.length} existing file(s) (use --force):`);
226
+ skipped.slice(0, 10).forEach(f => console.log(` · ${f}`));
154
227
  }
155
228
 
229
+ const L = layoutFor(profile.ide);
156
230
  console.log('\nNext:');
157
- console.log(' 1. Fill .aies/implementation_plan.md');
158
- console.log(' 2. Attach it in IDE chat before coding');
159
- console.log(' 3. https://open-ai-engineering-standards.vercel.app/workflows');
231
+ console.log(' 1. Read AIES.md');
232
+ if (!isEnhance) {
233
+ console.log(' 2. npx @grvmithas/create-aies-kit enhance');
234
+ }
235
+ console.log(` ${isEnhance ? '2' : '3'}. Run ${L.promptsDir}/enhance-repo.prompt.md in your IDE agent`);
236
+ console.log(` ${isEnhance ? '3' : '4'}. Fill implementation_plan.md`);
237
+ console.log(` ${isEnhance ? '4' : '5'}. https://www.ai-standards.dev/workflows`);
160
238
  }
161
239
 
162
240
  main().catch(err => {