@rasensio/aidlc 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/README.md +251 -0
- package/capabilities/claude-code.yaml +9 -0
- package/capabilities/codex.yaml +8 -0
- package/capabilities/cursor.yaml +8 -0
- package/capabilities/kiro.yaml +9 -0
- package/capabilities/windsurf.yaml +8 -0
- package/ci/aidlc-gate.yml +100 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +39 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/add-action.d.ts +83 -0
- package/dist/commands/add-action.d.ts.map +1 -0
- package/dist/commands/add-action.js +437 -0
- package/dist/commands/add-action.js.map +1 -0
- package/dist/commands/continue.d.ts +23 -0
- package/dist/commands/continue.d.ts.map +1 -0
- package/dist/commands/continue.js +238 -0
- package/dist/commands/continue.js.map +1 -0
- package/dist/commands/discover.d.ts +19 -0
- package/dist/commands/discover.d.ts.map +1 -0
- package/dist/commands/discover.js +85 -0
- package/dist/commands/discover.js.map +1 -0
- package/dist/commands/docs.d.ts +25 -0
- package/dist/commands/docs.d.ts.map +1 -0
- package/dist/commands/docs.js +282 -0
- package/dist/commands/docs.js.map +1 -0
- package/dist/commands/gate.d.ts +25 -0
- package/dist/commands/gate.d.ts.map +1 -0
- package/dist/commands/gate.js +168 -0
- package/dist/commands/gate.js.map +1 -0
- package/dist/commands/init.d.ts +24 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +187 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/review.d.ts +60 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +264 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/setup.d.ts +24 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +206 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/start.d.ts +27 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +243 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +25 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +263 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/transition.d.ts +30 -0
- package/dist/commands/transition.d.ts.map +1 -0
- package/dist/commands/transition.js +353 -0
- package/dist/commands/transition.js.map +1 -0
- package/dist/compile/adapters/claude-code.d.ts +24 -0
- package/dist/compile/adapters/claude-code.d.ts.map +1 -0
- package/dist/compile/adapters/claude-code.js +271 -0
- package/dist/compile/adapters/claude-code.js.map +1 -0
- package/dist/compile/adapters/codex.d.ts +19 -0
- package/dist/compile/adapters/codex.d.ts.map +1 -0
- package/dist/compile/adapters/codex.js +157 -0
- package/dist/compile/adapters/codex.js.map +1 -0
- package/dist/compile/adapters/cursor.d.ts +21 -0
- package/dist/compile/adapters/cursor.d.ts.map +1 -0
- package/dist/compile/adapters/cursor.js +181 -0
- package/dist/compile/adapters/cursor.js.map +1 -0
- package/dist/compile/adapters/index.d.ts +16 -0
- package/dist/compile/adapters/index.d.ts.map +1 -0
- package/dist/compile/adapters/index.js +26 -0
- package/dist/compile/adapters/index.js.map +1 -0
- package/dist/compile/adapters/kiro.d.ts +24 -0
- package/dist/compile/adapters/kiro.d.ts.map +1 -0
- package/dist/compile/adapters/kiro.js +222 -0
- package/dist/compile/adapters/kiro.js.map +1 -0
- package/dist/compile/adapters/windsurf.d.ts +25 -0
- package/dist/compile/adapters/windsurf.d.ts.map +1 -0
- package/dist/compile/adapters/windsurf.js +242 -0
- package/dist/compile/adapters/windsurf.js.map +1 -0
- package/dist/compile/install-plan.d.ts +49 -0
- package/dist/compile/install-plan.d.ts.map +1 -0
- package/dist/compile/install-plan.js +112 -0
- package/dist/compile/install-plan.js.map +1 -0
- package/dist/compile/loaders.d.ts +81 -0
- package/dist/compile/loaders.d.ts.map +1 -0
- package/dist/compile/loaders.js +293 -0
- package/dist/compile/loaders.js.map +1 -0
- package/dist/compile/merger.d.ts +32 -0
- package/dist/compile/merger.d.ts.map +1 -0
- package/dist/compile/merger.js +60 -0
- package/dist/compile/merger.js.map +1 -0
- package/dist/core/gate.d.ts +36 -0
- package/dist/core/gate.d.ts.map +1 -0
- package/dist/core/gate.js +97 -0
- package/dist/core/gate.js.map +1 -0
- package/dist/core/index.d.ts +7 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +7 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/lifecycle.d.ts +89 -0
- package/dist/core/lifecycle.d.ts.map +1 -0
- package/dist/core/lifecycle.js +356 -0
- package/dist/core/lifecycle.js.map +1 -0
- package/dist/core/template-resolver.d.ts +56 -0
- package/dist/core/template-resolver.d.ts.map +1 -0
- package/dist/core/template-resolver.js +261 -0
- package/dist/core/template-resolver.js.map +1 -0
- package/dist/core/types.d.ts +527 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +8 -0
- package/dist/core/types.js.map +1 -0
- package/dist/discover/scanner.d.ts +58 -0
- package/dist/discover/scanner.d.ts.map +1 -0
- package/dist/discover/scanner.js +772 -0
- package/dist/discover/scanner.js.map +1 -0
- package/dist/events/event-bus.d.ts +53 -0
- package/dist/events/event-bus.d.ts.map +1 -0
- package/dist/events/event-bus.js +263 -0
- package/dist/events/event-bus.js.map +1 -0
- package/dist/events/plugin-hooks.d.ts +44 -0
- package/dist/events/plugin-hooks.d.ts.map +1 -0
- package/dist/events/plugin-hooks.js +225 -0
- package/dist/events/plugin-hooks.js.map +1 -0
- package/dist/orchestrator/budget-packer.d.ts +57 -0
- package/dist/orchestrator/budget-packer.d.ts.map +1 -0
- package/dist/orchestrator/budget-packer.js +70 -0
- package/dist/orchestrator/budget-packer.js.map +1 -0
- package/dist/orchestrator/config.d.ts +43 -0
- package/dist/orchestrator/config.d.ts.map +1 -0
- package/dist/orchestrator/config.js +109 -0
- package/dist/orchestrator/config.js.map +1 -0
- package/dist/orchestrator/endpoint-clients.d.ts +23 -0
- package/dist/orchestrator/endpoint-clients.d.ts.map +1 -0
- package/dist/orchestrator/endpoint-clients.js +129 -0
- package/dist/orchestrator/endpoint-clients.js.map +1 -0
- package/dist/orchestrator/orchestrator-loop.d.ts +93 -0
- package/dist/orchestrator/orchestrator-loop.d.ts.map +1 -0
- package/dist/orchestrator/orchestrator-loop.js +185 -0
- package/dist/orchestrator/orchestrator-loop.js.map +1 -0
- package/dist/security/confirmation.d.ts +90 -0
- package/dist/security/confirmation.d.ts.map +1 -0
- package/dist/security/confirmation.js +140 -0
- package/dist/security/confirmation.js.map +1 -0
- package/dist/setup/setup-compute.d.ts +54 -0
- package/dist/setup/setup-compute.d.ts.map +1 -0
- package/dist/setup/setup-compute.js +66 -0
- package/dist/setup/setup-compute.js.map +1 -0
- package/dist/state/snapshot-store.d.ts +79 -0
- package/dist/state/snapshot-store.d.ts.map +1 -0
- package/dist/state/snapshot-store.js +164 -0
- package/dist/state/snapshot-store.js.map +1 -0
- package/dist/state/state-recovery.d.ts +87 -0
- package/dist/state/state-recovery.d.ts.map +1 -0
- package/dist/state/state-recovery.js +274 -0
- package/dist/state/state-recovery.js.map +1 -0
- package/dist/state/transition-log.d.ts +40 -0
- package/dist/state/transition-log.d.ts.map +1 -0
- package/dist/state/transition-log.js +83 -0
- package/dist/state/transition-log.js.map +1 -0
- package/dist/state/yaml-helpers.d.ts +53 -0
- package/dist/state/yaml-helpers.d.ts.map +1 -0
- package/dist/state/yaml-helpers.js +110 -0
- package/dist/state/yaml-helpers.js.map +1 -0
- package/examples/.gitkeep +0 -0
- package/guidance/accessibility.md +67 -0
- package/guidance/api-conventions.md +124 -0
- package/guidance/index.yaml +7 -0
- package/guidance/secure-defaults.md +71 -0
- package/package.json +52 -0
- package/phases/.gitkeep +0 -0
- package/skills/00-overview.md +74 -0
- package/skills/10-ideation.md +45 -0
- package/skills/20-requirements.md +54 -0
- package/skills/30-design.md +57 -0
- package/skills/40-implementation.md +64 -0
- package/skills/50-testing.md +60 -0
- package/skills/60-deployment.md +63 -0
- package/skills/70-maintenance.md +56 -0
- package/skills/80-review.md +85 -0
- package/skills/81-continue.md +57 -0
- package/skills/82-add-action.md +71 -0
- package/templates/.gitkeep +0 -0
- package/templates/bugfix.yaml +14 -0
- package/templates/full-feature.yaml +44 -0
- package/templates/micro-task.yaml +11 -0
- package/templates/quick-feature.yaml +20 -0
- package/templates/spike.yaml +15 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `aidlc review` command — invoke adversarial review on an artifact.
|
|
3
|
+
*
|
|
4
|
+
* Behavior:
|
|
5
|
+
* - `aidlc review <instance> <artifact>` — create or show findings for an artifact.
|
|
6
|
+
* - Writes structured findings to `.aidlc/state/<instance>/<artifact>.review.md`.
|
|
7
|
+
* - In non-orchestrator mode: creates a placeholder findings file and prints
|
|
8
|
+
* instructions for manual review (the skill `80-review.md` guides AI agents).
|
|
9
|
+
* - With `--json`: output findings structure as JSON.
|
|
10
|
+
* - Integrates with review gate: `evaluateTransition` already checks for `*.review.md`
|
|
11
|
+
* files and parses findings from them.
|
|
12
|
+
*
|
|
13
|
+
* Requirements: 24.1, 24.2, 24.4
|
|
14
|
+
*
|
|
15
|
+
* @module
|
|
16
|
+
*/
|
|
17
|
+
import { Command } from 'commander';
|
|
18
|
+
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
19
|
+
import { join } from 'node:path';
|
|
20
|
+
import { atomicWrite, instancePath } from '../state/snapshot-store.js';
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// Findings file parsing
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
/**
|
|
25
|
+
* Parse a review findings markdown file into structured data.
|
|
26
|
+
*
|
|
27
|
+
* Expected format:
|
|
28
|
+
* ```
|
|
29
|
+
* ---
|
|
30
|
+
* artifact: <filename>
|
|
31
|
+
* reviewed_at: <ISO 8601>
|
|
32
|
+
* reviewer: <session-id>
|
|
33
|
+
* ---
|
|
34
|
+
*
|
|
35
|
+
* ## Finding 1
|
|
36
|
+
* - **Severity:** critical | major | minor | info
|
|
37
|
+
* - **Section:** <reference>
|
|
38
|
+
* - **Issue:** <description>
|
|
39
|
+
* - **Suggestion:** <resolution>
|
|
40
|
+
* - **Status:** open | resolved | accepted-risk | rejected
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export function parseFindingsFile(content) {
|
|
44
|
+
const meta = parseFrontmatter(content);
|
|
45
|
+
const findings = parseFindings(content);
|
|
46
|
+
return {
|
|
47
|
+
artifact: meta.artifact,
|
|
48
|
+
reviewed_at: meta.reviewed_at,
|
|
49
|
+
reviewer: meta.reviewer,
|
|
50
|
+
findings,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Parse YAML-like frontmatter from the findings file.
|
|
55
|
+
*/
|
|
56
|
+
function parseFrontmatter(content) {
|
|
57
|
+
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
58
|
+
if (!fmMatch) {
|
|
59
|
+
return { artifact: '', reviewed_at: '', reviewer: '' };
|
|
60
|
+
}
|
|
61
|
+
const fmBlock = fmMatch[1];
|
|
62
|
+
const artifact = extractField(fmBlock, 'artifact') ?? '';
|
|
63
|
+
const reviewed_at = extractField(fmBlock, 'reviewed_at') ?? '';
|
|
64
|
+
const reviewer = extractField(fmBlock, 'reviewer') ?? '';
|
|
65
|
+
return { artifact, reviewed_at, reviewer };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Extract a simple key: value field from a YAML block.
|
|
69
|
+
*/
|
|
70
|
+
function extractField(block, key) {
|
|
71
|
+
const regex = new RegExp(`^${key}:\\s*(.+)$`, 'm');
|
|
72
|
+
const match = block.match(regex);
|
|
73
|
+
return match ? match[1].trim() : undefined;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Parse finding blocks from the markdown body.
|
|
77
|
+
*/
|
|
78
|
+
function parseFindings(content) {
|
|
79
|
+
const findings = [];
|
|
80
|
+
// Remove frontmatter
|
|
81
|
+
const bodyMatch = content.match(/^---\n[\s\S]*?\n---\n([\s\S]*)/);
|
|
82
|
+
const body = bodyMatch ? bodyMatch[1] : content;
|
|
83
|
+
// Split on ## Finding N or ## F<N>: headings
|
|
84
|
+
const findingBlocks = body.split(/^## /m).filter((b) => b.trim().length > 0);
|
|
85
|
+
for (const block of findingBlocks) {
|
|
86
|
+
const finding = parseSingleFinding(block, findings.length + 1);
|
|
87
|
+
if (finding) {
|
|
88
|
+
findings.push(finding);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return findings;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Parse a single finding block.
|
|
95
|
+
*/
|
|
96
|
+
function parseSingleFinding(block, index) {
|
|
97
|
+
const lines = block.split('\n');
|
|
98
|
+
const titleLine = lines[0]?.trim() ?? '';
|
|
99
|
+
// Extract title — may be "Finding 1" or "F1: Title [severity] [status]"
|
|
100
|
+
const titleMatch = titleLine.match(/^(?:Finding\s+\d+|F\d+)(?::\s*(.+?))?(?:\s*\[(\w+)\]\s*\[(\w+)\])?$/i);
|
|
101
|
+
const title = titleMatch?.[1]?.trim() ?? titleLine;
|
|
102
|
+
// Parse fields from bullet points
|
|
103
|
+
const severity = extractBulletField(block, 'Severity');
|
|
104
|
+
const section = extractBulletField(block, 'Section');
|
|
105
|
+
const issue = extractBulletField(block, 'Issue');
|
|
106
|
+
const suggestion = extractBulletField(block, 'Suggestion');
|
|
107
|
+
const status = extractBulletField(block, 'Status');
|
|
108
|
+
// A finding must have at least a severity to be valid
|
|
109
|
+
if (!severity && !titleMatch?.[2]) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
const effectiveSeverity = (severity ?? titleMatch?.[2] ?? 'info');
|
|
113
|
+
const effectiveStatus = (status ?? titleMatch?.[3] ?? 'open');
|
|
114
|
+
return {
|
|
115
|
+
id: `F${index}`,
|
|
116
|
+
title: title || `Finding ${index}`,
|
|
117
|
+
severity: effectiveSeverity,
|
|
118
|
+
status: effectiveStatus,
|
|
119
|
+
section: section ?? undefined,
|
|
120
|
+
issue: issue ?? undefined,
|
|
121
|
+
suggested_resolution: suggestion ?? undefined,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Extract a bullet field value: `- **FieldName:** value`
|
|
126
|
+
*/
|
|
127
|
+
function extractBulletField(block, fieldName) {
|
|
128
|
+
const regex = new RegExp(`^\\s*-\\s*\\*\\*${fieldName}:\\*\\*\\s*(.+)$`, 'mi');
|
|
129
|
+
const match = block.match(regex);
|
|
130
|
+
return match ? match[1].trim() : undefined;
|
|
131
|
+
}
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
// Findings file generation
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
/**
|
|
136
|
+
* Generate a placeholder findings file for manual review.
|
|
137
|
+
*/
|
|
138
|
+
export function generatePlaceholderFindings(artifactName, reviewer) {
|
|
139
|
+
const now = new Date().toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
140
|
+
return `---
|
|
141
|
+
artifact: ${artifactName}
|
|
142
|
+
reviewed_at: ${now}
|
|
143
|
+
reviewer: ${reviewer}
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Finding 1
|
|
147
|
+
- **Severity:** info
|
|
148
|
+
- **Section:** (pending review)
|
|
149
|
+
- **Issue:** Review has not yet been performed. Run this command with an AI agent or perform manual review following the instructions in skills/80-review.md.
|
|
150
|
+
- **Suggestion:** Complete the adversarial review for this artifact.
|
|
151
|
+
- **Status:** open
|
|
152
|
+
`;
|
|
153
|
+
}
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
// Command registration
|
|
156
|
+
// ---------------------------------------------------------------------------
|
|
157
|
+
/**
|
|
158
|
+
* Register the `aidlc review` command on the given commander program.
|
|
159
|
+
*/
|
|
160
|
+
export function registerReview(program) {
|
|
161
|
+
program
|
|
162
|
+
.command('review')
|
|
163
|
+
.description('Run an adversarial review of a lifecycle artifact, recording structured findings')
|
|
164
|
+
.argument('<instance>', 'Lifecycle instance name')
|
|
165
|
+
.argument('<artifact>', 'Artifact filename to review (e.g., requirements.md)')
|
|
166
|
+
.option('--json', 'Output findings as structured JSON')
|
|
167
|
+
.action((instance, artifact, opts) => {
|
|
168
|
+
runReview(instance, artifact, opts);
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
// ---------------------------------------------------------------------------
|
|
172
|
+
// Core logic
|
|
173
|
+
// ---------------------------------------------------------------------------
|
|
174
|
+
function runReview(instanceArg, artifactArg, opts) {
|
|
175
|
+
const projectRoot = process.cwd();
|
|
176
|
+
const stateDir = join(projectRoot, '.aidlc', 'state');
|
|
177
|
+
// Validate instance exists
|
|
178
|
+
const instDir = instancePath(stateDir, instanceArg);
|
|
179
|
+
if (!existsSync(instDir)) {
|
|
180
|
+
process.stderr.write(`Error: instance '${instanceArg}' not found.\n`);
|
|
181
|
+
process.exitCode = 1;
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
// Check if a findings file already exists
|
|
185
|
+
const findingsFileName = `${artifactArg}.review.md`;
|
|
186
|
+
const findingsFilePath = join(instDir, findingsFileName);
|
|
187
|
+
if (existsSync(findingsFilePath)) {
|
|
188
|
+
// Read and output existing findings
|
|
189
|
+
const content = readFileSync(findingsFilePath, 'utf8');
|
|
190
|
+
const parsed = parseFindingsFile(content);
|
|
191
|
+
if (opts.json) {
|
|
192
|
+
process.stdout.write(JSON.stringify(parsed, null, 2) + '\n');
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
printFindingsSummary(parsed);
|
|
196
|
+
}
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
// No findings file exists — create a placeholder
|
|
200
|
+
const reviewer = getReviewerIdentity();
|
|
201
|
+
const placeholder = generatePlaceholderFindings(artifactArg, reviewer);
|
|
202
|
+
// Write the findings file atomically
|
|
203
|
+
atomicWrite(findingsFilePath, placeholder);
|
|
204
|
+
// Parse what we just wrote for output
|
|
205
|
+
const parsed = parseFindingsFile(placeholder);
|
|
206
|
+
if (opts.json) {
|
|
207
|
+
process.stdout.write(JSON.stringify(parsed, null, 2) + '\n');
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
process.stdout.write(`Review findings file created:\n`);
|
|
211
|
+
process.stdout.write(` ${findingsFileName}\n\n`);
|
|
212
|
+
process.stdout.write(`Location: .aidlc/state/${instanceArg}/${findingsFileName}\n\n`);
|
|
213
|
+
process.stdout.write(`Next steps:\n`);
|
|
214
|
+
process.stdout.write(` 1. Run an adversarial review using an AI agent (skill: 80-review.md)\n`);
|
|
215
|
+
process.stdout.write(` 2. Or manually edit the findings file to record review results\n`);
|
|
216
|
+
process.stdout.write(` 3. The review gate will block phase transitions while critical findings are open\n`);
|
|
217
|
+
process.stdout.write(`\n`);
|
|
218
|
+
printFindingsSummary(parsed);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// ---------------------------------------------------------------------------
|
|
222
|
+
// Helpers
|
|
223
|
+
// ---------------------------------------------------------------------------
|
|
224
|
+
/**
|
|
225
|
+
* Determine reviewer identity from environment.
|
|
226
|
+
*/
|
|
227
|
+
function getReviewerIdentity() {
|
|
228
|
+
return (process.env.AIDLC_SESSION ||
|
|
229
|
+
process.env.USER ||
|
|
230
|
+
process.env.USERNAME ||
|
|
231
|
+
process.env.LOGNAME ||
|
|
232
|
+
'unknown');
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Print a human-readable findings summary.
|
|
236
|
+
*/
|
|
237
|
+
function printFindingsSummary(output) {
|
|
238
|
+
const { findings } = output;
|
|
239
|
+
process.stdout.write(`Review summary for "${output.artifact}":\n`);
|
|
240
|
+
process.stdout.write(` Reviewed at: ${output.reviewed_at}\n`);
|
|
241
|
+
process.stdout.write(` Reviewer: ${output.reviewer}\n`);
|
|
242
|
+
process.stdout.write(` Findings: ${findings.length}\n`);
|
|
243
|
+
if (findings.length === 0) {
|
|
244
|
+
process.stdout.write(` No findings recorded.\n`);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
// Count by severity
|
|
248
|
+
const bySeverity = {};
|
|
249
|
+
for (const f of findings) {
|
|
250
|
+
bySeverity[f.severity] = (bySeverity[f.severity] || 0) + 1;
|
|
251
|
+
}
|
|
252
|
+
process.stdout.write(`\n By severity:\n`);
|
|
253
|
+
for (const sev of ['critical', 'major', 'minor', 'info']) {
|
|
254
|
+
if (bySeverity[sev]) {
|
|
255
|
+
process.stdout.write(` ${sev}: ${bySeverity[sev]}\n`);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// Check if critical open findings exist (blocks transition)
|
|
259
|
+
const criticalOpen = findings.filter((f) => f.severity === 'critical' && f.status === 'open');
|
|
260
|
+
if (criticalOpen.length > 0) {
|
|
261
|
+
process.stdout.write(`\n ⚠ ${criticalOpen.length} critical finding(s) with status "open" — review gate will block phase transition.\n`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review.js","sourceRoot":"","sources":["../../src/commands/review.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `aidlc setup` command — interactive setup or update of AIDLC configuration.
|
|
3
|
+
*
|
|
4
|
+
* Behavior:
|
|
5
|
+
* - Detect existing `.aidlc/config.yaml` → update mode vs fresh-setup mode.
|
|
6
|
+
* - In interactive mode: use @clack/prompts to collect SetupAnswers.
|
|
7
|
+
* - In non-interactive mode (`--non-interactive`): use empty answers (preserve
|
|
8
|
+
* existing or apply defaults).
|
|
9
|
+
* - Call `computeSetup(existingConfig, answers)` to produce the config.
|
|
10
|
+
* - Write the result to `.aidlc/config.yaml` using `saveYaml`.
|
|
11
|
+
* - Run `aidlc init` for each configured platform.
|
|
12
|
+
* - Run `aidlc discover` to generate context docs.
|
|
13
|
+
* - Print summary.
|
|
14
|
+
*
|
|
15
|
+
* Requirements: 21.1, 21.9, 7.8
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
*/
|
|
19
|
+
import { Command } from 'commander';
|
|
20
|
+
/**
|
|
21
|
+
* Register the `aidlc setup` command on the given commander program.
|
|
22
|
+
*/
|
|
23
|
+
export declare function registerSetup(program: Command): void;
|
|
24
|
+
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+HpC;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAQpD"}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `aidlc setup` command — interactive setup or update of AIDLC configuration.
|
|
3
|
+
*
|
|
4
|
+
* Behavior:
|
|
5
|
+
* - Detect existing `.aidlc/config.yaml` → update mode vs fresh-setup mode.
|
|
6
|
+
* - In interactive mode: use @clack/prompts to collect SetupAnswers.
|
|
7
|
+
* - In non-interactive mode (`--non-interactive`): use empty answers (preserve
|
|
8
|
+
* existing or apply defaults).
|
|
9
|
+
* - Call `computeSetup(existingConfig, answers)` to produce the config.
|
|
10
|
+
* - Write the result to `.aidlc/config.yaml` using `saveYaml`.
|
|
11
|
+
* - Run `aidlc init` for each configured platform.
|
|
12
|
+
* - Run `aidlc discover` to generate context docs.
|
|
13
|
+
* - Print summary.
|
|
14
|
+
*
|
|
15
|
+
* Requirements: 21.1, 21.9, 7.8
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
*/
|
|
19
|
+
import { Command } from 'commander';
|
|
20
|
+
import { existsSync } from 'node:fs';
|
|
21
|
+
import { join } from 'node:path';
|
|
22
|
+
import * as clack from '@clack/prompts';
|
|
23
|
+
import { computeSetup } from '../setup/setup-compute.js';
|
|
24
|
+
import { loadYaml, saveYaml } from '../state/yaml-helpers.js';
|
|
25
|
+
import { supportedPlatforms } from '../compile/adapters/index.js';
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Constants
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
const PROJECT_TYPES = ['web-app', 'library', 'cli', 'api'];
|
|
30
|
+
const COMPLEXITIES = ['simple', 'moderate', 'complex'];
|
|
31
|
+
const AVAILABLE_TEMPLATES = ['micro-task', 'full-feature', 'quick-feature', 'bugfix', 'spike'];
|
|
32
|
+
const AVAILABLE_SCOPES = ['full', 'standard', 'micro'];
|
|
33
|
+
/**
|
|
34
|
+
* Mapping from complexity to default scope and template (Req 21.5).
|
|
35
|
+
*/
|
|
36
|
+
const COMPLEXITY_DEFAULTS = {
|
|
37
|
+
simple: { scope: 'micro', template: 'micro-task' },
|
|
38
|
+
moderate: { scope: 'standard', template: 'quick-feature' },
|
|
39
|
+
complex: { scope: 'full', template: 'full-feature' },
|
|
40
|
+
};
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
// Helpers
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
/**
|
|
45
|
+
* Load existing config from `.aidlc/config.yaml`, or null if it doesn't exist.
|
|
46
|
+
*/
|
|
47
|
+
function loadExistingConfig(projectRoot) {
|
|
48
|
+
const configPath = join(projectRoot, '.aidlc', 'config.yaml');
|
|
49
|
+
if (!existsSync(configPath)) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
return loadYaml(configPath);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// Malformed config → treat as fresh setup
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Collect answers interactively using @clack/prompts.
|
|
62
|
+
*/
|
|
63
|
+
async function collectInteractiveAnswers(existing) {
|
|
64
|
+
clack.intro('aidlc setup');
|
|
65
|
+
if (existing) {
|
|
66
|
+
clack.note(`Existing configuration found. Current platforms: ${existing.platforms.join(', ') || 'none'}\n` +
|
|
67
|
+
`Scope: ${existing.defaults.scope}, Template: ${existing.defaults.template}`, 'Update mode');
|
|
68
|
+
}
|
|
69
|
+
// Project type
|
|
70
|
+
const projectType = await clack.select({
|
|
71
|
+
message: 'Project type:',
|
|
72
|
+
options: PROJECT_TYPES.map((t) => ({ value: t, label: t })),
|
|
73
|
+
});
|
|
74
|
+
if (clack.isCancel(projectType))
|
|
75
|
+
return null;
|
|
76
|
+
// Complexity
|
|
77
|
+
const complexity = await clack.select({
|
|
78
|
+
message: 'Complexity:',
|
|
79
|
+
options: COMPLEXITIES.map((c) => ({
|
|
80
|
+
value: c,
|
|
81
|
+
label: c,
|
|
82
|
+
hint: c === 'simple'
|
|
83
|
+
? 'tasks then execution only'
|
|
84
|
+
: c === 'complex'
|
|
85
|
+
? 'all phases including requirements and design'
|
|
86
|
+
: 'requirements, design, implementation',
|
|
87
|
+
})),
|
|
88
|
+
});
|
|
89
|
+
if (clack.isCancel(complexity))
|
|
90
|
+
return null;
|
|
91
|
+
// Platforms
|
|
92
|
+
const platforms = await clack.multiselect({
|
|
93
|
+
message: 'Platforms to support:',
|
|
94
|
+
options: supportedPlatforms.map((p) => ({
|
|
95
|
+
value: p,
|
|
96
|
+
label: p,
|
|
97
|
+
})),
|
|
98
|
+
required: false,
|
|
99
|
+
});
|
|
100
|
+
if (clack.isCancel(platforms))
|
|
101
|
+
return null;
|
|
102
|
+
// Default template
|
|
103
|
+
const template = await clack.select({
|
|
104
|
+
message: 'Default template:',
|
|
105
|
+
options: AVAILABLE_TEMPLATES.map((t) => ({ value: t, label: t })),
|
|
106
|
+
initialValue: COMPLEXITY_DEFAULTS[complexity]?.template ?? 'micro-task',
|
|
107
|
+
});
|
|
108
|
+
if (clack.isCancel(template))
|
|
109
|
+
return null;
|
|
110
|
+
// Default scope
|
|
111
|
+
const scope = await clack.select({
|
|
112
|
+
message: 'Default scope:',
|
|
113
|
+
options: AVAILABLE_SCOPES.map((s) => ({ value: s, label: s })),
|
|
114
|
+
initialValue: COMPLEXITY_DEFAULTS[complexity]?.scope ?? 'micro',
|
|
115
|
+
});
|
|
116
|
+
if (clack.isCancel(scope))
|
|
117
|
+
return null;
|
|
118
|
+
return {
|
|
119
|
+
projectType: projectType,
|
|
120
|
+
complexity: complexity,
|
|
121
|
+
platforms: platforms,
|
|
122
|
+
template: template,
|
|
123
|
+
scope: scope,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
// Command registration
|
|
128
|
+
// ---------------------------------------------------------------------------
|
|
129
|
+
/**
|
|
130
|
+
* Register the `aidlc setup` command on the given commander program.
|
|
131
|
+
*/
|
|
132
|
+
export function registerSetup(program) {
|
|
133
|
+
program
|
|
134
|
+
.command('setup')
|
|
135
|
+
.description('Interactive setup or update of AIDLC configuration')
|
|
136
|
+
.option('--non-interactive', 'Skip prompts, use defaults or existing config')
|
|
137
|
+
.action(async (opts) => {
|
|
138
|
+
await runSetup(opts);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
// ---------------------------------------------------------------------------
|
|
142
|
+
// Core logic
|
|
143
|
+
// ---------------------------------------------------------------------------
|
|
144
|
+
async function runSetup(opts) {
|
|
145
|
+
const projectRoot = process.cwd();
|
|
146
|
+
const configPath = join(projectRoot, '.aidlc', 'config.yaml');
|
|
147
|
+
// Load existing config
|
|
148
|
+
const existing = loadExistingConfig(projectRoot);
|
|
149
|
+
const isUpdate = existing !== null;
|
|
150
|
+
let answers;
|
|
151
|
+
if (opts.nonInteractive) {
|
|
152
|
+
// Non-interactive: use empty answers (preserve existing or apply defaults)
|
|
153
|
+
answers = {};
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
// Interactive: collect answers via prompts
|
|
157
|
+
const collected = await collectInteractiveAnswers(existing);
|
|
158
|
+
if (collected === null) {
|
|
159
|
+
process.stderr.write('Setup cancelled.\n');
|
|
160
|
+
process.exitCode = 1;
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
answers = collected;
|
|
164
|
+
}
|
|
165
|
+
// Compute the resulting config
|
|
166
|
+
const config = computeSetup(existing, answers);
|
|
167
|
+
// Write `.aidlc/config.yaml`
|
|
168
|
+
saveYaml(configPath, config);
|
|
169
|
+
// Run `aidlc init` for each configured platform
|
|
170
|
+
if (config.platforms.length > 0) {
|
|
171
|
+
const { registerInit } = await import('./init.js');
|
|
172
|
+
for (const platform of config.platforms) {
|
|
173
|
+
process.stderr.write(`Running init for platform: ${platform}\n`);
|
|
174
|
+
const initProgram = new Command();
|
|
175
|
+
initProgram.exitOverride();
|
|
176
|
+
registerInit(initProgram);
|
|
177
|
+
try {
|
|
178
|
+
await initProgram.parseAsync(['init', '--platform', platform], { from: 'user' });
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
// commander throws on exitOverride; non-fatal for setup
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// Run discover to generate context docs
|
|
186
|
+
process.stderr.write('Running discover...\n');
|
|
187
|
+
try {
|
|
188
|
+
const { registerDiscover } = await import('./discover.js');
|
|
189
|
+
const discoverProgram = new Command();
|
|
190
|
+
discoverProgram.exitOverride();
|
|
191
|
+
registerDiscover(discoverProgram);
|
|
192
|
+
await discoverProgram.parseAsync(['discover'], { from: 'user' });
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
// Non-fatal: discover may fail on empty projects
|
|
196
|
+
}
|
|
197
|
+
// Print summary
|
|
198
|
+
process.stdout.write(`\n${isUpdate ? 'Configuration updated' : 'Setup complete'}:\n`);
|
|
199
|
+
process.stdout.write(` Config: ${configPath}\n`);
|
|
200
|
+
process.stdout.write(` Scope: ${config.defaults.scope}\n`);
|
|
201
|
+
process.stdout.write(` Template: ${config.defaults.template}\n`);
|
|
202
|
+
process.stdout.write(` Platforms: ${config.platforms.length > 0 ? config.platforms.join(', ') : 'none'}\n`);
|
|
203
|
+
process.stdout.write(` Actions: ${config.actions.length > 0 ? config.actions.join(', ') : 'none'}\n`);
|
|
204
|
+
process.stdout.write('\n');
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `aidlc start` command — begin a new lifecycle instance.
|
|
3
|
+
*
|
|
4
|
+
* Behavior:
|
|
5
|
+
* - Load templates from the package `templates/` dir and `.aidlc/templates/` (custom).
|
|
6
|
+
* - If no template argument is given:
|
|
7
|
+
* - In interactive mode: list available templates and prompt for selection (Req 8.2).
|
|
8
|
+
* - In non-interactive mode: exit with error.
|
|
9
|
+
* - Resolve the template (apply inheritance if needed).
|
|
10
|
+
* - Determine scope from `--scope` option or template default.
|
|
11
|
+
* - Determine initial phase based on scope (Req 5.1):
|
|
12
|
+
* full → ideation, standard → requirements, micro → implementation.
|
|
13
|
+
* - Create instance namespace under `.aidlc/state/<name>/`.
|
|
14
|
+
* - Write `instance.yaml` with initial state.
|
|
15
|
+
* - Write initial `phase-<name>.yaml` files for all applicable phases (status: pending).
|
|
16
|
+
* - Print summary to stdout.
|
|
17
|
+
*
|
|
18
|
+
* Requirements: 5.1, 8.2, 23.1
|
|
19
|
+
*
|
|
20
|
+
* @module
|
|
21
|
+
*/
|
|
22
|
+
import { Command } from 'commander';
|
|
23
|
+
/**
|
|
24
|
+
* Register the `aidlc start` command on the given commander program.
|
|
25
|
+
*/
|
|
26
|
+
export declare function registerStart(program: Command): void;
|
|
27
|
+
//# sourceMappingURL=start.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkGpC;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiBpD"}
|