@jaimevalasek/aioson 1.23.3 → 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/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/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/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/.claude/commands/aioson/agent/forge-run.md +17 -0
- package/template/AGENTS.md +15 -13
- package/template/CLAUDE.md +10 -9
- package/template/OPENCODE.md +24 -23
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Parser da tabela "Execution Sequence" do implementation-plan-{slug}.md
|
|
5
|
+
* (convenção Wave do @pm — Fase 4/5 do plano de verificação executável).
|
|
6
|
+
*
|
|
7
|
+
* Compartilhado entre `spec:analyze` (check wave_file_overlap) e
|
|
8
|
+
* `forge:compile` (compilação spec → workflow script). Sem coluna Wave a
|
|
9
|
+
* função retorna null — chamadores tratam como "convenção ausente"
|
|
10
|
+
* (retrocompat com planos antigos).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param {string} content — markdown do implementation-plan
|
|
15
|
+
* @returns {Array<{phase, wave, files: string[], scope, done}>|null}
|
|
16
|
+
*/
|
|
17
|
+
function parseExecutionWaves(content) {
|
|
18
|
+
const lines = String(content || '').split(/\r?\n/);
|
|
19
|
+
let columns = null;
|
|
20
|
+
const rows = [];
|
|
21
|
+
|
|
22
|
+
for (const line of lines) {
|
|
23
|
+
const trimmed = line.trim();
|
|
24
|
+
if (!trimmed.startsWith('|')) {
|
|
25
|
+
if (columns && rows.length) break; // fim da tabela alvo
|
|
26
|
+
columns = columns && rows.length === 0 ? columns : null;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const cells = trimmed.split('|').slice(1, -1).map((c) => c.trim());
|
|
30
|
+
const lower = cells.map((c) => c.toLowerCase());
|
|
31
|
+
|
|
32
|
+
if (!columns) {
|
|
33
|
+
if (lower.includes('wave') && lower.some((c) => c.includes('phase')) && lower.some((c) => c.includes('file'))) {
|
|
34
|
+
columns = {
|
|
35
|
+
phase: lower.findIndex((c) => c.includes('phase')),
|
|
36
|
+
wave: lower.indexOf('wave'),
|
|
37
|
+
files: lower.findIndex((c) => c.includes('file')),
|
|
38
|
+
scope: lower.findIndex((c) => c.includes('scope')),
|
|
39
|
+
done: lower.findIndex((c) => c.includes('done'))
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (cells.every((c) => /^:?-{2,}:?$/.test(c))) continue; // separador
|
|
46
|
+
|
|
47
|
+
const wave = parseInt(cells[columns.wave], 10);
|
|
48
|
+
if (!Number.isInteger(wave)) continue;
|
|
49
|
+
const files = (cells[columns.files] || '')
|
|
50
|
+
.split(/,|<br\s*\/?\s*>/i)
|
|
51
|
+
.map((f) => f.replace(/`/g, '').trim().replace(/\\/g, '/').toLowerCase())
|
|
52
|
+
.filter((f) => f && !/^(\.{3}|-|—)$/.test(f));
|
|
53
|
+
rows.push({
|
|
54
|
+
phase: cells[columns.phase] || `row ${rows.length + 1}`,
|
|
55
|
+
wave,
|
|
56
|
+
files,
|
|
57
|
+
scope: columns.scope >= 0 ? (cells[columns.scope] || '') : '',
|
|
58
|
+
done: columns.done >= 0 ? (cells[columns.done] || '') : ''
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return columns ? rows : null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Agrupa as fases por wave, em ordem ascendente. */
|
|
66
|
+
function groupByWave(rows) {
|
|
67
|
+
const byWave = new Map();
|
|
68
|
+
for (const row of rows || []) {
|
|
69
|
+
if (!byWave.has(row.wave)) byWave.set(row.wave, []);
|
|
70
|
+
byWave.get(row.wave).push(row);
|
|
71
|
+
}
|
|
72
|
+
return [...byWave.entries()]
|
|
73
|
+
.sort((a, b) => a[0] - b[0])
|
|
74
|
+
.map(([wave, phases]) => ({ wave, phases }));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
module.exports = { parseExecutionWaves, groupByWave };
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Payload de revisão fresh-context para o prompt do @validator (Fase 2 do
|
|
5
|
+
* plano de verificação executável).
|
|
6
|
+
*
|
|
7
|
+
* `harness:validate` gera o prompt do @validator headless; este módulo anexa
|
|
8
|
+
* a ele tudo que um contexto ISOLADO precisa para validar sem herdar o
|
|
9
|
+
* histórico da sessão que implementou: diff vs base, lista de arquivos
|
|
10
|
+
* alterados (incluindo untracked), resultado dos checks determinísticos
|
|
11
|
+
* (last-check-output.json) e a instrução de onde gravar o veredito JSON.
|
|
12
|
+
*
|
|
13
|
+
* Nunca lança: fora de um repo git (ou em falha de I/O) retorna um payload
|
|
14
|
+
* degradado com a nota correspondente — os testes do router rodam em tmpdir
|
|
15
|
+
* sem git e devem continuar passando.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const fs = require('node:fs');
|
|
19
|
+
const path = require('node:path');
|
|
20
|
+
const { execFileSync } = require('node:child_process');
|
|
21
|
+
|
|
22
|
+
const { parsePorcelain } = require('./git-baseline');
|
|
23
|
+
const { matchGlob } = require('./glob-match');
|
|
24
|
+
|
|
25
|
+
/** Estado do framework não é superfície de revisão (mesmo precedente do git-baseline). */
|
|
26
|
+
const FRAMEWORK_STATE_GLOB = '.aioson/**';
|
|
27
|
+
|
|
28
|
+
const DEFAULT_MAX_DIFF_BYTES = 200000;
|
|
29
|
+
|
|
30
|
+
function git(targetDir, gitArgs) {
|
|
31
|
+
return execFileSync('git', gitArgs, {
|
|
32
|
+
cwd: targetDir,
|
|
33
|
+
encoding: 'utf8',
|
|
34
|
+
maxBuffer: 1024 * 1024 * 20,
|
|
35
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Resolve a ref base do diff, na ordem:
|
|
41
|
+
* 1. `baseRef` explícito (--base)
|
|
42
|
+
* 2. `baseline.json` do plan dir (HEAD capturado no preflight do self:loop)
|
|
43
|
+
* 3. merge-base de HEAD com main/master (local)
|
|
44
|
+
* 4. 'HEAD' (apenas mudanças não commitadas)
|
|
45
|
+
*
|
|
46
|
+
* @returns {{ base: string, source: string }}
|
|
47
|
+
*/
|
|
48
|
+
function resolveBase(targetDir, planDir, baseRef) {
|
|
49
|
+
if (baseRef) return { base: String(baseRef), source: 'explicit --base' };
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
const baselinePath = path.join(planDir, 'baseline.json');
|
|
53
|
+
if (fs.existsSync(baselinePath)) {
|
|
54
|
+
const baseline = JSON.parse(fs.readFileSync(baselinePath, 'utf8'));
|
|
55
|
+
if (baseline && baseline.head) return { base: baseline.head, source: 'baseline.json (loop preflight)' };
|
|
56
|
+
}
|
|
57
|
+
} catch { /* baseline ilegível — segue o fallback */ }
|
|
58
|
+
|
|
59
|
+
for (const branch of ['main', 'master']) {
|
|
60
|
+
try {
|
|
61
|
+
const mergeBase = git(targetDir, ['merge-base', 'HEAD', branch]).trim();
|
|
62
|
+
const head = git(targetDir, ['rev-parse', 'HEAD']).trim();
|
|
63
|
+
// merge-base === HEAD significa que estamos NO branch (ou atrás dele):
|
|
64
|
+
// o diff vs base seria vazio; cai para HEAD (mudanças não commitadas).
|
|
65
|
+
if (mergeBase && mergeBase !== head) return { base: mergeBase, source: `merge-base with ${branch}` };
|
|
66
|
+
} catch { /* branch ausente — tenta o próximo */ }
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return { base: 'HEAD', source: 'fallback (uncommitted changes only)' };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Trunca em fronteira de linha com marcador; bytes UTF-8. */
|
|
73
|
+
function truncateDiff(diff, maxBytes) {
|
|
74
|
+
const bytes = Buffer.byteLength(diff, 'utf8');
|
|
75
|
+
if (bytes <= maxBytes) return { diff, truncated: false, bytes };
|
|
76
|
+
let slice = Buffer.from(diff, 'utf8').subarray(0, maxBytes).toString('utf8');
|
|
77
|
+
// remove eventual caractere multibyte cortado e fecha na última linha completa
|
|
78
|
+
slice = slice.replace(/�+$/g, '');
|
|
79
|
+
const lastNewline = slice.lastIndexOf('\n');
|
|
80
|
+
if (lastNewline > 0) slice = slice.slice(0, lastNewline);
|
|
81
|
+
return {
|
|
82
|
+
diff: `${slice}\n... [diff truncated at ${maxBytes} bytes of ${bytes} — read the changed files directly for the rest]`,
|
|
83
|
+
truncated: true,
|
|
84
|
+
bytes
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Sumariza last-check-output.json em linhas de texto; null quando ausente. */
|
|
89
|
+
function summarizeCheckOutput(planDir) {
|
|
90
|
+
const checkPath = path.join(planDir, 'last-check-output.json');
|
|
91
|
+
if (!fs.existsSync(checkPath)) return null;
|
|
92
|
+
try {
|
|
93
|
+
const report = JSON.parse(fs.readFileSync(checkPath, 'utf8'));
|
|
94
|
+
const lines = [
|
|
95
|
+
`Ran at: ${report.checked_at} — ${report.passed}/${report.executable_total} executable checks passed, ${report.skipped_no_verification} criteria without verification.`
|
|
96
|
+
];
|
|
97
|
+
for (const check of report.checks || []) {
|
|
98
|
+
lines.push(`- ${check.ok ? 'PASS' : 'FAIL'} ${check.id} — \`${check.command}\` (exit ${check.exitCode}${check.timedOut ? ', timeout' : ''})`);
|
|
99
|
+
}
|
|
100
|
+
lines.push('Copy these exit-code verdicts verbatim into `results[].passed` for their criteria — do not re-judge them.');
|
|
101
|
+
return lines.join('\n');
|
|
102
|
+
} catch {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Monta o payload de revisão. Nunca lança.
|
|
109
|
+
*
|
|
110
|
+
* @param {string} targetDir — raiz do projeto
|
|
111
|
+
* @param {string} planDir — .aioson/plans/{slug}
|
|
112
|
+
* @param {object} opts
|
|
113
|
+
* @param {string} [opts.slug]
|
|
114
|
+
* @param {string} [opts.baseRef] — ref explícita (--base)
|
|
115
|
+
* @param {number} [opts.maxDiffBytes]
|
|
116
|
+
* @param {string} [opts.outputPath] — onde o validator grava o JSON
|
|
117
|
+
* @returns {{ ok, base, baseSource, changedFiles, untracked, truncated, diffBytes, hasChecks, text }}
|
|
118
|
+
*/
|
|
119
|
+
function buildReviewPayload(targetDir, planDir, opts = {}) {
|
|
120
|
+
const maxDiffBytes = Number.isInteger(Number(opts.maxDiffBytes)) && Number(opts.maxDiffBytes) > 0
|
|
121
|
+
? Number(opts.maxDiffBytes)
|
|
122
|
+
: DEFAULT_MAX_DIFF_BYTES;
|
|
123
|
+
const checkSummary = summarizeCheckOutput(planDir);
|
|
124
|
+
|
|
125
|
+
const header = [
|
|
126
|
+
'',
|
|
127
|
+
'---',
|
|
128
|
+
'',
|
|
129
|
+
'## Review payload (generated by `aioson harness:validate`)',
|
|
130
|
+
'',
|
|
131
|
+
'> Run this prompt in a **fresh, isolated context** (subagent/Task tool or a separate session). Never validate inline in the session that implemented the feature — the implementation history biases the verdict.',
|
|
132
|
+
''
|
|
133
|
+
];
|
|
134
|
+
|
|
135
|
+
const outputBlock = [
|
|
136
|
+
'### Verdict output',
|
|
137
|
+
'',
|
|
138
|
+
`Write **only** the validator JSON verdict${opts.outputPath ? ` to: \`${opts.outputPath}\`` : ''}.`,
|
|
139
|
+
opts.slug ? `The orchestrating session then consumes it with: \`aioson harness:validate . --slug=${opts.slug}\`` : '',
|
|
140
|
+
''
|
|
141
|
+
].filter((line) => line !== '');
|
|
142
|
+
|
|
143
|
+
const checksBlock = [
|
|
144
|
+
'### Deterministic check results (`aioson harness:check`)',
|
|
145
|
+
'',
|
|
146
|
+
checkSummary || 'No `last-check-output.json` found — run `aioson harness:check` first (criteria with `verification` must be decided by exit code, not judgment).',
|
|
147
|
+
''
|
|
148
|
+
];
|
|
149
|
+
|
|
150
|
+
let gitFailed = false;
|
|
151
|
+
let base = null;
|
|
152
|
+
let baseSource = null;
|
|
153
|
+
let changedFiles = [];
|
|
154
|
+
let untracked = [];
|
|
155
|
+
let diffResult = { diff: '', truncated: false, bytes: 0 };
|
|
156
|
+
|
|
157
|
+
try {
|
|
158
|
+
const resolved = resolveBase(targetDir, planDir, opts.baseRef);
|
|
159
|
+
base = resolved.base;
|
|
160
|
+
baseSource = resolved.source;
|
|
161
|
+
|
|
162
|
+
const nameStatus = git(targetDir, ['diff', '--name-status', base]);
|
|
163
|
+
changedFiles = nameStatus
|
|
164
|
+
.split('\n')
|
|
165
|
+
.map((line) => line.trim())
|
|
166
|
+
.filter(Boolean)
|
|
167
|
+
.map((line) => {
|
|
168
|
+
const [status, ...rest] = line.split('\t');
|
|
169
|
+
return { status, path: rest.join('\t') };
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
untracked = parsePorcelain(git(targetDir, ['status', '--porcelain', '-uall']))
|
|
173
|
+
.filter((entry) => entry.status === 'added' && !matchGlob(FRAMEWORK_STATE_GLOB, entry.path))
|
|
174
|
+
.map((entry) => entry.path);
|
|
175
|
+
|
|
176
|
+
diffResult = truncateDiff(git(targetDir, ['diff', base]), maxDiffBytes);
|
|
177
|
+
} catch {
|
|
178
|
+
gitFailed = true;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
let diffBlock;
|
|
182
|
+
if (gitFailed) {
|
|
183
|
+
diffBlock = [
|
|
184
|
+
'### Diff under review',
|
|
185
|
+
'',
|
|
186
|
+
'Diff unavailable (not a git repository or git failed). Review the files listed in `progress.json.completed_steps` directly.',
|
|
187
|
+
''
|
|
188
|
+
];
|
|
189
|
+
} else {
|
|
190
|
+
const fileLines = [
|
|
191
|
+
...changedFiles.map((f) => `- ${f.status} ${f.path}`),
|
|
192
|
+
...untracked.map((p) => `- ?? ${p} (untracked)`)
|
|
193
|
+
];
|
|
194
|
+
diffBlock = [
|
|
195
|
+
`### Changed files vs base \`${base}\` (${baseSource})`,
|
|
196
|
+
'',
|
|
197
|
+
fileLines.length ? fileLines.join('\n') : '(no changes detected)',
|
|
198
|
+
'',
|
|
199
|
+
'### Unified diff',
|
|
200
|
+
'',
|
|
201
|
+
'Untracked files do not appear in the diff below — read them directly.',
|
|
202
|
+
'',
|
|
203
|
+
'```diff',
|
|
204
|
+
diffResult.diff || '(empty diff)',
|
|
205
|
+
'```',
|
|
206
|
+
''
|
|
207
|
+
];
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const text = [...header, ...checksBlock, ...diffBlock, ...outputBlock].join('\n');
|
|
211
|
+
|
|
212
|
+
return {
|
|
213
|
+
ok: !gitFailed,
|
|
214
|
+
base,
|
|
215
|
+
baseSource,
|
|
216
|
+
changedFiles,
|
|
217
|
+
untracked,
|
|
218
|
+
truncated: diffResult.truncated,
|
|
219
|
+
diffBytes: diffResult.bytes,
|
|
220
|
+
hasChecks: Boolean(checkSummary),
|
|
221
|
+
text
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
module.exports = {
|
|
226
|
+
DEFAULT_MAX_DIFF_BYTES,
|
|
227
|
+
resolveBase,
|
|
228
|
+
truncateDiff,
|
|
229
|
+
buildReviewPayload
|
|
230
|
+
};
|
package/src/i18n/messages/en.js
CHANGED
|
@@ -21,16 +21,16 @@ module.exports = {
|
|
|
21
21
|
'aioson agent:prompt <agent> [path] [--tool=codex|claude|opencode] [--lang=<bcp47-tag>] [--locale=en]',
|
|
22
22
|
help_agent_help:
|
|
23
23
|
'aioson agent:help [agent] [--json]',
|
|
24
|
-
help_agent_invoke:
|
|
25
|
-
'aioson agent:invoke <agent> [path] [--tool=codex|claude|opencode] [--mode=framework_target|app_target] [--feature=<slug>] [--scope=<area>] [--lang=<bcp47-tag>] [--locale=en]',
|
|
26
|
-
help_agent_epilogue:
|
|
27
|
-
'aioson agent:epilogue [path] --agent=<agent> --summary=<text> [--feature=<slug>] [--approve-gate=A|B|C|D] [--json] [--locale=en]',
|
|
24
|
+
help_agent_invoke:
|
|
25
|
+
'aioson agent:invoke <agent> [path] [--tool=codex|claude|opencode] [--mode=framework_target|app_target] [--feature=<slug>] [--scope=<area>] [--lang=<bcp47-tag>] [--locale=en]',
|
|
26
|
+
help_agent_epilogue:
|
|
27
|
+
'aioson agent:epilogue [path] --agent=<agent> --summary=<text> [--feature=<slug>] [--approve-gate=A|B|C|D] [--json] [--locale=en]',
|
|
28
28
|
help_context_validate: 'aioson context:validate [path] [--json] [--locale=en]',
|
|
29
|
-
help_context_pack:
|
|
30
|
-
'aioson context:pack [path] [--agent=<agent>] [--goal=<text>] [--module=<module-or-folder>] [--max-files=8] [--json] [--locale=en]',
|
|
31
|
-
help_context_select:
|
|
32
|
-
'aioson context:select [path] [--agent=<agent>] [--mode=planning|executing] [--task=<text>] [--paths=<path[,path2]>] [--feature=<slug>] [--json] [--locale=en]',
|
|
33
|
-
help_context_load:
|
|
29
|
+
help_context_pack:
|
|
30
|
+
'aioson context:pack [path] [--agent=<agent>] [--goal=<text>] [--module=<module-or-folder>] [--max-files=8] [--json] [--locale=en]',
|
|
31
|
+
help_context_select:
|
|
32
|
+
'aioson context:select [path] [--agent=<agent>] [--mode=planning|executing] [--task=<text>] [--paths=<path[,path2]>] [--feature=<slug>] [--json] [--locale=en]',
|
|
33
|
+
help_context_load:
|
|
34
34
|
'aioson context:load [path] --target=<rule|brain>:<slug> --agent=<name> [--batch="slug1,slug2"] [--feature=<slug>] [--classification=<MICRO|SMALL|MEDIUM>] [--verbose] [--json] [--locale=en]',
|
|
35
35
|
help_chain_audit:
|
|
36
36
|
'aioson chain:audit <file> [path] [--limit=N] [--feature=<slug>] [--json] [--locale=en]',
|
|
@@ -122,10 +122,10 @@ module.exports = {
|
|
|
122
122
|
'aioson workflow:next [path] [--complete[=<agent>]] [--agent=<agent>] [--skip=<agent>] [--status] [--suggest] [--tool=codex|claude|opencode] [--json] [--locale=en]',
|
|
123
123
|
help_workflow_status:
|
|
124
124
|
'aioson workflow:status [path] [--suggest] [--tool=codex|claude|opencode] [--json] [--locale=en]',
|
|
125
|
-
help_workflow_execute:
|
|
126
|
-
'aioson workflow:execute [path] [--feature=<slug>] [--agentic] [--max-dev-qa-cycles=<n>] [--max-tester-cycles=<n>] [--max-pentester-cycles=<n>] [--dry-run] [--lane=<n>] [--json] [--locale=en]',
|
|
127
|
-
help_review_cycle:
|
|
128
|
-
'aioson review-cycle:<status|advance|resolve|reset> [path] --feature=<slug> [--plan=<path>] [--source=qa|tester|pentester] [--json] [--locale=en]',
|
|
125
|
+
help_workflow_execute:
|
|
126
|
+
'aioson workflow:execute [path] [--feature=<slug>] [--agentic] [--max-dev-qa-cycles=<n>] [--max-tester-cycles=<n>] [--max-pentester-cycles=<n>] [--dry-run] [--lane=<n>] [--json] [--locale=en]',
|
|
127
|
+
help_review_cycle:
|
|
128
|
+
'aioson review-cycle:<status|advance|resolve|reset> [path] --feature=<slug> [--plan=<path>] [--source=qa|tester|pentester] [--json] [--locale=en]',
|
|
129
129
|
help_parallel_init:
|
|
130
130
|
'aioson parallel:init [path] [--workers=2..6] [--force] [--dry-run] [--json] [--locale=en]',
|
|
131
131
|
help_parallel_doctor:
|
|
@@ -155,7 +155,9 @@ module.exports = {
|
|
|
155
155
|
help_harness_init:
|
|
156
156
|
'aioson harness:init [path] --slug=<slug> [--mode=BALANCED|URGENT|ECONOMICAL] [--locale=en]',
|
|
157
157
|
help_harness_validate:
|
|
158
|
-
'aioson harness:validate [path] --slug=<slug> [--artifact=<path>] [--locale=en]',
|
|
158
|
+
'aioson harness:validate [path] --slug=<slug> [--base=<ref>] [--no-diff] [--max-diff-bytes=<n>] [--artifact=<path>] [--locale=en]',
|
|
159
|
+
help_harness_check:
|
|
160
|
+
'aioson harness:check [path] --slug=<slug> [--criteria=C1,C2] [--timeout=<ms>] [--json] [--locale=en]',
|
|
159
161
|
help_harness_retro:
|
|
160
162
|
'aioson harness:retro [path] --feature=<slug> | --last=<N> [--json] [--locale=en]',
|
|
161
163
|
help_harness_preview:
|
|
@@ -1082,7 +1084,11 @@ module.exports = {
|
|
|
1082
1084
|
contract_not_found: 'Contract not found for slug: {slug}',
|
|
1083
1085
|
validating: 'Validating harness for {slug}...',
|
|
1084
1086
|
blocked: 'Execution paused: {reason}',
|
|
1085
|
-
init_dry_run: '[dry-run] Would initialize harness for {slug}'
|
|
1087
|
+
init_dry_run: '[dry-run] Would initialize harness for {slug}',
|
|
1088
|
+
check_header: 'Harness check — {slug}',
|
|
1089
|
+
check_no_executable: ' No criteria with verification commands ({total} criteria total). @validator judges them all.',
|
|
1090
|
+
check_summary: ' Checks: {passed}/{executable} passed ({skipped} without verification — judged by @validator)',
|
|
1091
|
+
check_unknown_criteria: 'Unknown criteria ids: {ids}'
|
|
1086
1092
|
},
|
|
1087
1093
|
web_map: {
|
|
1088
1094
|
url_missing: 'Missing required option: --url=<url>.',
|
package/src/i18n/messages/es.js
CHANGED
|
@@ -22,16 +22,16 @@ module.exports = {
|
|
|
22
22
|
'aioson agent:prompt <agent> [path] [--tool=codex|claude|opencode] [--lang=<bcp47-tag>] [--locale=es]',
|
|
23
23
|
help_agent_help:
|
|
24
24
|
'aioson agent:help [agent] [--json]',
|
|
25
|
-
help_agent_invoke:
|
|
26
|
-
'aioson agent:invoke <agent> [path] [--tool=codex|claude|opencode] [--mode=framework_target|app_target] [--feature=<slug>] [--scope=<area>] [--lang=<bcp47-tag>] [--locale=es]',
|
|
27
|
-
help_agent_epilogue:
|
|
28
|
-
'aioson agent:epilogue [path] --agent=<agente> --summary=<texto> [--feature=<slug>] [--approve-gate=A|B|C|D] [--json] [--locale=es]',
|
|
25
|
+
help_agent_invoke:
|
|
26
|
+
'aioson agent:invoke <agent> [path] [--tool=codex|claude|opencode] [--mode=framework_target|app_target] [--feature=<slug>] [--scope=<area>] [--lang=<bcp47-tag>] [--locale=es]',
|
|
27
|
+
help_agent_epilogue:
|
|
28
|
+
'aioson agent:epilogue [path] --agent=<agente> --summary=<texto> [--feature=<slug>] [--approve-gate=A|B|C|D] [--json] [--locale=es]',
|
|
29
29
|
help_context_validate: 'aioson context:validate [path] [--json] [--locale=es]',
|
|
30
|
-
help_context_pack:
|
|
31
|
-
'aioson context:pack [path] [--agent=<agente>] [--goal=<texto>] [--module=<modulo-o-carpeta>] [--max-files=8] [--json] [--locale=es]',
|
|
32
|
-
help_context_select:
|
|
33
|
-
'aioson context:select [path] [--agent=<agente>] [--mode=planning|executing] [--task=<texto>] [--paths=<ruta[,ruta2]>] [--feature=<slug>] [--json] [--locale=es]',
|
|
34
|
-
help_context_load:
|
|
30
|
+
help_context_pack:
|
|
31
|
+
'aioson context:pack [path] [--agent=<agente>] [--goal=<texto>] [--module=<modulo-o-carpeta>] [--max-files=8] [--json] [--locale=es]',
|
|
32
|
+
help_context_select:
|
|
33
|
+
'aioson context:select [path] [--agent=<agente>] [--mode=planning|executing] [--task=<texto>] [--paths=<ruta[,ruta2]>] [--feature=<slug>] [--json] [--locale=es]',
|
|
34
|
+
help_context_load:
|
|
35
35
|
'aioson context:load [path] --target=<rule|brain>:<slug> --agent=<nombre> [--batch="slug1,slug2"] [--feature=<slug>] [--classification=<MICRO|SMALL|MEDIUM>] [--verbose] [--json] [--locale=es]',
|
|
36
36
|
help_chain_audit:
|
|
37
37
|
'aioson chain:audit <archivo> [path] [--limit=N] [--feature=<slug>] [--json] [--locale=es]',
|
|
@@ -112,10 +112,10 @@ module.exports = {
|
|
|
112
112
|
'aioson test:package [source-path] [--keep] [--dry-run] [--json] [--locale=es]',
|
|
113
113
|
help_workflow_plan:
|
|
114
114
|
'aioson workflow:plan [path] [--classification=MICRO|SMALL|MEDIUM] [--json] [--locale=es]',
|
|
115
|
-
help_workflow_execute:
|
|
116
|
-
'aioson workflow:execute [path] [--feature=<slug>] [--agentic] [--max-dev-qa-cycles=<n>] [--max-tester-cycles=<n>] [--max-pentester-cycles=<n>] [--dry-run] [--lane=<n>] [--json] [--locale=es]',
|
|
117
|
-
help_review_cycle:
|
|
118
|
-
'aioson review-cycle:<status|advance|resolve|reset> [path] --feature=<slug> [--plan=<path>] [--source=qa|tester|pentester] [--json] [--locale=es]',
|
|
115
|
+
help_workflow_execute:
|
|
116
|
+
'aioson workflow:execute [path] [--feature=<slug>] [--agentic] [--max-dev-qa-cycles=<n>] [--max-tester-cycles=<n>] [--max-pentester-cycles=<n>] [--dry-run] [--lane=<n>] [--json] [--locale=es]',
|
|
117
|
+
help_review_cycle:
|
|
118
|
+
'aioson review-cycle:<status|advance|resolve|reset> [path] --feature=<slug> [--plan=<path>] [--source=qa|tester|pentester] [--json] [--locale=es]',
|
|
119
119
|
help_parallel_init:
|
|
120
120
|
'aioson parallel:init [path] [--workers=2..6] [--force] [--dry-run] [--json] [--locale=es]',
|
|
121
121
|
help_parallel_doctor:
|
|
@@ -142,6 +142,8 @@ module.exports = {
|
|
|
142
142
|
'aioson qa:scan [path] [--url=<app-url>] [--depth=3] [--max-pages=50] [--headed] [--html] [--json] [--locale=es]',
|
|
143
143
|
help_qa_report:
|
|
144
144
|
'aioson qa:report [path] [--html] [--json] [--locale=es]',
|
|
145
|
+
help_harness_check:
|
|
146
|
+
'aioson harness:check [path] --slug=<slug> [--criteria=C1,C2] [--timeout=<ms>] [--json] [--locale=es]',
|
|
145
147
|
help_harness_retro:
|
|
146
148
|
'aioson harness:retro [path] --feature=<slug> | --last=<N> [--json] [--locale=es]',
|
|
147
149
|
help_harness_preview:
|
package/src/i18n/messages/fr.js
CHANGED
|
@@ -22,16 +22,16 @@ module.exports = {
|
|
|
22
22
|
'aioson agent:prompt <agent> [path] [--tool=codex|claude|opencode] [--lang=<bcp47-tag>] [--locale=fr]',
|
|
23
23
|
help_agent_help:
|
|
24
24
|
'aioson agent:help [agent] [--json]',
|
|
25
|
-
help_agent_invoke:
|
|
26
|
-
'aioson agent:invoke <agent> [path] [--tool=codex|claude|opencode] [--mode=framework_target|app_target] [--feature=<slug>] [--scope=<area>] [--lang=<bcp47-tag>] [--locale=fr]',
|
|
27
|
-
help_agent_epilogue:
|
|
28
|
-
'aioson agent:epilogue [path] --agent=<agent> --summary=<texte> [--feature=<slug>] [--approve-gate=A|B|C|D] [--json] [--locale=fr]',
|
|
25
|
+
help_agent_invoke:
|
|
26
|
+
'aioson agent:invoke <agent> [path] [--tool=codex|claude|opencode] [--mode=framework_target|app_target] [--feature=<slug>] [--scope=<area>] [--lang=<bcp47-tag>] [--locale=fr]',
|
|
27
|
+
help_agent_epilogue:
|
|
28
|
+
'aioson agent:epilogue [path] --agent=<agent> --summary=<texte> [--feature=<slug>] [--approve-gate=A|B|C|D] [--json] [--locale=fr]',
|
|
29
29
|
help_context_validate: 'aioson context:validate [path] [--json] [--locale=fr]',
|
|
30
|
-
help_context_pack:
|
|
31
|
-
'aioson context:pack [path] [--agent=<agent>] [--goal=<texte>] [--module=<module-ou-dossier>] [--max-files=8] [--json] [--locale=fr]',
|
|
32
|
-
help_context_select:
|
|
33
|
-
'aioson context:select [path] [--agent=<agent>] [--mode=planning|executing] [--task=<texte>] [--paths=<chemin[,chemin2]>] [--feature=<slug>] [--json] [--locale=fr]',
|
|
34
|
-
help_context_load:
|
|
30
|
+
help_context_pack:
|
|
31
|
+
'aioson context:pack [path] [--agent=<agent>] [--goal=<texte>] [--module=<module-ou-dossier>] [--max-files=8] [--json] [--locale=fr]',
|
|
32
|
+
help_context_select:
|
|
33
|
+
'aioson context:select [path] [--agent=<agent>] [--mode=planning|executing] [--task=<texte>] [--paths=<chemin[,chemin2]>] [--feature=<slug>] [--json] [--locale=fr]',
|
|
34
|
+
help_context_load:
|
|
35
35
|
'aioson context:load [path] --target=<rule|brain>:<slug> --agent=<nom> [--batch="slug1,slug2"] [--feature=<slug>] [--classification=<MICRO|SMALL|MEDIUM>] [--verbose] [--json] [--locale=fr]',
|
|
36
36
|
help_chain_audit:
|
|
37
37
|
'aioson chain:audit <fichier> [path] [--limit=N] [--feature=<slug>] [--json] [--locale=fr]',
|
|
@@ -112,10 +112,10 @@ module.exports = {
|
|
|
112
112
|
'aioson test:package [source-path] [--keep] [--dry-run] [--json] [--locale=fr]',
|
|
113
113
|
help_workflow_plan:
|
|
114
114
|
'aioson workflow:plan [path] [--classification=MICRO|SMALL|MEDIUM] [--json] [--locale=fr]',
|
|
115
|
-
help_workflow_execute:
|
|
116
|
-
'aioson workflow:execute [path] [--feature=<slug>] [--agentic] [--max-dev-qa-cycles=<n>] [--max-tester-cycles=<n>] [--max-pentester-cycles=<n>] [--dry-run] [--lane=<n>] [--json] [--locale=fr]',
|
|
117
|
-
help_review_cycle:
|
|
118
|
-
'aioson review-cycle:<status|advance|resolve|reset> [path] --feature=<slug> [--plan=<path>] [--source=qa|tester|pentester] [--json] [--locale=fr]',
|
|
115
|
+
help_workflow_execute:
|
|
116
|
+
'aioson workflow:execute [path] [--feature=<slug>] [--agentic] [--max-dev-qa-cycles=<n>] [--max-tester-cycles=<n>] [--max-pentester-cycles=<n>] [--dry-run] [--lane=<n>] [--json] [--locale=fr]',
|
|
117
|
+
help_review_cycle:
|
|
118
|
+
'aioson review-cycle:<status|advance|resolve|reset> [path] --feature=<slug> [--plan=<path>] [--source=qa|tester|pentester] [--json] [--locale=fr]',
|
|
119
119
|
help_parallel_init:
|
|
120
120
|
'aioson parallel:init [path] [--workers=2..6] [--force] [--dry-run] [--json] [--locale=fr]',
|
|
121
121
|
help_parallel_doctor:
|
|
@@ -142,6 +142,8 @@ module.exports = {
|
|
|
142
142
|
'aioson qa:scan [path] [--url=<app-url>] [--depth=3] [--max-pages=50] [--headed] [--html] [--json] [--locale=fr]',
|
|
143
143
|
help_qa_report:
|
|
144
144
|
'aioson qa:report [path] [--html] [--json] [--locale=fr]',
|
|
145
|
+
help_harness_check:
|
|
146
|
+
'aioson harness:check [path] --slug=<slug> [--criteria=C1,C2] [--timeout=<ms>] [--json] [--locale=fr]',
|
|
145
147
|
help_harness_retro:
|
|
146
148
|
'aioson harness:retro [path] --feature=<slug> | --last=<N> [--json] [--locale=fr]',
|
|
147
149
|
help_harness_preview:
|
|
@@ -22,16 +22,16 @@ module.exports = {
|
|
|
22
22
|
'aioson agent:prompt <agent> [path] [--tool=codex|claude|opencode] [--lang=<bcp47-tag>] [--locale=pt-BR]',
|
|
23
23
|
help_agent_help:
|
|
24
24
|
'aioson agent:help [agent] [--json]',
|
|
25
|
-
help_agent_invoke:
|
|
26
|
-
'aioson agent:invoke <agent> [path] [--tool=codex|claude|opencode] [--mode=framework_target|app_target] [--feature=<slug>] [--scope=<area>] [--lang=<bcp47-tag>] [--locale=pt-BR]',
|
|
27
|
-
help_agent_epilogue:
|
|
28
|
-
'aioson agent:epilogue [path] --agent=<agente> --summary=<texto> [--feature=<slug>] [--approve-gate=A|B|C|D] [--json] [--locale=pt-BR]',
|
|
25
|
+
help_agent_invoke:
|
|
26
|
+
'aioson agent:invoke <agent> [path] [--tool=codex|claude|opencode] [--mode=framework_target|app_target] [--feature=<slug>] [--scope=<area>] [--lang=<bcp47-tag>] [--locale=pt-BR]',
|
|
27
|
+
help_agent_epilogue:
|
|
28
|
+
'aioson agent:epilogue [path] --agent=<agente> --summary=<texto> [--feature=<slug>] [--approve-gate=A|B|C|D] [--json] [--locale=pt-BR]',
|
|
29
29
|
help_context_validate: 'aioson context:validate [path] [--json] [--locale=pt-BR]',
|
|
30
|
-
help_context_pack:
|
|
31
|
-
'aioson context:pack [path] [--agent=<agente>] [--goal=<texto>] [--module=<modulo-ou-pasta>] [--max-files=8] [--json] [--locale=pt-BR]',
|
|
32
|
-
help_context_select:
|
|
33
|
-
'aioson context:select [path] [--agent=<agente>] [--mode=planning|executing] [--task=<texto>] [--paths=<caminho[,caminho2]>] [--feature=<slug>] [--json] [--locale=pt-BR]',
|
|
34
|
-
help_context_load:
|
|
30
|
+
help_context_pack:
|
|
31
|
+
'aioson context:pack [path] [--agent=<agente>] [--goal=<texto>] [--module=<modulo-ou-pasta>] [--max-files=8] [--json] [--locale=pt-BR]',
|
|
32
|
+
help_context_select:
|
|
33
|
+
'aioson context:select [path] [--agent=<agente>] [--mode=planning|executing] [--task=<texto>] [--paths=<caminho[,caminho2]>] [--feature=<slug>] [--json] [--locale=pt-BR]',
|
|
34
|
+
help_context_load:
|
|
35
35
|
'aioson context:load [path] --target=<rule|brain>:<slug> --agent=<nome> [--batch="slug1,slug2"] [--feature=<slug>] [--classification=<MICRO|SMALL|MEDIUM>] [--verbose] [--json] [--locale=pt-BR]',
|
|
36
36
|
help_chain_audit:
|
|
37
37
|
'aioson chain:audit <arquivo> [path] [--limit=N] [--feature=<slug>] [--json] [--locale=pt-BR]',
|
|
@@ -124,10 +124,10 @@ module.exports = {
|
|
|
124
124
|
'aioson workflow:next [path] [--complete[=<agente>]] [--agent=<agente>] [--skip=<agente>] [--status] [--suggest] [--tool=codex|claude|opencode] [--json] [--locale=pt-BR]',
|
|
125
125
|
help_workflow_status:
|
|
126
126
|
'aioson workflow:status [path] [--suggest] [--tool=codex|claude|opencode] [--json] [--locale=pt-BR]',
|
|
127
|
-
help_workflow_execute:
|
|
128
|
-
'aioson workflow:execute [path] [--feature=<slug>] [--agentic] [--max-dev-qa-cycles=<n>] [--max-tester-cycles=<n>] [--max-pentester-cycles=<n>] [--dry-run] [--lane=<n>] [--json] [--locale=pt-BR]',
|
|
129
|
-
help_review_cycle:
|
|
130
|
-
'aioson review-cycle:<status|advance|resolve|reset> [path] --feature=<slug> [--plan=<path>] [--source=qa|tester|pentester] [--json] [--locale=pt-BR]',
|
|
127
|
+
help_workflow_execute:
|
|
128
|
+
'aioson workflow:execute [path] [--feature=<slug>] [--agentic] [--max-dev-qa-cycles=<n>] [--max-tester-cycles=<n>] [--max-pentester-cycles=<n>] [--dry-run] [--lane=<n>] [--json] [--locale=pt-BR]',
|
|
129
|
+
help_review_cycle:
|
|
130
|
+
'aioson review-cycle:<status|advance|resolve|reset> [path] --feature=<slug> [--plan=<path>] [--source=qa|tester|pentester] [--json] [--locale=pt-BR]',
|
|
131
131
|
help_parallel_init:
|
|
132
132
|
'aioson parallel:init [path] [--workers=2..6] [--force] [--dry-run] [--json] [--locale=pt-BR]',
|
|
133
133
|
help_parallel_doctor:
|
|
@@ -157,7 +157,9 @@ module.exports = {
|
|
|
157
157
|
help_harness_init:
|
|
158
158
|
'aioson harness:init [path] --slug=<slug> [--mode=BALANCED|URGENT|ECONOMICAL] [--locale=pt-BR]',
|
|
159
159
|
help_harness_validate:
|
|
160
|
-
'aioson harness:validate [path] --slug=<slug> [--artifact=<path>] [--locale=pt-BR]',
|
|
160
|
+
'aioson harness:validate [path] --slug=<slug> [--base=<ref>] [--no-diff] [--max-diff-bytes=<n>] [--artifact=<path>] [--locale=pt-BR]',
|
|
161
|
+
help_harness_check:
|
|
162
|
+
'aioson harness:check [path] --slug=<slug> [--criteria=C1,C2] [--timeout=<ms>] [--json] [--locale=pt-BR]',
|
|
161
163
|
help_harness_retro:
|
|
162
164
|
'aioson harness:retro [path] --feature=<slug> | --last=<N> [--json] [--locale=pt-BR]',
|
|
163
165
|
help_harness_preview:
|
|
@@ -1106,7 +1108,11 @@ module.exports = {
|
|
|
1106
1108
|
contract_not_found: 'Contrato nao encontrado para o slug: {slug}',
|
|
1107
1109
|
validating: 'Validando harness para {slug}...',
|
|
1108
1110
|
blocked: 'Execucao pausada: {reason}',
|
|
1109
|
-
init_dry_run: '[dry-run] Inicializaria harness para {slug}'
|
|
1111
|
+
init_dry_run: '[dry-run] Inicializaria harness para {slug}',
|
|
1112
|
+
check_header: 'Harness check — {slug}',
|
|
1113
|
+
check_no_executable: ' Nenhum criterio com comando de verification ({total} criterios no total). @validator julga todos.',
|
|
1114
|
+
check_summary: ' Checks: {passed}/{executable} passaram ({skipped} sem verification — julgados pelo @validator)',
|
|
1115
|
+
check_unknown_criteria: 'Ids de criterios desconhecidos: {ids}'
|
|
1110
1116
|
},
|
|
1111
1117
|
web_map: {
|
|
1112
1118
|
url_missing: 'Opcao obrigatoria ausente: --url=<url>.',
|
package/src/parser.js
CHANGED
|
@@ -29,13 +29,15 @@ function parseArgv(argv) {
|
|
|
29
29
|
'all', 'force', 'dry-run', 'no-interactive', 'fix', 'json',
|
|
30
30
|
'help', 'version', 'no-launch', 'attach', 'tmux',
|
|
31
31
|
'allow-warnings', 'install-hook', 'uninstall-hook', 'remove-hook',
|
|
32
|
-
'agent-safe', 'agentic',
|
|
32
|
+
'agent-safe', 'agentic',
|
|
33
33
|
'selective',
|
|
34
34
|
'status', 'suggest', 'apply',
|
|
35
35
|
'runtime-only', 'template-only', 'inception', 'locales',
|
|
36
36
|
// feature:export structure/output toggles — pure booleans; without these
|
|
37
37
|
// a following positional (e.g. `--flatten .`) would be swallowed as the value.
|
|
38
38
|
'flatten', 'no-index',
|
|
39
|
+
// harness:validate — pure boolean; `--no-diff .` must not swallow the path.
|
|
40
|
+
'no-diff',
|
|
39
41
|
// `--resume` alone means "resume last"; `--resume=<id>` carries a value
|
|
40
42
|
// and is handled by the `=` branch above. Without this entry, `--resume`
|
|
41
43
|
// followed by `--tool=claude` would swallow the next token as its value.
|