@jaimevalasek/aioson 1.23.1 → 1.28.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/CHANGELOG.md +56 -0
- package/docs/en/4-agents/README.md +11 -8
- package/docs/en/4-agents/forge-run.md +165 -0
- package/docs/en/5-reference/README.md +1 -0
- package/docs/en/5-reference/cli-reference.md +199 -85
- package/docs/en/5-reference/executable-verification.md +165 -0
- package/docs/pt/4-agentes/README.md +2 -1
- package/docs/pt/4-agentes/forge-run.md +150 -0
- package/docs/pt/4-agentes/pm.md +8 -0
- package/docs/pt/4-agentes/qa.md +2 -0
- package/docs/pt/4-agentes/scope-check.md +19 -1
- package/docs/pt/4-agentes/sheldon.md +2 -0
- package/docs/pt/4-agentes/validator.md +20 -0
- package/docs/pt/5-referencia/autopilot-handoff.md +33 -0
- package/docs/pt/5-referencia/comandos-cli.md +64 -9
- package/docs/pt/5-referencia/fluxo-artefatos.md +40 -15
- package/docs/pt/5-referencia/loop-guardrails.md +19 -0
- package/docs/pt/5-referencia/sdd-automation-scripts.md +130 -26
- package/package.json +1 -1
- package/src/cli.js +70 -54
- package/src/commands/context-select.js +1 -0
- package/src/commands/forge-compile.js +330 -0
- package/src/commands/harness-check.js +159 -0
- package/src/commands/harness.js +37 -2
- package/src/commands/spec-analyze.js +324 -0
- package/src/constants.js +118 -108
- package/src/context-selector.js +28 -2
- package/src/gateway-pointer-merge.js +25 -4
- package/src/harness/contract-schema.js +8 -0
- package/src/harness/plan-waves.js +77 -0
- package/src/harness/review-payload.js +230 -0
- package/src/i18n/messages/en.js +21 -15
- package/src/i18n/messages/es.js +15 -13
- package/src/i18n/messages/fr.js +15 -13
- package/src/i18n/messages/pt-BR.js +21 -15
- package/src/parser.js +3 -1
- package/template/.aioson/agents/dev.md +67 -66
- package/template/.aioson/agents/deyvin.md +79 -74
- package/template/.aioson/agents/forge-run.md +57 -0
- package/template/.aioson/agents/pm.md +51 -45
- package/template/.aioson/agents/qa.md +22 -22
- package/template/.aioson/agents/scope-check.md +49 -46
- package/template/.aioson/agents/sheldon.md +1 -1
- package/template/.aioson/agents/validator.md +16 -5
- package/template/.aioson/docs/autopilot-handoff.md +34 -32
- package/template/.aioson/docs/sheldon/harness-contract.md +19 -2
- package/template/.aioson/skills/process/aioson-spec-driven/SKILL.md +9 -7
- package/template/.aioson/skills/process/aioson-spec-driven/references/deyvin.md +19 -15
- package/template/.claude/commands/aioson/agent/forge-run.md +17 -0
- package/template/AGENTS.md +7 -5
- package/template/CLAUDE.md +4 -3
- package/template/OPENCODE.md +24 -22
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* aioson spec:analyze — cross-artifact CONTENT consistency for a feature
|
|
5
|
+
* (Fase 3 do plano de verificação executável; análogo determinístico do
|
|
6
|
+
* /speckit.analyze).
|
|
7
|
+
*
|
|
8
|
+
* Escopo distinto de `artifact:validate` (presença/integridade da cadeia —
|
|
9
|
+
* intocado): aqui valida-se o CONTEÚDO entre artefatos já existentes:
|
|
10
|
+
*
|
|
11
|
+
* - Rastreabilidade de IDs: REQ-x e AC-x declarados em requirements-{slug}.md
|
|
12
|
+
* que nenhum artefato downstream referencia (gap de cobertura) e IDs
|
|
13
|
+
* referenciados downstream que não existem em requirements (órfãos — sinal
|
|
14
|
+
* de drift/alucinação).
|
|
15
|
+
* - Staleness: artefato upstream modificado DEPOIS de um downstream já gerado
|
|
16
|
+
* (ex.: PRD editado após o implementation-plan) — o downstream pode estar
|
|
17
|
+
* defasado.
|
|
18
|
+
* - Estados bloqueantes: readiness `blocked` no design-doc/readiness.
|
|
19
|
+
* - Sanidade do harness-contract: erros de schema (error) e avisos de
|
|
20
|
+
* cobertura executável (info), via validateContract.
|
|
21
|
+
* - Vínculo AC→contrato: ACs declarados sem nenhuma menção no contrato (info).
|
|
22
|
+
*
|
|
23
|
+
* Determinístico, read-only sobre os artefatos; persiste o relatório em
|
|
24
|
+
* `.aioson/context/spec-analyze-{slug}.json` (best-effort). Severidades:
|
|
25
|
+
* error (bloqueia gate), warning (drift provável), info (dívida/aviso).
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
const fs = require('node:fs');
|
|
29
|
+
const path = require('node:path');
|
|
30
|
+
|
|
31
|
+
const { scanArtifacts, detectClassification } = require('../preflight-engine');
|
|
32
|
+
const { validateContract } = require('../harness/contract-schema');
|
|
33
|
+
|
|
34
|
+
const REQ_ID_RE = /\bREQ(?:-[A-Z0-9]+)+\b/g;
|
|
35
|
+
const AC_ID_RE = /\bAC(?:-[A-Z0-9]+)+\b/g;
|
|
36
|
+
|
|
37
|
+
/** Edições upstream no mesmo fluxo de geração não são drift — tolerância. */
|
|
38
|
+
const STALENESS_TOLERANCE_MS = 60000;
|
|
39
|
+
|
|
40
|
+
/** Ordem upstream→downstream para staleness. `architecture.md` fica de fora:
|
|
41
|
+
* é artefato global do projeto; seu mtime não pertence ao fluxo da feature. */
|
|
42
|
+
const STALENESS_CHAIN = [
|
|
43
|
+
['prd', 'prd'],
|
|
44
|
+
['sheldon_enrichment', 'sheldon-enrichment'],
|
|
45
|
+
['requirements', 'requirements'],
|
|
46
|
+
['spec', 'spec'],
|
|
47
|
+
['design_doc', 'design-doc'],
|
|
48
|
+
['implementation_plan', 'implementation-plan']
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
/** Superfícies downstream onde um REQ/AC declarado deveria reaparecer. */
|
|
52
|
+
const TRACE_TARGETS = ['spec', 'design_doc', 'implementation_plan', 'conformance'];
|
|
53
|
+
|
|
54
|
+
const { parseExecutionWaves } = require('../harness/plan-waves');
|
|
55
|
+
|
|
56
|
+
function extractIds(content, regex) {
|
|
57
|
+
return new Set(String(content || '').match(regex) || []);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function mtimeMs(targetDir, artifact) {
|
|
61
|
+
if (!artifact || !artifact.exists || !artifact.path) return null;
|
|
62
|
+
try {
|
|
63
|
+
return fs.statSync(path.join(targetDir, artifact.path)).mtimeMs;
|
|
64
|
+
} catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function readContract(targetDir, slug) {
|
|
70
|
+
const contractPath = path.join(targetDir, '.aioson', 'plans', slug, 'harness-contract.json');
|
|
71
|
+
if (!fs.existsSync(contractPath)) return { exists: false };
|
|
72
|
+
try {
|
|
73
|
+
const raw = fs.readFileSync(contractPath, 'utf8');
|
|
74
|
+
return { exists: true, path: path.relative(targetDir, contractPath), raw, contract: JSON.parse(raw) };
|
|
75
|
+
} catch (err) {
|
|
76
|
+
return { exists: true, path: path.relative(targetDir, contractPath), parseError: err.message };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async function runSpecAnalyze({ args, options = {}, logger }) {
|
|
81
|
+
const targetDir = path.resolve(process.cwd(), args?.[0] || '.');
|
|
82
|
+
const slug = String(options.feature || options.slug || '').trim();
|
|
83
|
+
|
|
84
|
+
if (!slug) {
|
|
85
|
+
logger.error('--feature=<slug> is required.');
|
|
86
|
+
return { ok: false, error: 'missing_feature' };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const artifacts = await scanArtifacts(targetDir, slug);
|
|
90
|
+
const classification = await detectClassification(targetDir, slug);
|
|
91
|
+
const contractInfo = readContract(targetDir, slug);
|
|
92
|
+
const findings = [];
|
|
93
|
+
|
|
94
|
+
const present = Object.entries(artifacts)
|
|
95
|
+
.filter(([, a]) => a && a.exists)
|
|
96
|
+
.map(([name]) => name);
|
|
97
|
+
|
|
98
|
+
// ── Rastreabilidade REQ/AC ────────────────────────────────────────────────
|
|
99
|
+
const declaredReqs = artifacts.requirements.exists
|
|
100
|
+
? extractIds(artifacts.requirements.content, REQ_ID_RE)
|
|
101
|
+
: new Set();
|
|
102
|
+
const declaredAcs = artifacts.requirements.exists
|
|
103
|
+
? extractIds(artifacts.requirements.content, AC_ID_RE)
|
|
104
|
+
: new Set();
|
|
105
|
+
|
|
106
|
+
const downstream = TRACE_TARGETS
|
|
107
|
+
.filter((name) => artifacts[name] && artifacts[name].exists)
|
|
108
|
+
.map((name) => ({ name, content: artifacts[name].content || '' }));
|
|
109
|
+
if (contractInfo.exists && contractInfo.raw) {
|
|
110
|
+
downstream.push({ name: 'harness-contract', content: contractInfo.raw });
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (artifacts.requirements.exists && downstream.length > 0) {
|
|
114
|
+
const downstreamText = downstream.map((d) => d.content).join('\n');
|
|
115
|
+
const downstreamReqs = extractIds(downstreamText, REQ_ID_RE);
|
|
116
|
+
const downstreamAcs = extractIds(downstreamText, AC_ID_RE);
|
|
117
|
+
|
|
118
|
+
const untracedReqs = [...declaredReqs].filter((id) => !downstreamReqs.has(id));
|
|
119
|
+
if (untracedReqs.length > 0 && declaredReqs.size > untracedReqs.length) {
|
|
120
|
+
// Só acusa gap quando ALGUM REQ é rastreado — artefatos que não citam
|
|
121
|
+
// IDs por estilo (plano em prosa) não devem virar ruído.
|
|
122
|
+
findings.push({
|
|
123
|
+
severity: 'warning',
|
|
124
|
+
check: 'untraced_requirement',
|
|
125
|
+
message: `${untracedReqs.length} REQ id(s) declared in requirements but never referenced downstream: ${untracedReqs.slice(0, 10).join(', ')}${untracedReqs.length > 10 ? '…' : ''}`,
|
|
126
|
+
artifacts: ['requirements', ...downstream.map((d) => d.name)]
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const orphanIds = [
|
|
131
|
+
...[...downstreamReqs].filter((id) => !declaredReqs.has(id)),
|
|
132
|
+
...[...downstreamAcs].filter((id) => !declaredAcs.has(id))
|
|
133
|
+
];
|
|
134
|
+
if (orphanIds.length > 0) {
|
|
135
|
+
const offenders = downstream
|
|
136
|
+
.filter((d) => orphanIds.some((id) => d.content.includes(id)))
|
|
137
|
+
.map((d) => d.name);
|
|
138
|
+
findings.push({
|
|
139
|
+
severity: 'warning',
|
|
140
|
+
check: 'orphan_reference',
|
|
141
|
+
message: `${orphanIds.length} REQ/AC id(s) referenced downstream but not declared in requirements-${slug}.md: ${orphanIds.slice(0, 10).join(', ')}${orphanIds.length > 10 ? '…' : ''} (drift or cross-feature reference)`,
|
|
142
|
+
artifacts: offenders
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// ── Staleness upstream → downstream ──────────────────────────────────────
|
|
148
|
+
const chainWithTimes = STALENESS_CHAIN
|
|
149
|
+
.map(([key, label]) => ({ key, label, mtime: mtimeMs(targetDir, artifacts[key]) }))
|
|
150
|
+
.filter((entry) => entry.mtime !== null);
|
|
151
|
+
|
|
152
|
+
for (let i = 0; i < chainWithTimes.length; i += 1) {
|
|
153
|
+
for (let j = i + 1; j < chainWithTimes.length; j += 1) {
|
|
154
|
+
const upstream = chainWithTimes[i];
|
|
155
|
+
const downstreamArtifact = chainWithTimes[j];
|
|
156
|
+
if (upstream.mtime > downstreamArtifact.mtime + STALENESS_TOLERANCE_MS) {
|
|
157
|
+
findings.push({
|
|
158
|
+
severity: 'warning',
|
|
159
|
+
check: 'stale_downstream',
|
|
160
|
+
message: `${upstream.label} was modified after ${downstreamArtifact.label} was produced — ${downstreamArtifact.label} may be stale (re-run its owner agent or confirm the change is editorial)`,
|
|
161
|
+
artifacts: [upstream.key, downstreamArtifact.key]
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// ── Waves de paralelismo do implementation-plan ──────────────────────────
|
|
168
|
+
if (artifacts.implementation_plan.exists) {
|
|
169
|
+
const waves = parseExecutionWaves(artifacts.implementation_plan.content);
|
|
170
|
+
if (waves && waves.length > 0) {
|
|
171
|
+
const byWave = new Map();
|
|
172
|
+
for (const row of waves) {
|
|
173
|
+
if (!byWave.has(row.wave)) byWave.set(row.wave, []);
|
|
174
|
+
byWave.get(row.wave).push(row);
|
|
175
|
+
}
|
|
176
|
+
for (const [wave, phases] of byWave) {
|
|
177
|
+
if (phases.length < 2) continue;
|
|
178
|
+
for (let i = 0; i < phases.length; i += 1) {
|
|
179
|
+
for (let j = i + 1; j < phases.length; j += 1) {
|
|
180
|
+
const shared = phases[i].files.filter((f) => phases[j].files.includes(f));
|
|
181
|
+
if (shared.length > 0) {
|
|
182
|
+
findings.push({
|
|
183
|
+
severity: 'warning',
|
|
184
|
+
check: 'wave_file_overlap',
|
|
185
|
+
message: `wave ${wave}: phases ${phases[i].phase} and ${phases[j].phase} are marked parallel but share Primary files: ${shared.join(', ')} — same-wave phases must be file-disjoint (split the files or separate the waves)`,
|
|
186
|
+
artifacts: ['implementation_plan']
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// ── Estados bloqueantes ───────────────────────────────────────────────────
|
|
196
|
+
for (const key of ['design_doc', 'readiness']) {
|
|
197
|
+
const artifact = artifacts[key];
|
|
198
|
+
if (artifact && artifact.exists && artifact.frontmatter) {
|
|
199
|
+
const readiness = String(artifact.frontmatter.readiness || '').toLowerCase();
|
|
200
|
+
if (readiness === 'blocked') {
|
|
201
|
+
findings.push({
|
|
202
|
+
severity: 'error',
|
|
203
|
+
check: 'readiness_blocked',
|
|
204
|
+
message: `${path.basename(artifact.path)} declares readiness: blocked — resolve with @discovery-design-doc before the execution gate`,
|
|
205
|
+
artifacts: [key]
|
|
206
|
+
});
|
|
207
|
+
} else if (readiness === 'ready_with_warnings') {
|
|
208
|
+
findings.push({
|
|
209
|
+
severity: 'info',
|
|
210
|
+
check: 'readiness_warnings',
|
|
211
|
+
message: `${path.basename(artifact.path)} declares readiness: ready_with_warnings — review its warnings before @dev`,
|
|
212
|
+
artifacts: [key]
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// ── Sanidade do harness-contract ─────────────────────────────────────────
|
|
219
|
+
if (contractInfo.exists) {
|
|
220
|
+
if (contractInfo.parseError) {
|
|
221
|
+
findings.push({
|
|
222
|
+
severity: 'error',
|
|
223
|
+
check: 'contract_invalid',
|
|
224
|
+
message: `harness-contract.json is not valid JSON: ${contractInfo.parseError}`,
|
|
225
|
+
artifacts: ['harness-contract']
|
|
226
|
+
});
|
|
227
|
+
} else {
|
|
228
|
+
const schema = validateContract(contractInfo.contract);
|
|
229
|
+
for (const err of schema.errors) {
|
|
230
|
+
findings.push({
|
|
231
|
+
severity: 'error',
|
|
232
|
+
check: 'contract_schema',
|
|
233
|
+
message: `contract schema invalid: ${err.field} — ${err.reason}`,
|
|
234
|
+
artifacts: ['harness-contract']
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
for (const warn of schema.warnings) {
|
|
238
|
+
findings.push({
|
|
239
|
+
severity: 'info',
|
|
240
|
+
check: 'contract_coverage',
|
|
241
|
+
message: `${warn.field}: ${warn.reason}`,
|
|
242
|
+
artifacts: ['harness-contract']
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Vínculo AC→contrato: criteria derivam dos ACs; nenhum AC mencionado é
|
|
247
|
+
// sinal fraco (descrições podem parafrasear) — info, não warning.
|
|
248
|
+
if (declaredAcs.size > 0 && contractInfo.raw) {
|
|
249
|
+
const mentioned = [...declaredAcs].filter((id) => contractInfo.raw.includes(id));
|
|
250
|
+
if (mentioned.length === 0) {
|
|
251
|
+
findings.push({
|
|
252
|
+
severity: 'info',
|
|
253
|
+
check: 'contract_ac_unlinked',
|
|
254
|
+
message: `none of the ${declaredAcs.size} AC id(s) from requirements appear in harness-contract.json — confirm criteria[] actually derive from the enriched ACs`,
|
|
255
|
+
artifacts: ['requirements', 'harness-contract']
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const summary = {
|
|
263
|
+
errors: findings.filter((f) => f.severity === 'error').length,
|
|
264
|
+
warnings: findings.filter((f) => f.severity === 'warning').length,
|
|
265
|
+
info: findings.filter((f) => f.severity === 'info').length
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
const report = {
|
|
269
|
+
ok: summary.errors === 0,
|
|
270
|
+
feature: slug,
|
|
271
|
+
classification: classification || 'unknown',
|
|
272
|
+
analyzed_at: new Date().toISOString(),
|
|
273
|
+
artifacts_present: present,
|
|
274
|
+
contract_present: Boolean(contractInfo.exists && !contractInfo.parseError),
|
|
275
|
+
findings,
|
|
276
|
+
summary
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
// Persistência best-effort — segue a convenção *-{slug}.json de
|
|
280
|
+
// .aioson/context/ (coletada por feature:export/archive).
|
|
281
|
+
try {
|
|
282
|
+
const contextPath = path.join(targetDir, '.aioson', 'context');
|
|
283
|
+
if (fs.existsSync(contextPath)) {
|
|
284
|
+
fs.writeFileSync(
|
|
285
|
+
path.join(contextPath, `spec-analyze-${slug}.json`),
|
|
286
|
+
JSON.stringify(report, null, 2),
|
|
287
|
+
'utf8'
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
} catch { /* relatório em stdout permanece o canônico */ }
|
|
291
|
+
|
|
292
|
+
if (options.json) {
|
|
293
|
+
logger.log(JSON.stringify(report, null, 2));
|
|
294
|
+
return report;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
logger.log('');
|
|
298
|
+
logger.log(`Spec analyze — ${slug} (${report.classification})`);
|
|
299
|
+
logger.log('━'.repeat(45));
|
|
300
|
+
logger.log(`Artifacts present: ${present.length ? present.join(', ') : '(none)'}${report.contract_present ? ' + harness-contract' : ''}`);
|
|
301
|
+
|
|
302
|
+
if (findings.length === 0) {
|
|
303
|
+
logger.log('');
|
|
304
|
+
logger.log('✓ No cross-artifact inconsistencies detected.');
|
|
305
|
+
} else {
|
|
306
|
+
for (const severity of ['error', 'warning', 'info']) {
|
|
307
|
+
const group = findings.filter((f) => f.severity === severity);
|
|
308
|
+
if (!group.length) continue;
|
|
309
|
+
logger.log('');
|
|
310
|
+
logger.log(`${severity.toUpperCase()} (${group.length}):`);
|
|
311
|
+
for (const finding of group) {
|
|
312
|
+
logger.log(` - [${finding.check}] ${finding.message}`);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
logger.log('');
|
|
318
|
+
logger.log(`Summary: ${summary.errors} error(s), ${summary.warnings} warning(s), ${summary.info} info — ${report.ok ? 'OK for the execution gate' : 'BLOCKED (resolve errors first)'}`);
|
|
319
|
+
logger.log('Chain presence: aioson artifact:validate . --feature=' + slug);
|
|
320
|
+
|
|
321
|
+
return report;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
module.exports = { runSpecAnalyze };
|
package/src/constants.js
CHANGED
|
@@ -1,42 +1,43 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const MANAGED_FILES = [
|
|
4
|
-
'CLAUDE.md',
|
|
5
|
-
'AGENTS.md',
|
|
6
|
-
'OPENCODE.md',
|
|
4
|
+
'CLAUDE.md',
|
|
5
|
+
'AGENTS.md',
|
|
6
|
+
'OPENCODE.md',
|
|
7
7
|
'.aioson/config.md',
|
|
8
8
|
'.aioson/agents/setup.md',
|
|
9
|
-
'.aioson/agents/discovery-design-doc.md',
|
|
10
|
-
'.aioson/agents/discover.md',
|
|
11
|
-
'.aioson/agents/analyst.md',
|
|
12
|
-
'.aioson/agents/scope-check.md',
|
|
13
|
-
'.aioson/agents/architect.md',
|
|
9
|
+
'.aioson/agents/discovery-design-doc.md',
|
|
10
|
+
'.aioson/agents/discover.md',
|
|
11
|
+
'.aioson/agents/analyst.md',
|
|
12
|
+
'.aioson/agents/scope-check.md',
|
|
13
|
+
'.aioson/agents/architect.md',
|
|
14
14
|
'.aioson/agents/ux-ui.md',
|
|
15
15
|
'.aioson/agents/product.md',
|
|
16
|
-
'.aioson/agents/deyvin.md',
|
|
17
|
-
'.aioson/agents/pair.md',
|
|
18
|
-
'.aioson/agents/pm.md',
|
|
19
|
-
'.aioson/agents/sheldon.md',
|
|
20
|
-
'.aioson/agents/dev.md',
|
|
21
|
-
'.aioson/agents/qa.md',
|
|
16
|
+
'.aioson/agents/deyvin.md',
|
|
17
|
+
'.aioson/agents/pair.md',
|
|
18
|
+
'.aioson/agents/pm.md',
|
|
19
|
+
'.aioson/agents/sheldon.md',
|
|
20
|
+
'.aioson/agents/dev.md',
|
|
21
|
+
'.aioson/agents/qa.md',
|
|
22
22
|
'.aioson/agents/validator.md',
|
|
23
23
|
'.aioson/agents/tester.md',
|
|
24
24
|
'.aioson/agents/orchestrator.md',
|
|
25
25
|
'.aioson/agents/pentester.md',
|
|
26
26
|
'.aioson/agents/squad.md',
|
|
27
|
-
'.aioson/agents/orache.md',
|
|
28
|
-
'.aioson/agents/genome.md',
|
|
29
|
-
'.aioson/agents/neo.md',
|
|
30
|
-
'.aioson/agents/design-hybrid-forge.md',
|
|
27
|
+
'.aioson/agents/orache.md',
|
|
28
|
+
'.aioson/agents/genome.md',
|
|
29
|
+
'.aioson/agents/neo.md',
|
|
30
|
+
'.aioson/agents/design-hybrid-forge.md',
|
|
31
31
|
'.aioson/agents/site-forge.md',
|
|
32
32
|
'.aioson/agents/profiler-researcher.md',
|
|
33
|
-
'.aioson/agents/profiler-enricher.md',
|
|
34
|
-
'.aioson/agents/profiler-forge.md',
|
|
35
|
-
'.aioson/agents/committer.md',
|
|
36
|
-
'.aioson/agents/copywriter.md',
|
|
37
|
-
'.aioson/agents/briefing.md',
|
|
38
|
-
'.aioson/agents/briefing-refiner.md',
|
|
39
|
-
'.aioson/
|
|
33
|
+
'.aioson/agents/profiler-enricher.md',
|
|
34
|
+
'.aioson/agents/profiler-forge.md',
|
|
35
|
+
'.aioson/agents/committer.md',
|
|
36
|
+
'.aioson/agents/copywriter.md',
|
|
37
|
+
'.aioson/agents/briefing.md',
|
|
38
|
+
'.aioson/agents/briefing-refiner.md',
|
|
39
|
+
'.aioson/agents/forge-run.md',
|
|
40
|
+
'.aioson/docs/squad/package-contract.md',
|
|
40
41
|
'.aioson/docs/squad/creation-flow.md',
|
|
41
42
|
'.aioson/docs/squad/research-loop.md',
|
|
42
43
|
'.aioson/docs/squad/quality-lens.md',
|
|
@@ -61,13 +62,13 @@ const MANAGED_FILES = [
|
|
|
61
62
|
'.aioson/docs/dev/stack-conventions.md',
|
|
62
63
|
'.aioson/docs/dev/execution-discipline.md',
|
|
63
64
|
'.aioson/docs/quality/code-health-analysis.md',
|
|
64
|
-
'.aioson/skills/process/decision-presentation/SKILL.md',
|
|
65
|
-
'.aioson/skills/process/decision-presentation/references/jargon-map.en.yaml',
|
|
66
|
-
'.aioson/skills/process/decision-presentation/references/jargon-map.pt-BR.yaml',
|
|
67
|
-
'.aioson/skills/process/prompt-sharpener/SKILL.md',
|
|
68
|
-
'.aioson/skills/process/prompt-sharpener/references/prompt-diagnostics.md',
|
|
69
|
-
'.aioson/skills/process/prompt-sharpener/agents/openai.yaml',
|
|
70
|
-
'.aioson/skills/static/laravel-conventions.md',
|
|
65
|
+
'.aioson/skills/process/decision-presentation/SKILL.md',
|
|
66
|
+
'.aioson/skills/process/decision-presentation/references/jargon-map.en.yaml',
|
|
67
|
+
'.aioson/skills/process/decision-presentation/references/jargon-map.pt-BR.yaml',
|
|
68
|
+
'.aioson/skills/process/prompt-sharpener/SKILL.md',
|
|
69
|
+
'.aioson/skills/process/prompt-sharpener/references/prompt-diagnostics.md',
|
|
70
|
+
'.aioson/skills/process/prompt-sharpener/agents/openai.yaml',
|
|
71
|
+
'.aioson/skills/static/laravel-conventions.md',
|
|
71
72
|
'.aioson/skills/static/tall-stack-patterns.md',
|
|
72
73
|
'.aioson/skills/static/jetstream-setup.md',
|
|
73
74
|
'.aioson/skills/static/rails-conventions.md',
|
|
@@ -139,10 +140,10 @@ const MANAGED_FILES = [
|
|
|
139
140
|
];
|
|
140
141
|
|
|
141
142
|
const REQUIRED_FILES = [
|
|
142
|
-
'CLAUDE.md',
|
|
143
|
-
'AGENTS.md',
|
|
144
|
-
'OPENCODE.md',
|
|
145
|
-
'.claude/commands/aioson/agent/setup.md',
|
|
143
|
+
'CLAUDE.md',
|
|
144
|
+
'AGENTS.md',
|
|
145
|
+
'OPENCODE.md',
|
|
146
|
+
'.claude/commands/aioson/agent/setup.md',
|
|
146
147
|
'.claude/commands/aioson/agent/discover.md',
|
|
147
148
|
'.claude/commands/aioson/agent/dev.md',
|
|
148
149
|
'.claude/commands/aioson/agent/qa.md',
|
|
@@ -184,12 +185,12 @@ const AGENT_DEFINITIONS = [
|
|
|
184
185
|
{
|
|
185
186
|
id: 'discovery-design-doc',
|
|
186
187
|
displayName: 'Discovery/Design Doc',
|
|
187
|
-
description: 'Discovery and design doc generation',
|
|
188
|
-
command: '@discovery-design-doc',
|
|
189
|
-
path: '.aioson/agents/discovery-design-doc.md',
|
|
190
|
-
dependsOn: ['.aioson/context/project.context.md'],
|
|
191
|
-
output: '.aioson/context/design-doc*.md + .aioson/context/readiness*.md'
|
|
192
|
-
},
|
|
188
|
+
description: 'Discovery and design doc generation',
|
|
189
|
+
command: '@discovery-design-doc',
|
|
190
|
+
path: '.aioson/agents/discovery-design-doc.md',
|
|
191
|
+
dependsOn: ['.aioson/context/project.context.md'],
|
|
192
|
+
output: '.aioson/context/design-doc*.md + .aioson/context/readiness*.md'
|
|
193
|
+
},
|
|
193
194
|
{
|
|
194
195
|
id: 'discover',
|
|
195
196
|
displayName: 'Discover',
|
|
@@ -218,38 +219,38 @@ const AGENT_DEFINITIONS = [
|
|
|
218
219
|
dependsOn: ['.aioson/context/project.context.md'],
|
|
219
220
|
output: 'small code changes + continuity notes in spec.md + runtime logs/tasks'
|
|
220
221
|
},
|
|
221
|
-
{
|
|
222
|
-
id: 'analyst',
|
|
223
|
-
displayName: 'Analyst',
|
|
224
|
-
description: 'Domain discovery and entity mapping (SMALL/MEDIUM)',
|
|
225
|
-
command: '@analyst',
|
|
226
|
-
path: '.aioson/agents/analyst.md',
|
|
227
|
-
dependsOn: ['.aioson/context/project.context.md'],
|
|
228
|
-
output: '.aioson/context/discovery.md or .aioson/context/requirements-{slug}.md + .aioson/context/spec-{slug}.md'
|
|
229
|
-
},
|
|
230
|
-
{
|
|
231
|
-
id: 'scope-check',
|
|
232
|
-
displayName: 'Scope Check',
|
|
233
|
-
description: 'Scope alignment before development and optional post-dev drift checks',
|
|
234
|
-
command: '@scope-check',
|
|
235
|
-
path: '.aioson/agents/scope-check.md',
|
|
236
|
-
dependsOn: [
|
|
237
|
-
'.aioson/context/project.context.md',
|
|
238
|
-
'.aioson/context/prd.md or .aioson/context/prd-{slug}.md',
|
|
239
|
-
'.aioson/context/discovery.md or .aioson/context/requirements-{slug}.md + .aioson/context/spec-{slug}.md'
|
|
240
|
-
],
|
|
241
|
-
output: '.aioson/context/scope-check.md or .aioson/context/scope-check-{slug}.md'
|
|
242
|
-
},
|
|
243
|
-
{
|
|
244
|
-
id: 'architect',
|
|
222
|
+
{
|
|
223
|
+
id: 'analyst',
|
|
224
|
+
displayName: 'Analyst',
|
|
225
|
+
description: 'Domain discovery and entity mapping (SMALL/MEDIUM)',
|
|
226
|
+
command: '@analyst',
|
|
227
|
+
path: '.aioson/agents/analyst.md',
|
|
228
|
+
dependsOn: ['.aioson/context/project.context.md'],
|
|
229
|
+
output: '.aioson/context/discovery.md or .aioson/context/requirements-{slug}.md + .aioson/context/spec-{slug}.md'
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
id: 'scope-check',
|
|
233
|
+
displayName: 'Scope Check',
|
|
234
|
+
description: 'Scope alignment before development and optional post-dev drift checks',
|
|
235
|
+
command: '@scope-check',
|
|
236
|
+
path: '.aioson/agents/scope-check.md',
|
|
237
|
+
dependsOn: [
|
|
238
|
+
'.aioson/context/project.context.md',
|
|
239
|
+
'.aioson/context/prd.md or .aioson/context/prd-{slug}.md',
|
|
240
|
+
'.aioson/context/discovery.md or .aioson/context/requirements-{slug}.md + .aioson/context/spec-{slug}.md'
|
|
241
|
+
],
|
|
242
|
+
output: '.aioson/context/scope-check.md or .aioson/context/scope-check-{slug}.md'
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
id: 'architect',
|
|
245
246
|
displayName: 'Architect',
|
|
246
247
|
description: 'Project structure and technical decisions (SMALL/MEDIUM)',
|
|
247
248
|
command: '@architect',
|
|
248
249
|
path: '.aioson/agents/architect.md',
|
|
249
|
-
dependsOn: [
|
|
250
|
-
'.aioson/context/project.context.md',
|
|
251
|
-
'.aioson/context/discovery.md or .aioson/context/requirements-{slug}.md + .aioson/context/spec-{slug}.md'
|
|
252
|
-
],
|
|
250
|
+
dependsOn: [
|
|
251
|
+
'.aioson/context/project.context.md',
|
|
252
|
+
'.aioson/context/discovery.md or .aioson/context/requirements-{slug}.md + .aioson/context/spec-{slug}.md'
|
|
253
|
+
],
|
|
253
254
|
output: '.aioson/context/architecture.md'
|
|
254
255
|
},
|
|
255
256
|
{
|
|
@@ -272,16 +273,16 @@ const AGENT_DEFINITIONS = [
|
|
|
272
273
|
description: 'Backlog and user stories (MEDIUM only)',
|
|
273
274
|
command: '@pm',
|
|
274
275
|
path: '.aioson/agents/pm.md',
|
|
275
|
-
dependsOn: [
|
|
276
|
-
'.aioson/context/project.context.md',
|
|
277
|
-
'.aioson/context/prd.md or .aioson/context/prd-{slug}.md',
|
|
278
|
-
'.aioson/context/requirements-{slug}.md + .aioson/context/spec-{slug}.md (feature mode)',
|
|
279
|
-
'.aioson/context/discovery.md',
|
|
280
|
-
'.aioson/context/architecture.md',
|
|
281
|
-
'.aioson/context/design-doc-{slug}.md + .aioson/context/readiness-{slug}.md (feature mode, when present)',
|
|
282
|
-
'.aioson/context/ui-spec.md (when present)'
|
|
283
|
-
],
|
|
284
|
-
output: '.aioson/context/prd.md or prd-{slug}.md (enriched with acceptance criteria) + .aioson/context/implementation-plan-{slug}.md for MEDIUM features'
|
|
276
|
+
dependsOn: [
|
|
277
|
+
'.aioson/context/project.context.md',
|
|
278
|
+
'.aioson/context/prd.md or .aioson/context/prd-{slug}.md',
|
|
279
|
+
'.aioson/context/requirements-{slug}.md + .aioson/context/spec-{slug}.md (feature mode)',
|
|
280
|
+
'.aioson/context/discovery.md',
|
|
281
|
+
'.aioson/context/architecture.md',
|
|
282
|
+
'.aioson/context/design-doc-{slug}.md + .aioson/context/readiness-{slug}.md (feature mode, when present)',
|
|
283
|
+
'.aioson/context/ui-spec.md (when present)'
|
|
284
|
+
],
|
|
285
|
+
output: '.aioson/context/prd.md or prd-{slug}.md (enriched with acceptance criteria) + .aioson/context/implementation-plan-{slug}.md for MEDIUM features'
|
|
285
286
|
},
|
|
286
287
|
{
|
|
287
288
|
id: 'dev',
|
|
@@ -405,6 +406,15 @@ const AGENT_DEFINITIONS = [
|
|
|
405
406
|
dependsOn: ['.aioson/context/project.context.md'],
|
|
406
407
|
output: 'src/components/*.tsx + src/app/page.tsx + docs/research/{hostname}/ + public/images/{hostname}/'
|
|
407
408
|
},
|
|
409
|
+
{
|
|
410
|
+
id: 'forge-run',
|
|
411
|
+
displayName: 'Forge Run',
|
|
412
|
+
description: 'Compile and run the Lane B workflow harness for a MEDIUM feature',
|
|
413
|
+
command: '@forge-run',
|
|
414
|
+
path: '.aioson/agents/forge-run.md',
|
|
415
|
+
dependsOn: ['.aioson/context/project.context.md'],
|
|
416
|
+
output: '.aioson/plans/{slug}/forge-run.workflow.js + workflow run verdict (stops before feature:close)'
|
|
417
|
+
},
|
|
408
418
|
{
|
|
409
419
|
id: 'neo',
|
|
410
420
|
displayName: 'Neo',
|
|
@@ -414,15 +424,15 @@ const AGENT_DEFINITIONS = [
|
|
|
414
424
|
dependsOn: ['.aioson/context/project.context.md'],
|
|
415
425
|
output: 'routing decision + agent handoff'
|
|
416
426
|
},
|
|
417
|
-
{
|
|
418
|
-
id: 'sheldon',
|
|
419
|
-
displayName: 'Sheldon',
|
|
420
|
-
description: 'PRD quality review and pre-implementation enrichment',
|
|
421
|
-
command: '@sheldon',
|
|
422
|
-
path: '.aioson/agents/sheldon.md',
|
|
423
|
-
dependsOn: ['.aioson/context/project.context.md'],
|
|
424
|
-
output: 'enriched PRD or phased execution plan'
|
|
425
|
-
},
|
|
427
|
+
{
|
|
428
|
+
id: 'sheldon',
|
|
429
|
+
displayName: 'Sheldon',
|
|
430
|
+
description: 'PRD quality review and pre-implementation enrichment',
|
|
431
|
+
command: '@sheldon',
|
|
432
|
+
path: '.aioson/agents/sheldon.md',
|
|
433
|
+
dependsOn: ['.aioson/context/project.context.md'],
|
|
434
|
+
output: 'enriched PRD or phased execution plan'
|
|
435
|
+
},
|
|
426
436
|
{
|
|
427
437
|
id: 'committer',
|
|
428
438
|
displayName: 'Committer',
|
|
@@ -441,26 +451,26 @@ const AGENT_DEFINITIONS = [
|
|
|
441
451
|
dependsOn: [],
|
|
442
452
|
output: 'marketing copy + content assets'
|
|
443
453
|
},
|
|
444
|
-
{
|
|
445
|
-
id: 'briefing',
|
|
446
|
-
displayName: 'Briefing',
|
|
447
|
-
description: 'Pre-production briefings and planning',
|
|
448
|
-
command: '@briefing',
|
|
454
|
+
{
|
|
455
|
+
id: 'briefing',
|
|
456
|
+
displayName: 'Briefing',
|
|
457
|
+
description: 'Pre-production briefings and planning',
|
|
458
|
+
command: '@briefing',
|
|
449
459
|
path: '.aioson/agents/briefing.md',
|
|
450
|
-
dependsOn: ['.aioson/context/project.context.md'],
|
|
451
|
-
output: '.aioson/briefings/{slug}/'
|
|
452
|
-
},
|
|
453
|
-
{
|
|
454
|
-
id: 'briefing-refiner',
|
|
455
|
-
displayName: 'Briefing Refiner',
|
|
456
|
-
description: 'Interactive refinement of briefing artifacts before Product PRD generation',
|
|
457
|
-
command: '@briefing-refiner',
|
|
458
|
-
path: '.aioson/agents/briefing-refiner.md',
|
|
459
|
-
dependsOn: ['.aioson/context/project.context.md', '.aioson/briefings/config.md'],
|
|
460
|
-
output: '.aioson/briefings/{slug}/review.html + refinement-feedback.json + refinement-report.md'
|
|
461
|
-
},
|
|
462
|
-
{
|
|
463
|
-
id: 'profiler-researcher',
|
|
460
|
+
dependsOn: ['.aioson/context/project.context.md'],
|
|
461
|
+
output: '.aioson/briefings/{slug}/'
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
id: 'briefing-refiner',
|
|
465
|
+
displayName: 'Briefing Refiner',
|
|
466
|
+
description: 'Interactive refinement of briefing artifacts before Product PRD generation',
|
|
467
|
+
command: '@briefing-refiner',
|
|
468
|
+
path: '.aioson/agents/briefing-refiner.md',
|
|
469
|
+
dependsOn: ['.aioson/context/project.context.md', '.aioson/briefings/config.md'],
|
|
470
|
+
output: '.aioson/briefings/{slug}/review.html + refinement-feedback.json + refinement-report.md'
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
id: 'profiler-researcher',
|
|
464
474
|
displayName: 'Profiler Researcher',
|
|
465
475
|
description: 'Clone profiler: research phase',
|
|
466
476
|
command: '@profiler-researcher',
|