@bamptee/aia-code 0.8.0 → 0.10.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
@@ -35,9 +35,10 @@ Each CLI manages its own authentication. Run `claude`, `codex`, or `gemini` once
35
35
  | `aia next <feature> [description]` | Run the next pending step automatically |
36
36
  | `aia status <feature>` | Show the current status of a feature |
37
37
  | `aia reset <step> <feature>` | Reset a step to pending so it can be re-run |
38
+ | `aia quick <name> [description]` | Quick story/ticket: dev-plan → implement → review only |
38
39
  | `aia repo scan` | Scan codebase and generate `repo-map.json` |
39
40
 
40
- ### Options for `run` and `next`
41
+ ### Options for `run`, `next`, and `quick`
41
42
 
42
43
  | Flag | Description |
43
44
  |------|-------------|
@@ -219,6 +220,33 @@ aia run ba-spec session-replay
219
220
  aia run tech-spec session-replay
220
221
  ```
221
222
 
223
+ #### Initial specs (`init.md`)
224
+
225
+ When you create a feature, AIA generates an `init.md` file. Edit it to add your initial specs, requirements, and constraints -- this content is injected into **every step** as context:
226
+
227
+ ```bash
228
+ aia feature session-replay
229
+ # Edit .aia/features/session-replay/init.md with your specs
230
+ aia next session-replay
231
+ ```
232
+
233
+ ```markdown
234
+ <!-- .aia/features/session-replay/init.md -->
235
+ # session-replay
236
+
237
+ ## Description
238
+ Record and replay user sessions for debugging.
239
+
240
+ ## Existing specs
241
+ - Capture DOM snapshots every 500ms
242
+ - Record network requests and console logs
243
+ - Max session duration: 30 minutes
244
+
245
+ ## Constraints
246
+ - Must work with our existing React 18 + Express stack
247
+ - Storage budget: max 5MB per session
248
+ ```
249
+
222
250
  #### Using `next` (recommended)
223
251
 
224
252
  `next` automatically picks the next pending step:
@@ -253,6 +281,26 @@ aia reset tech-spec session-replay
253
281
  aia run tech-spec session-replay "Add WebSocket support and rate limiting"
254
282
  ```
255
283
 
284
+ #### Quick mode (stories & tickets)
285
+
286
+ For small stories or tickets that don't need the full 8-step pipeline, use `aia quick`. It skips brief, ba-spec, questions, tech-spec, and challenge, and runs only **dev-plan → implement → review**:
287
+
288
+ ```bash
289
+ # Create feature + run 3 steps in sequence
290
+ aia quick fix-login-bug "Fix the login timeout issue on mobile"
291
+
292
+ # Or create the feature first, edit init.md, then run
293
+ aia feature fix-login-bug
294
+ # Edit .aia/features/fix-login-bug/init.md with details
295
+ aia quick fix-login-bug
296
+ ```
297
+
298
+ The `init.md` file serves as the sole input context for the dev-plan step. Verbose and apply flags work the same way:
299
+
300
+ ```bash
301
+ aia quick add-rate-limit "Add rate limiting to the /api/upload endpoint" -v
302
+ ```
303
+
256
304
  ### 8. Print mode vs Agent mode
257
305
 
258
306
  By default, AIA runs in **print mode** -- the AI generates text (specs, plans, reviews) saved to `.md` files.
@@ -326,7 +374,7 @@ knowledge:
326
374
 
327
375
  ## Prompt assembly
328
376
 
329
- When you run a step, the prompt is built from up to 6 sections:
377
+ When you run a step, the prompt is built from up to 7 sections:
330
378
 
