@codexa/cli 8.6.15 → 9.0.2
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/commands/knowledge.ts +51 -0
- package/commands/patterns.ts +410 -28
- package/commands/task.ts +64 -13
- package/commands/utils.ts +244 -0
- package/gates/typecheck-validator.ts +174 -0
- package/gates/validator.ts +88 -0
- package/package.json +1 -1
- package/protocol/subagent-protocol.ts +31 -4
- package/workflow.ts +62 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codexa/cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "9.0.2",
|
|
4
4
|
"description": "Orchestrated workflow system for Claude Code - manages feature development through parallel subagents with structured phases, gates, and quality enforcement.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -18,12 +18,12 @@ export interface Knowledge {
|
|
|
18
18
|
severity: "info" | "warning" | "critical";
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
//
|
|
21
|
+
// v9.0: Raciocinio do subagent (approach OBRIGATORIO para status "completed")
|
|
22
22
|
export interface Reasoning {
|
|
23
|
-
approach: string; // Como abordou o problema
|
|
23
|
+
approach: string; // OBRIGATORIO: Como abordou o problema (min 20 chars)
|
|
24
24
|
challenges?: string[]; // Desafios encontrados
|
|
25
25
|
alternatives?: string[]; // Alternativas consideradas
|
|
26
|
-
recommendations?: string; //
|
|
26
|
+
recommendations?: string; // Recomendacoes para proximas tasks
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
export interface SubagentReturn {
|
|
@@ -222,6 +222,8 @@ export function parseSubagentReturn(input: string): ParseResult {
|
|
|
222
222
|
errors: [
|
|
223
223
|
`JSON invalido: ${(e as Error).message}`,
|
|
224
224
|
"Verifique se o JSON esta bem formatado.",
|
|
225
|
+
"Dica: Caracteres como ! $ ` em double-quotes causam problemas no shell.",
|
|
226
|
+
"Use aspas simples ou --output-file /tmp/result.json para evitar escaping.",
|
|
225
227
|
],
|
|
226
228
|
rawInput: input,
|
|
227
229
|
};
|
|
@@ -238,6 +240,10 @@ export function parseSubagentReturn(input: string): ParseResult {
|
|
|
238
240
|
const summaryError = validateString(parsed.summary, "summary", 10, 500);
|
|
239
241
|
if (summaryError) errors.push(summaryError);
|
|
240
242
|
|
|
243
|
+
// files_created / files_modified: default para [] se ausentes
|
|
244
|
+
if (parsed.files_created === undefined) parsed.files_created = [];
|
|
245
|
+
if (parsed.files_modified === undefined) parsed.files_modified = [];
|
|
246
|
+
|
|
241
247
|
// files_created
|
|
242
248
|
const filesCreatedError = validateStringArray(parsed.files_created, "files_created");
|
|
243
249
|
if (filesCreatedError) errors.push(filesCreatedError);
|
|
@@ -282,7 +288,7 @@ export function parseSubagentReturn(input: string): ParseResult {
|
|
|
282
288
|
}
|
|
283
289
|
}
|
|
284
290
|
|
|
285
|
-
//
|
|
291
|
+
// v9.0: reasoning (validar estrutura se presente)
|
|
286
292
|
if (parsed.reasoning !== undefined) {
|
|
287
293
|
if (typeof parsed.reasoning !== "object" || parsed.reasoning === null) {
|
|
288
294
|
errors.push("Campo 'reasoning' deve ser um objeto");
|
|
@@ -305,6 +311,24 @@ export function parseSubagentReturn(input: string): ParseResult {
|
|
|
305
311
|
}
|
|
306
312
|
}
|
|
307
313
|
|
|
314
|
+
// v9.0: Validacao de reasoning obrigatorio para status "completed" (Gate 4.4)
|
|
315
|
+
if (parsed.status === "completed") {
|
|
316
|
+
if (!parsed.reasoning || typeof parsed.reasoning !== "object") {
|
|
317
|
+
errors.push(
|
|
318
|
+
"Status 'completed' requer campo 'reasoning' com pelo menos 'approach'. " +
|
|
319
|
+
"Isso preserva contexto entre tasks. Exemplo: {\"reasoning\": {\"approach\": \"Descreva como abordou o problema\"}}"
|
|
320
|
+
);
|
|
321
|
+
} else {
|
|
322
|
+
const r = parsed.reasoning as Record<string, unknown>;
|
|
323
|
+
if (!r.approach || typeof r.approach !== "string" || (r.approach as string).length < 20) {
|
|
324
|
+
errors.push(
|
|
325
|
+
"Campo 'reasoning.approach' obrigatorio com minimo 20 caracteres para status 'completed'. " +
|
|
326
|
+
"Descreva COMO voce abordou o problema, nao apenas O QUE fez."
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
308
332
|
// v8.5: utilities_created (opcional, validar estrutura se presente)
|
|
309
333
|
if (parsed.utilities_created !== undefined) {
|
|
310
334
|
if (!Array.isArray(parsed.utilities_created)) {
|
|
@@ -392,6 +416,9 @@ export function formatValidationErrors(result: ParseResult): string {
|
|
|
392
416
|
"summary": "Resumo do que foi feito (10-500 chars)",
|
|
393
417
|
"files_created": ["path/to/file.ts"],
|
|
394
418
|
"files_modified": ["path/to/other.ts"],
|
|
419
|
+
"reasoning": {
|
|
420
|
+
"approach": "OBRIGATORIO (min 20 chars): Como abordou o problema e POR QUE tomou essas decisoes"
|
|
421
|
+
},
|
|
395
422
|
"patterns_discovered": ["Pattern identificado"],
|
|
396
423
|
"decisions_made": [{"title": "...", "decision": "..."}],
|
|
397
424
|
"blockers": ["Bloqueio se status != completed"],
|
package/workflow.ts
CHANGED
|
@@ -6,8 +6,8 @@ import { checkRequest, checkApprove, checkReject } from "./commands/check";
|
|
|
6
6
|
import { taskNext, taskStart, taskDone } from "./commands/task";
|
|
7
7
|
import { decide, listDecisions } from "./commands/decide";
|
|
8
8
|
import { reviewStart, reviewApprove, reviewSkip } from "./commands/review";
|
|
9
|
-
import { addKnowledge, listKnowledge, acknowledgeKnowledge, queryGraph } from "./commands/knowledge";
|
|
10
|
-
import { status, contextExport, recover, contextUpdate } from "./commands/utils";
|
|
9
|
+
import { addKnowledge, listKnowledge, acknowledgeKnowledge, queryGraph, resolveKnowledge } from "./commands/knowledge";
|
|
10
|
+
import { status, contextExport, recover, contextUpdate, contextDetail } from "./commands/utils";
|
|
11
11
|
import {
|
|
12
12
|
discoverStart,
|
|
13
13
|
discoverConfirm,
|
|
@@ -190,8 +190,9 @@ taskCmd
|
|
|
190
190
|
.command("start <ids>")
|
|
191
191
|
.description("Inicia task(s) - pode ser multiplas separadas por virgula")
|
|
192
192
|
.option("--json", "Saida em JSON")
|
|
193
|
+
.option("--full-context", "Incluir contexto completo (modo legado)")
|
|
193
194
|
.action((ids: string, options) => {
|
|
194
|
-
taskStart(ids, options.json);
|
|
195
|
+
taskStart(ids, options.json, options.fullContext);
|
|
195
196
|
});
|
|
196
197
|
|
|
197
198
|
taskCmd
|
|
@@ -199,10 +200,33 @@ taskCmd
|
|
|
199
200
|
.description("Completa uma task")
|
|
200
201
|
.option("--checkpoint <text>", "Resumo do que foi feito (extraido automaticamente de --output)")
|
|
201
202
|
.option("--output <json>", "Retorno JSON do subagent (processa automaticamente)")
|
|
203
|
+
.option("--output-file <path>", "Ler retorno JSON de arquivo (evita problemas de shell escaping)")
|
|
202
204
|
.option("--files <files>", "Arquivos criados/modificados (extraido automaticamente de --output)")
|
|
203
205
|
.option("--force", "Ignorar validacao de standards (sera registrado)")
|
|
204
206
|
.option("--force-reason <reason>", "Motivo do bypass de validacao")
|
|
205
207
|
.action((id: string, options) => {
|
|
208
|
+
// Resolver --output-file: ler conteudo do arquivo
|
|
209
|
+
if (options.outputFile && !options.output) {
|
|
210
|
+
try {
|
|
211
|
+
options.output = readFileSync(options.outputFile, "utf-8");
|
|
212
|
+
} catch (e) {
|
|
213
|
+
console.error(`\n[ERRO] Nao foi possivel ler arquivo: ${options.outputFile}`);
|
|
214
|
+
console.error(` ${(e as Error).message}\n`);
|
|
215
|
+
process.exit(1);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Resolver stdin: --output - (le de stdin)
|
|
220
|
+
if (options.output === "-") {
|
|
221
|
+
try {
|
|
222
|
+
options.output = readFileSync("/dev/stdin", "utf-8");
|
|
223
|
+
} catch (e) {
|
|
224
|
+
console.error("\n[ERRO] Nao foi possivel ler de stdin.");
|
|
225
|
+
console.error(` ${(e as Error).message}\n`);
|
|
226
|
+
process.exit(1);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
206
230
|
// Checkpoint obrigatorio se nao houver --output
|
|
207
231
|
if (!options.output && !options.checkpoint) {
|
|
208
232
|
console.error("\n[ERRO] Checkpoint obrigatorio.");
|
|
@@ -280,6 +304,14 @@ knowledgeCmd
|
|
|
280
304
|
acknowledgeKnowledge(id);
|
|
281
305
|
});
|
|
282
306
|
|
|
307
|
+
knowledgeCmd
|
|
308
|
+
.command("resolve <ids>")
|
|
309
|
+
.description("Resolve/reconhece knowledge item(s) critico(s)")
|
|
310
|
+
.option("--resolution <text>", "Descricao de como o blocker foi resolvido")
|
|
311
|
+
.action((ids: string, opts: { resolution?: string }) => {
|
|
312
|
+
resolveKnowledge(ids, opts.resolution);
|
|
313
|
+
});
|
|
314
|
+
|
|
283
315
|
knowledgeCmd
|
|
284
316
|
.command("graph")
|
|
285
317
|
.description("Consulta o knowledge graph (relacoes entre arquivos, decisoes, patterns)")
|
|
@@ -351,6 +383,14 @@ contextCmd
|
|
|
351
383
|
contextUpdate(options);
|
|
352
384
|
});
|
|
353
385
|
|
|
386
|
+
contextCmd
|
|
387
|
+
.command("detail <section>")
|
|
388
|
+
.description("Mostra secao especifica do contexto (standards, decisions, patterns, knowledge, architecture)")
|
|
389
|
+
.option("--json", "Output JSON")
|
|
390
|
+
.action((section: string, opts: { json?: boolean }) => {
|
|
391
|
+
contextDetail(section, opts.json);
|
|
392
|
+
});
|
|
393
|
+
|
|
354
394
|
// Manter compatibilidade: context sem subcomando = export
|
|
355
395
|
program
|
|
356
396
|
.command("ctx")
|
|
@@ -541,6 +581,25 @@ discoverCmd
|
|
|
541
581
|
patternsAnalyze(path, options.json);
|
|
542
582
|
});
|
|
543
583
|
|
|
584
|
+
// v9.0: Analise profunda com metadata enriquecida + grepai
|
|
585
|
+
discoverCmd
|
|
586
|
+
.command("analyze-deep <files...>")
|
|
587
|
+
.description("Analise profunda de arquivos (hooks, patterns, directives)")
|
|
588
|
+
.option("--json", "Saida em JSON")
|
|
589
|
+
.action((files, options) => {
|
|
590
|
+
const { patternsAnalyzeDeep } = require("./commands/patterns");
|
|
591
|
+
patternsAnalyzeDeep(files, options.json);
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
// v9.0: Anti-patterns de gate bypasses
|
|
595
|
+
discoverCmd
|
|
596
|
+
.command("extract-anti-patterns")
|
|
597
|
+
.description("Extrai anti-patterns do historico de gate bypasses")
|
|
598
|
+
.action(() => {
|
|
599
|
+
const { extractAntiPatternsFromHistory } = require("./commands/patterns");
|
|
600
|
+
extractAntiPatternsFromHistory();
|
|
601
|
+
});
|
|
602
|
+
|
|
544
603
|
discoverCmd
|
|
545
604
|
.command("export-patterns")
|
|
546
605
|
.description("Regenera arquivo patterns.md")
|