331
379
  ```
332
380
  === DESCRIPTION ===
@@ -338,6 +386,9 @@ When you run a step, the prompt is built from up to 6 sections:
338
386
  === KNOWLEDGE ===
339
387
  (all .md files from the knowledge categories)
340
388
 
389
+ === INITIAL SPECS ===
390
+ (content of init.md -- your initial specs and requirements)
391
+
341
392
  === FEATURE ===
342
393
  (outputs of all prior steps for this feature)
343
394
 
@@ -368,6 +419,7 @@ src/
368
419
  feature.js # aia feature <name>
369
420
  run.js # aia run <step> <feature>
370
421
  next.js # aia next <feature>
422
+ quick.js # aia quick <name> [description]
371
423
  status.js # aia status <feature>
372
424
  reset.js # aia reset <step> <feature>
373
425
  repo.js # aia repo scan
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bamptee/aia-code",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "description": "AI Architecture Assistant - orchestrate AI-assisted development workflows via CLI tools (Claude, Codex, Gemini)",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/cli.js CHANGED
@@ -6,6 +6,7 @@ import { registerRepoCommand } from './commands/repo.js';
6
6
  import { registerStatusCommand } from './commands/status.js';
7
7
  import { registerResetCommand } from './commands/reset.js';
8
8
  import { registerNextCommand } from './commands/next.js';
9
+ import { registerQuickCommand } from './commands/quick.js';
9
10
 
10
11
  export function createCli() {
11
12
  const program = new Command();
@@ -19,6 +20,7 @@ export function createCli() {
19
20
  registerFeatureCommand(program);
20
21
  registerRunCommand(program);
21
22
  registerNextCommand(program);
23
+ registerQuickCommand(program);
22
24
  registerRepoCommand(program);
23
25
  registerStatusCommand(program);
24
26
  registerResetCommand(program);
@@ -1,5 +1,7 @@
1
+ import path from 'node:path';
1
2
  import chalk from 'chalk';
2
3
  import { createFeature } from '../services/feature.js';
4
+ import { AIA_DIR } from '../constants.js';
3
5
 
4
6
  export function registerFeatureCommand(program) {
5
7
  program
@@ -8,7 +10,9 @@ export function registerFeatureCommand(program) {
8
10
  .action(async (name) => {
9
11
  try {
10
12
  await createFeature(name);
13
+ const initPath = path.join(AIA_DIR, 'features', name, 'init.md');
11
14
  console.log(chalk.green(`Feature "${name}" created.`));
15
+ console.log(chalk.gray(`Edit ${initPath} to add your initial specs and requirements.`));
12
16
  } catch (err) {
13
17
  console.error(chalk.red(err.message));
14
18
  process.exit(1);
@@ -0,0 +1,62 @@
1
+ import chalk from 'chalk';
2
+ import fs from 'fs-extra';
3
+ import path from 'node:path';
4
+ import yaml from 'yaml';
5
+ import { AIA_DIR, FEATURE_STEPS, QUICK_STEPS, STEP_STATUS } from '../constants.js';
6
+ import { createFeature, validateFeatureName } from '../services/feature.js';
7
+ import { runStep } from '../services/runner.js';
8
+
9
+ async function skipEarlySteps(feature, root) {
10
+ const statusFile = path.join(root, AIA_DIR, 'features', feature, 'status.yaml');
11
+ const raw = await fs.readFile(statusFile, 'utf-8');
12
+ const status = yaml.parse(raw);
13
+
14
+ for (const step of FEATURE_STEPS) {
15
+ if (!QUICK_STEPS.includes(step)) {
16
+ status.steps[step] = STEP_STATUS.DONE;
17
+ }
18
+ }
19
+ status.current_step = QUICK_STEPS[0];
20
+
21
+ await fs.writeFile(statusFile, yaml.stringify(status), 'utf-8');
22
+ }
23
+
24
+ export function registerQuickCommand(program) {
25
+ program
26
+ .command('quick <name> [description]')
27
+ .description('Quick story/ticket: create feature then run dev-plan → implement → review')
28
+ .option('-v, --verbose', 'Show AI thinking/tool usage')
29
+ .option('-a, --apply', 'Force agent mode (file editing) for all steps')
30
+ .action(async (name, description, opts) => {
31
+ try {
32
+ validateFeatureName(name);
33
+
34
+ const root = process.cwd();
35
+ const featureDir = path.join(root, AIA_DIR, 'features', name);
36
+
37
+ if (!(await fs.pathExists(featureDir))) {
38
+ await createFeature(name, root);
39
+ console.log(chalk.green(`Feature "${name}" created.`));
40
+ const initPath = path.join(AIA_DIR, 'features', name, 'init.md');
41
+ console.log(chalk.gray(`Using ${initPath} as input.`));
42
+ }
43
+
44
+ await skipEarlySteps(name, root);
45
+
46
+ for (const step of QUICK_STEPS) {
47
+ console.log(chalk.cyan(`\n--- Running ${step} ---\n`));
48
+ await runStep(step, name, {
49
+ description,
50
+ verbose: opts.verbose,
51
+ apply: opts.apply,
52
+ root,
53
+ });
54
+ }
55
+
56
+ console.log(chalk.green(`\nQuick pipeline completed for "${name}".`));
57
+ } catch (err) {
58
+ console.error(chalk.red(err.message));
59
+ process.exit(1);
60
+ }
61
+ });
62
+ }
package/src/constants.js CHANGED
@@ -36,6 +36,8 @@ export const FEATURE_STEPS = [
36
36
  'review',
37
37
  ];
38
38
 
39
+ export const QUICK_STEPS = ['dev-plan', 'implement', 'review'];
40
+
39
41
  export const APPLY_STEPS = new Set([
40
42
  'implement',
41
43
  ]);
@@ -44,6 +44,11 @@ async function loadFeatureFiles(feature, step, root) {
44
44
  return sections.join('\n\n');
45
45
  }
46
46
 
47
+ async function loadInitSpecs(feature, root) {
48
+ const filePath = path.join(root, AIA_DIR, 'features', feature, 'init.md');
49
+ return readIfExists(filePath);
50
+ }
51
+
47
52
  async function loadPreviousOutput(feature, step, root) {
48
53
  const filePath = path.join(root, AIA_DIR, 'features', feature, `${step}.md`);
49
54
  return readIfExists(filePath);
@@ -75,9 +80,10 @@ async function loadPromptTemplate(step, root) {
75
80
  export async function buildPrompt(feature, step, { description, root = process.cwd() } = {}) {
76
81
  const config = await loadConfig(root);
77
82
 
78
- const [context, knowledgeCategories, featureContent, previousOutput, task] = await Promise.all([
83
+ const [context, knowledgeCategories, initSpecs, featureContent, previousOutput, task] = await Promise.all([
79
84
  loadContextFiles(config, root),
80
85
  resolveKnowledgeCategories(feature, config, root),
86
+ loadInitSpecs(feature, root),
81
87
  loadFeatureFiles(feature, step, root),
82
88
  loadPreviousOutput(feature, step, root),
83
89
  loadPromptTemplate(step, root),
@@ -99,6 +105,11 @@ export async function buildPrompt(feature, step, { description, root = process.c
99
105
  parts.push('\n\n=== KNOWLEDGE ===\n');
100
106
  parts.push(knowledge || '(no knowledge)');
101
107
 
108
+ if (initSpecs) {
109
+ parts.push('\n\n=== INITIAL SPECS ===\n');
110
+ parts.push(initSpecs);
111
+ }
112
+
102
113
  parts.push('\n\n=== FEATURE ===\n');
103
114
  parts.push(featureContent || '(no prior steps)');
104
115
 
@@ -5,6 +5,7 @@ import { AIA_DIR, FEATURE_STEPS } from '../constants.js';
5
5
 
6
6
  const FEATURE_FILES = [
7
7
  'status.yaml',
8
+ 'init.md',
8
9
  ...FEATURE_STEPS.map((s) => `${s}.md`),
9
10
  ];
10
11
 
@@ -18,6 +19,23 @@ export function validateFeatureName(name) {
18
19
  }
19
20
  }
20
21
 
22
+ function buildInitMd(name) {
23
+ return `# ${name}
24
+
25
+ <!-- Describe your feature here. This file is injected into every step as context. -->
26
+ <!-- Add any initial specs, requirements, mockups, or notes you already have. -->
27
+
28
+ ## Description
29
+
30
+
31
+ ## Existing specs
32
+
33
+
34
+ ## Constraints
35
+
36
+ `;
37
+ }
38
+
21
39
  function buildStatusYaml(name) {
22
40
  const steps = {};
23
41
  for (const step of FEATURE_STEPS) {
@@ -45,7 +63,9 @@ export async function createFeature(name, root = process.cwd()) {
45
63
 
46
64
  for (const file of FEATURE_FILES) {
47
65
  const filePath = path.join(featureDir, file);
48
- const content = file === 'status.yaml' ? buildStatusYaml(name) : '';
66
+ let content = '';
67
+ if (file === 'status.yaml') content = buildStatusYaml(name);
68
+ else if (file === 'init.md') content = buildInitMd(name);
49
69
  await fs.writeFile(filePath, content, 'utf-8');
50
70
  }
51
71
  }