@codexa/cli 9.0.2 → 9.0.4
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/architect.test.ts +531 -0
- package/commands/architect.ts +75 -17
- package/commands/check.ts +7 -17
- package/commands/clear.ts +40 -1
- package/commands/decide.ts +37 -49
- package/commands/discover.ts +136 -28
- package/commands/knowledge.test.ts +160 -0
- package/commands/knowledge.ts +192 -102
- package/commands/patterns.test.ts +169 -0
- package/commands/patterns.ts +6 -13
- package/commands/plan.test.ts +73 -0
- package/commands/plan.ts +18 -66
- package/commands/product.ts +8 -17
- package/commands/research.ts +4 -3
- package/commands/review.ts +190 -28
- package/commands/spec-resolver.test.ts +119 -0
- package/commands/spec-resolver.ts +90 -0
- package/commands/standards.ts +7 -15
- package/commands/sync.ts +89 -0
- package/commands/task.ts +72 -167
- package/commands/utils.test.ts +100 -0
- package/commands/utils.ts +78 -706
- package/db/schema.test.ts +760 -0
- package/db/schema.ts +284 -130
- package/gates/validator.test.ts +675 -0
- package/gates/validator.ts +112 -27
- package/package.json +3 -1
- package/protocol/process-return.ts +25 -93
- package/protocol/subagent-protocol.test.ts +936 -0
- package/protocol/subagent-protocol.ts +19 -1
- package/workflow.ts +176 -67
|
@@ -27,6 +27,8 @@ export interface Reasoning {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
export interface SubagentReturn {
|
|
30
|
+
// v9.1: Versao do protocolo (opcional por compatibilidade)
|
|
31
|
+
protocol_version?: string;
|
|
30
32
|
status: "completed" | "blocked" | "needs_decision";
|
|
31
33
|
summary: string;
|
|
32
34
|
files_created: string[];
|
|
@@ -58,11 +60,14 @@ const VALID_STATUSES = ["completed", "blocked", "needs_decision"];
|
|
|
58
60
|
const VALID_KNOWLEDGE_CATEGORIES = ["discovery", "decision", "blocker", "pattern", "constraint"];
|
|
59
61
|
const VALID_SEVERITIES = ["info", "warning", "critical"];
|
|
60
62
|
|
|
63
|
+
// v9.1: Versao atual do protocolo de subagentes
|
|
64
|
+
export const CURRENT_PROTOCOL_VERSION = "9.1";
|
|
65
|
+
|
|
61
66
|
/**
|
|
62
67
|
* Extrai JSON de uma string que pode conter texto misto
|
|
63
68
|
* Subagents podem retornar texto com JSON embutido
|
|
64
69
|
*/
|
|
65
|
-
function extractJsonFromText(text: string): string | null {
|
|
70
|
+
export function extractJsonFromText(text: string): string | null {
|
|
66
71
|
// Tenta encontrar JSON em bloco de codigo
|
|
67
72
|
const codeBlockMatch = text.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
68
73
|
if (codeBlockMatch) {
|
|
@@ -350,6 +355,17 @@ export function parseSubagentReturn(input: string): ParseResult {
|
|
|
350
355
|
}
|
|
351
356
|
}
|
|
352
357
|
|
|
358
|
+
// v9.1: protocol_version (opcional, warn on mismatch)
|
|
359
|
+
if (parsed.protocol_version !== undefined) {
|
|
360
|
+
if (typeof parsed.protocol_version !== "string") {
|
|
361
|
+
errors.push("Campo 'protocol_version' deve ser string");
|
|
362
|
+
} else if (parsed.protocol_version !== CURRENT_PROTOCOL_VERSION) {
|
|
363
|
+
console.warn(
|
|
364
|
+
`[protocol] Versao do protocolo: esperado ${CURRENT_PROTOCOL_VERSION}, recebido ${parsed.protocol_version}`
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
353
369
|
// 5. Validacoes semanticas
|
|
354
370
|
|
|
355
371
|
// Se blocked, deve ter blockers
|
|
@@ -376,6 +392,7 @@ export function parseSubagentReturn(input: string): ParseResult {
|
|
|
376
392
|
|
|
377
393
|
// Cast para tipo correto
|
|
378
394
|
const data: SubagentReturn = {
|
|
395
|
+
protocol_version: parsed.protocol_version as string | undefined,
|
|
379
396
|
status: parsed.status as SubagentReturn["status"],
|
|
380
397
|
summary: parsed.summary as string,
|
|
381
398
|
files_created: parsed.files_created as string[],
|
|
@@ -412,6 +429,7 @@ export function formatValidationErrors(result: ParseResult): string {
|
|
|
412
429
|
output += "\n" + "─".repeat(50) + "\n";
|
|
413
430
|
output += "O retorno deve seguir o formato:\n\n";
|
|
414
431
|
output += `{
|
|
432
|
+
"protocol_version": "9.1",
|
|
415
433
|
"status": "completed | blocked | needs_decision",
|
|
416
434
|
"summary": "Resumo do que foi feito (10-500 chars)",
|
|
417
435
|
"files_created": ["path/to/file.ts"],
|
package/workflow.ts
CHANGED
|
@@ -6,7 +6,7 @@ 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, resolveKnowledge } from "./commands/knowledge";
|
|
9
|
+
import { addKnowledge, listKnowledge, acknowledgeKnowledge, queryGraph, resolveKnowledge, compactKnowledge } from "./commands/knowledge";
|
|
10
10
|
import { status, contextExport, recover, contextUpdate, contextDetail } from "./commands/utils";
|
|
11
11
|
import {
|
|
12
12
|
discoverStart,
|
|
@@ -22,12 +22,14 @@ import {
|
|
|
22
22
|
discoverPatternRemove,
|
|
23
23
|
discoverRefreshPatterns,
|
|
24
24
|
discoverExportPatterns,
|
|
25
|
+
discoverIncremental,
|
|
25
26
|
} from "./commands/discover";
|
|
26
27
|
import { clearTasks, clearShow } from "./commands/clear";
|
|
27
28
|
import { standardsList, standardsAdd, standardsEdit, standardsRemove, standardsExport } from "./commands/standards";
|
|
28
29
|
import { productGuide, productImport, productSet, productGoalAdd, productFeatureAdd, productConfirm, productShow, productReset } from "./commands/product";
|
|
29
30
|
import { researchStart, researchShow, researchFill, researchMapAgent, researchReset } from "./commands/research";
|
|
30
31
|
import { patternsExtract, patternsAnalyze } from "./commands/patterns";
|
|
32
|
+
import { syncAgents } from "./commands/sync";
|
|
31
33
|
import {
|
|
32
34
|
architectStart,
|
|
33
35
|
architectShow,
|
|
@@ -38,11 +40,12 @@ import {
|
|
|
38
40
|
architectCancel,
|
|
39
41
|
} from "./commands/architect";
|
|
40
42
|
import { initSchema } from "./db/schema";
|
|
41
|
-
import { getDb } from "./db/connection";
|
|
43
|
+
import { getDb, closeDb } from "./db/connection";
|
|
42
44
|
import { execSync } from "child_process";
|
|
43
45
|
import { existsSync, readFileSync } from "fs";
|
|
44
46
|
import { join } from "path";
|
|
45
47
|
import pkg from "./package.json";
|
|
48
|
+
import { CodexaError, ValidationError, GateError } from "./errors";
|
|
46
49
|
|
|
47
50
|
function checkVersionSync(): void {
|
|
48
51
|
// 1. Check CLI vs Plugin (dev repo only)
|
|
@@ -52,10 +55,11 @@ function checkVersionSync(): void {
|
|
|
52
55
|
if (existsSync(pluginJson)) {
|
|
53
56
|
const plugin = JSON.parse(readFileSync(pluginJson, "utf-8"));
|
|
54
57
|
if (plugin.version && plugin.version !== pkg.version) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
throw new CodexaError(
|
|
59
|
+
`✘ Versao incompativel: CLI=${pkg.version} Plugin=${plugin.version}\n` +
|
|
60
|
+
` O CLI e o plugin DEVEM ter a mesma versao.\n` +
|
|
61
|
+
` Atualize o CLI: bun add -g @codexa/cli@${plugin.version}`
|
|
62
|
+
);
|
|
59
63
|
}
|
|
60
64
|
}
|
|
61
65
|
} catch {
|
|
@@ -83,25 +87,73 @@ function checkVersionSync(): void {
|
|
|
83
87
|
}
|
|
84
88
|
|
|
85
89
|
if (project.cli_version !== pkg.version) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
throw new CodexaError(
|
|
91
|
+
`✘ Versao incompativel: CLI=${pkg.version} Projeto=${project.cli_version}\n` +
|
|
92
|
+
` O projeto foi configurado com CLI v${project.cli_version} mas voce esta usando v${pkg.version}.\n` +
|
|
93
|
+
` Opcoes:\n` +
|
|
94
|
+
` 1. Atualize o CLI: bun add -g @codexa/cli@${project.cli_version}\n` +
|
|
95
|
+
` 2. Reconfigure o projeto: codexa discover reset && codexa discover start`
|
|
96
|
+
);
|
|
92
97
|
}
|
|
93
98
|
} catch {
|
|
94
99
|
// DB not available or column doesn't exist yet — skip
|
|
95
100
|
}
|
|
96
101
|
}
|
|
97
102
|
|
|
103
|
+
function handleError(e: unknown): never {
|
|
104
|
+
if (e instanceof CodexaError) {
|
|
105
|
+
console.error(`\n${e.message}\n`);
|
|
106
|
+
|
|
107
|
+
// v9.3: Exibir diagnostico e passos de recuperacao para falhas de gate
|
|
108
|
+
if (e instanceof GateError && e.recovery) {
|
|
109
|
+
console.error("\u2500".repeat(50));
|
|
110
|
+
console.error("DIAGNOSTICO:");
|
|
111
|
+
console.error(` ${e.recovery.diagnostic}\n`);
|
|
112
|
+
console.error("PASSOS PARA CORRIGIR:");
|
|
113
|
+
for (const step of e.recovery.steps) {
|
|
114
|
+
console.error(` \u2192 ${step}`);
|
|
115
|
+
}
|
|
116
|
+
if (e.recovery.command) {
|
|
117
|
+
console.error(`\nPara mais detalhes: ${e.recovery.command}`);
|
|
118
|
+
}
|
|
119
|
+
console.error();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
closeDb();
|
|
123
|
+
process.exit(e.exitCode);
|
|
124
|
+
}
|
|
125
|
+
console.error(`\n[ERRO INESPERADO] ${(e as Error).message}\n`);
|
|
126
|
+
closeDb();
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function wrapAction<T extends (...args: any[]) => any>(fn: T): T {
|
|
131
|
+
return ((...args: any[]) => {
|
|
132
|
+
try {
|
|
133
|
+
const result = fn(...args);
|
|
134
|
+
if (result instanceof Promise) {
|
|
135
|
+
return result.catch((e) => {
|
|
136
|
+
closeDb();
|
|
137
|
+
handleError(e);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
return result;
|
|
141
|
+
} catch (e) {
|
|
142
|
+
closeDb();
|
|
143
|
+
handleError(e);
|
|
144
|
+
}
|
|
145
|
+
}) as T;
|
|
146
|
+
}
|
|
147
|
+
|
|
98
148
|
const program = new Command();
|
|
99
149
|
|
|
100
150
|
program
|
|
101
151
|
.name("codexa")
|
|
102
152
|
.description(`Codexa Workflow v${pkg.version} - Sistema de workflow para Claude Code`)
|
|
103
153
|
.version(pkg.version)
|
|
104
|
-
.hook("preAction", () =>
|
|
154
|
+
.hook("preAction", () => {
|
|
155
|
+
checkVersionSync();
|
|
156
|
+
});
|
|
105
157
|
|
|
106
158
|
// ═══════════════════════════════════════════════════════════════
|
|
107
159
|
// FASE: PLAN
|
|
@@ -122,8 +174,9 @@ planCmd
|
|
|
122
174
|
.command("show")
|
|
123
175
|
.description("Mostra o plano atual")
|
|
124
176
|
.option("--json", "Saida em JSON")
|
|
177
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
125
178
|
.action((options) => {
|
|
126
|
-
planShow(options.json);
|
|
179
|
+
planShow(options.json, options.spec);
|
|
127
180
|
});
|
|
128
181
|
|
|
129
182
|
planCmd
|
|
@@ -134,15 +187,17 @@ planCmd
|
|
|
134
187
|
.option("--depends <ids>", "IDs das tasks que esta depende (ex: 1,2)")
|
|
135
188
|
.option("--files <files>", "Arquivos esperados (ex: src/a.ts,src/b.ts)")
|
|
136
189
|
.option("--sequential", "Marca como sequencial (nao paralelizavel)")
|
|
190
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
137
191
|
.action((options) => {
|
|
138
|
-
planTaskAdd(options);
|
|
192
|
+
planTaskAdd({ ...options, specId: options.spec });
|
|
139
193
|
});
|
|
140
194
|
|
|
141
195
|
planCmd
|
|
142
196
|
.command("cancel")
|
|
143
197
|
.description("Cancela a feature atual (soft-cancel, preserva historico)")
|
|
144
|
-
.
|
|
145
|
-
|
|
198
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
199
|
+
.action((options) => {
|
|
200
|
+
planCancel(options.spec);
|
|
146
201
|
});
|
|
147
202
|
|
|
148
203
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -154,22 +209,25 @@ const checkCmd = program.command("check").description("Comandos da fase CHECK");
|
|
|
154
209
|
checkCmd
|
|
155
210
|
.command("request")
|
|
156
211
|
.description("Solicita aprovacao do plano")
|
|
157
|
-
.
|
|
158
|
-
|
|
212
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
213
|
+
.action((options) => {
|
|
214
|
+
checkRequest(options.spec);
|
|
159
215
|
});
|
|
160
216
|
|
|
161
217
|
checkCmd
|
|
162
218
|
.command("approve")
|
|
163
219
|
.description("Aprova o plano")
|
|
164
|
-
.
|
|
165
|
-
|
|
220
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
221
|
+
.action((options) => {
|
|
222
|
+
checkApprove(options.spec);
|
|
166
223
|
});
|
|
167
224
|
|
|
168
225
|
checkCmd
|
|
169
226
|
.command("reject <reason>")
|
|
170
227
|
.description("Rejeita o plano com motivo")
|
|
171
|
-
.
|
|
172
|
-
|
|
228
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
229
|
+
.action((reason: string, options) => {
|
|
230
|
+
checkReject(reason, options.spec);
|
|
173
231
|
});
|
|
174
232
|
|
|
175
233
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -182,18 +240,20 @@ taskCmd
|
|
|
182
240
|
.command("next")
|
|
183
241
|
.description("Mostra proximas tasks disponiveis")
|
|
184
242
|
.option("--json", "Saida em JSON")
|
|
185
|
-
.
|
|
186
|
-
|
|
187
|
-
|
|
243
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
244
|
+
.action(wrapAction((options) => {
|
|
245
|
+
taskNext(options.json, options.spec);
|
|
246
|
+
}));
|
|
188
247
|
|
|
189
248
|
taskCmd
|
|
190
249
|
.command("start <ids>")
|
|
191
250
|
.description("Inicia task(s) - pode ser multiplas separadas por virgula")
|
|
192
251
|
.option("--json", "Saida em JSON")
|
|
193
252
|
.option("--full-context", "Incluir contexto completo (modo legado)")
|
|
194
|
-
.
|
|
195
|
-
|
|
196
|
-
|
|
253
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
254
|
+
.action(wrapAction((ids: string, options) => {
|
|
255
|
+
taskStart(ids, options.json, options.fullContext, options.spec);
|
|
256
|
+
}));
|
|
197
257
|
|
|
198
258
|
taskCmd
|
|
199
259
|
.command("done <id>")
|
|
@@ -204,15 +264,15 @@ taskCmd
|
|
|
204
264
|
.option("--files <files>", "Arquivos criados/modificados (extraido automaticamente de --output)")
|
|
205
265
|
.option("--force", "Ignorar validacao de standards (sera registrado)")
|
|
206
266
|
.option("--force-reason <reason>", "Motivo do bypass de validacao")
|
|
207
|
-
.action((id: string, options) => {
|
|
267
|
+
.action(wrapAction((id: string, options) => {
|
|
208
268
|
// Resolver --output-file: ler conteudo do arquivo
|
|
209
269
|
if (options.outputFile && !options.output) {
|
|
210
270
|
try {
|
|
211
271
|
options.output = readFileSync(options.outputFile, "utf-8");
|
|
212
272
|
} catch (e) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
273
|
+
throw new ValidationError(
|
|
274
|
+
`[ERRO] Nao foi possivel ler arquivo: ${options.outputFile}\n ${(e as Error).message}`
|
|
275
|
+
);
|
|
216
276
|
}
|
|
217
277
|
}
|
|
218
278
|
|
|
@@ -221,17 +281,17 @@ taskCmd
|
|
|
221
281
|
try {
|
|
222
282
|
options.output = readFileSync("/dev/stdin", "utf-8");
|
|
223
283
|
} catch (e) {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
284
|
+
throw new ValidationError(
|
|
285
|
+
`[ERRO] Nao foi possivel ler de stdin.\n ${(e as Error).message}`
|
|
286
|
+
);
|
|
227
287
|
}
|
|
228
288
|
}
|
|
229
289
|
|
|
230
290
|
// Checkpoint obrigatorio se nao houver --output
|
|
231
291
|
if (!options.output && !options.checkpoint) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
292
|
+
throw new ValidationError(
|
|
293
|
+
"[ERRO] Checkpoint obrigatorio.\nUse: --checkpoint 'resumo' ou --output '{json do subagent}'"
|
|
294
|
+
);
|
|
235
295
|
}
|
|
236
296
|
|
|
237
297
|
taskDone(id, {
|
|
@@ -241,7 +301,7 @@ taskCmd
|
|
|
241
301
|
forceReason: options.forceReason,
|
|
242
302
|
output: options.output,
|
|
243
303
|
});
|
|
244
|
-
});
|
|
304
|
+
}));
|
|
245
305
|
|
|
246
306
|
// ═══════════════════════════════════════════════════════════════
|
|
247
307
|
// DECISOES
|
|
@@ -252,16 +312,18 @@ program
|
|
|
252
312
|
.description("Registra uma decisao")
|
|
253
313
|
.option("--rationale <text>", "Justificativa da decisao")
|
|
254
314
|
.option("--force", "Ignorar deteccao de conflitos")
|
|
315
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
255
316
|
.action((title: string, decision: string, options) => {
|
|
256
|
-
decide(title, decision, options);
|
|
317
|
+
decide(title, decision, { ...options, specId: options.spec });
|
|
257
318
|
});
|
|
258
319
|
|
|
259
320
|
program
|
|
260
321
|
.command("decisions")
|
|
261
322
|
.description("Lista decisoes")
|
|
262
323
|
.option("--json", "Saida em JSON")
|
|
324
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
263
325
|
.action((options) => {
|
|
264
|
-
listDecisions(options.json);
|
|
326
|
+
listDecisions(options.json, options.spec);
|
|
265
327
|
});
|
|
266
328
|
|
|
267
329
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -277,12 +339,14 @@ knowledgeCmd
|
|
|
277
339
|
.requiredOption("--category <cat>", "Categoria (discovery, decision, blocker, pattern, constraint)")
|
|
278
340
|
.option("--severity <level>", "Severidade (info, warning, critical)", "info")
|
|
279
341
|
.option("--broadcast <target>", "Destino (all ou IDs separados por virgula)", "all")
|
|
342
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
280
343
|
.action((options) => {
|
|
281
344
|
addKnowledge({
|
|
282
345
|
content: options.content,
|
|
283
346
|
category: options.category,
|
|
284
347
|
severity: options.severity,
|
|
285
348
|
broadcastTo: options.broadcast,
|
|
349
|
+
specId: options.spec,
|
|
286
350
|
});
|
|
287
351
|
});
|
|
288
352
|
|
|
@@ -293,23 +357,26 @@ knowledgeCmd
|
|
|
293
357
|
.option("--category <cat>", "Filtrar por categoria")
|
|
294
358
|
.option("--severity <level>", "Filtrar por severidade (critical, warning, info)")
|
|
295
359
|
.option("--json", "Saida em JSON")
|
|
360
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
296
361
|
.action((options) => {
|
|
297
|
-
listKnowledge(options);
|
|
362
|
+
listKnowledge({ ...options, specId: options.spec });
|
|
298
363
|
});
|
|
299
364
|
|
|
300
365
|
knowledgeCmd
|
|
301
366
|
.command("ack <id>")
|
|
302
367
|
.description("Marca knowledge como lido pela task atual")
|
|
303
|
-
.
|
|
304
|
-
|
|
368
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
369
|
+
.action((id: string, options) => {
|
|
370
|
+
acknowledgeKnowledge(id, options.spec);
|
|
305
371
|
});
|
|
306
372
|
|
|
307
373
|
knowledgeCmd
|
|
308
374
|
.command("resolve <ids>")
|
|
309
375
|
.description("Resolve/reconhece knowledge item(s) critico(s)")
|
|
310
376
|
.option("--resolution <text>", "Descricao de como o blocker foi resolvido")
|
|
311
|
-
.
|
|
312
|
-
|
|
377
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
378
|
+
.action((ids: string, opts: { resolution?: string; spec?: string }) => {
|
|
379
|
+
resolveKnowledge(ids, opts.resolution, opts.spec);
|
|
313
380
|
});
|
|
314
381
|
|
|
315
382
|
knowledgeCmd
|
|
@@ -317,10 +384,20 @@ knowledgeCmd
|
|
|
317
384
|
.description("Consulta o knowledge graph (relacoes entre arquivos, decisoes, patterns)")
|
|
318
385
|
.option("--file <path>", "Buscar relacoes de um arquivo")
|
|
319
386
|
.option("--decision <id>", "Buscar arquivos afetados por uma decisao")
|
|
320
|
-
.option("--
|
|
387
|
+
.option("--json", "Saida em JSON")
|
|
388
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
389
|
+
.action((options) => {
|
|
390
|
+
queryGraph({ ...options, specId: options.spec });
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
knowledgeCmd
|
|
394
|
+
.command("compact")
|
|
395
|
+
.description("Compacta knowledge (merge similares, arquivar antigos)")
|
|
396
|
+
.option("--spec <id>", "ID do spec (padrao: todos)")
|
|
397
|
+
.option("--dry-run", "Apenas mostrar o que seria compactado")
|
|
321
398
|
.option("--json", "Saida em JSON")
|
|
322
399
|
.action((options) => {
|
|
323
|
-
|
|
400
|
+
compactKnowledge({ specId: options.spec, dryRun: options.dryRun, json: options.json });
|
|
324
401
|
});
|
|
325
402
|
|
|
326
403
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -333,22 +410,27 @@ reviewCmd
|
|
|
333
410
|
.command("start")
|
|
334
411
|
.description("Inicia o review")
|
|
335
412
|
.option("--json", "Saida em JSON")
|
|
413
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
336
414
|
.action((options) => {
|
|
337
|
-
reviewStart(options.json);
|
|
415
|
+
reviewStart(options.json, options.spec);
|
|
338
416
|
});
|
|
339
417
|
|
|
340
418
|
reviewCmd
|
|
341
419
|
.command("approve")
|
|
342
420
|
.description("Aprova o review e finaliza a feature")
|
|
343
|
-
.
|
|
344
|
-
|
|
421
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
422
|
+
.option("--force", "Aprovar mesmo com score baixo (<50)")
|
|
423
|
+
.option("--force-reason <reason>", "Motivo para aprovacao forcada")
|
|
424
|
+
.action((options) => {
|
|
425
|
+
reviewApprove({ specId: options.spec, force: options.force, forceReason: options.forceReason });
|
|
345
426
|
});
|
|
346
427
|
|
|
347
428
|
reviewCmd
|
|
348
429
|
.command("skip")
|
|
349
430
|
.description("Pula o review e finaliza a feature diretamente")
|
|
350
|
-
.
|
|
351
|
-
|
|
431
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
432
|
+
.action((options) => {
|
|
433
|
+
reviewSkip(options.spec);
|
|
352
434
|
});
|
|
353
435
|
|
|
354
436
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -359,8 +441,9 @@ program
|
|
|
359
441
|
.command("status")
|
|
360
442
|
.description("Mostra status atual")
|
|
361
443
|
.option("--json", "Saida em JSON")
|
|
444
|
+
.option("--spec <id>", "ID do spec (padrao: todos ativos)")
|
|
362
445
|
.action((options) => {
|
|
363
|
-
status(options.json);
|
|
446
|
+
status(options.json, options.spec);
|
|
364
447
|
});
|
|
365
448
|
|
|
366
449
|
const contextCmd = program.command("context").description("Comandos de contexto");
|
|
@@ -369,8 +452,9 @@ contextCmd
|
|
|
369
452
|
.command("export")
|
|
370
453
|
.description("Exporta contexto para subagent")
|
|
371
454
|
.option("--task <id>", "ID da task especifica")
|
|
455
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
372
456
|
.action((options) => {
|
|
373
|
-
contextExport({ ...options, json: true }); // Sempre JSON
|
|
457
|
+
contextExport({ ...options, json: true, specId: options.spec }); // Sempre JSON
|
|
374
458
|
});
|
|
375
459
|
|
|
376
460
|
contextCmd
|
|
@@ -379,16 +463,18 @@ contextCmd
|
|
|
379
463
|
.option("--approach <text>", "Adiciona nova abordagem descoberta")
|
|
380
464
|
.option("--pattern <text>", "Registra padrao identificado no codigo")
|
|
381
465
|
.option("--constraint <text>", "Adiciona nova limitacao encontrada")
|
|
466
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
382
467
|
.action((options) => {
|
|
383
|
-
contextUpdate(options);
|
|
468
|
+
contextUpdate({ ...options, specId: options.spec });
|
|
384
469
|
});
|
|
385
470
|
|
|
386
471
|
contextCmd
|
|
387
472
|
.command("detail <section>")
|
|
388
473
|
.description("Mostra secao especifica do contexto (standards, decisions, patterns, knowledge, architecture)")
|
|
389
474
|
.option("--json", "Output JSON")
|
|
390
|
-
.
|
|
391
|
-
|
|
475
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
476
|
+
.action((section: string, opts: { json?: boolean; spec?: string }) => {
|
|
477
|
+
contextDetail(section, opts.json, opts.spec);
|
|
392
478
|
});
|
|
393
479
|
|
|
394
480
|
// Manter compatibilidade: context sem subcomando = export
|
|
@@ -396,8 +482,9 @@ program
|
|
|
396
482
|
.command("ctx")
|
|
397
483
|
.description("Alias para context export (compatibilidade)")
|
|
398
484
|
.option("--task <id>", "ID da task especifica")
|
|
485
|
+
.option("--spec <id>", "ID do spec (padrao: mais recente)")
|
|
399
486
|
.action((options) => {
|
|
400
|
-
contextExport({ ...options, json: true });
|
|
487
|
+
contextExport({ ...options, json: true, specId: options.spec });
|
|
401
488
|
});
|
|
402
489
|
|
|
403
490
|
program
|
|
@@ -463,7 +550,7 @@ discoverCmd
|
|
|
463
550
|
});
|
|
464
551
|
|
|
465
552
|
discoverCmd
|
|
466
|
-
.command("reset")
|
|
553
|
+
.command("reset", { hidden: true })
|
|
467
554
|
.description("Reseta descoberta para refazer")
|
|
468
555
|
.action(() => {
|
|
469
556
|
discoverReset();
|
|
@@ -477,6 +564,13 @@ discoverCmd
|
|
|
477
564
|
await discoverRefresh(options);
|
|
478
565
|
});
|
|
479
566
|
|
|
567
|
+
discoverCmd
|
|
568
|
+
.command("incremental")
|
|
569
|
+
.description("Atualiza discover incrementalmente (arquivos modificados desde ultimo discover)")
|
|
570
|
+
.action(async () => {
|
|
571
|
+
await discoverIncremental();
|
|
572
|
+
});
|
|
573
|
+
|
|
480
574
|
// ─────────────────────────────────────────────────────────────────
|
|
481
575
|
// PATTERNS (v7.4)
|
|
482
576
|
// ─────────────────────────────────────────────────────────────────
|
|
@@ -524,7 +618,7 @@ discoverCmd
|
|
|
524
618
|
});
|
|
525
619
|
|
|
526
620
|
discoverCmd
|
|
527
|
-
.command("pattern-edit <name>")
|
|
621
|
+
.command("pattern-edit <name>", { hidden: true })
|
|
528
622
|
.description("Edita um implementation pattern")
|
|
529
623
|
.option("--category <cat>", "Nova categoria")
|
|
530
624
|
.option("--scope <scope>", "Novo escopo")
|
|
@@ -574,7 +668,7 @@ discoverCmd
|
|
|
574
668
|
});
|
|
575
669
|
|
|
576
670
|
discoverCmd
|
|
577
|
-
.command("analyze-file <path>")
|
|
671
|
+
.command("analyze-file <path>", { hidden: true })
|
|
578
672
|
.description("Analisa estrutura de um arquivo (imports, exports, convencoes)")
|
|
579
673
|
.option("--json", "Saida em JSON")
|
|
580
674
|
.action((path, options) => {
|
|
@@ -583,7 +677,7 @@ discoverCmd
|
|
|
583
677
|
|
|
584
678
|
// v9.0: Analise profunda com metadata enriquecida + grepai
|
|
585
679
|
discoverCmd
|
|
586
|
-
.command("analyze-deep <files...>")
|
|
680
|
+
.command("analyze-deep <files...>", { hidden: true })
|
|
587
681
|
.description("Analise profunda de arquivos (hooks, patterns, directives)")
|
|
588
682
|
.option("--json", "Saida em JSON")
|
|
589
683
|
.action((files, options) => {
|
|
@@ -593,7 +687,7 @@ discoverCmd
|
|
|
593
687
|
|
|
594
688
|
// v9.0: Anti-patterns de gate bypasses
|
|
595
689
|
discoverCmd
|
|
596
|
-
.command("extract-anti-patterns")
|
|
690
|
+
.command("extract-anti-patterns", { hidden: true })
|
|
597
691
|
.description("Extrai anti-patterns do historico de gate bypasses")
|
|
598
692
|
.action(() => {
|
|
599
693
|
const { extractAntiPatternsFromHistory } = require("./commands/patterns");
|
|
@@ -601,7 +695,7 @@ discoverCmd
|
|
|
601
695
|
});
|
|
602
696
|
|
|
603
697
|
discoverCmd
|
|
604
|
-
.command("export-patterns")
|
|
698
|
+
.command("export-patterns", { hidden: true })
|
|
605
699
|
.description("Regenera arquivo patterns.md")
|
|
606
700
|
.action(() => {
|
|
607
701
|
discoverExportPatterns();
|
|
@@ -819,11 +913,12 @@ program
|
|
|
819
913
|
.description("Limpa tasks/features mantendo configuracoes do projeto (standards, patterns, PRD)")
|
|
820
914
|
.option("--force", "Confirma a limpeza (sem isso apenas mostra o que sera removido)")
|
|
821
915
|
.option("--show", "Mostra estado atual dos arquivos do workflow")
|
|
916
|
+
.option("--spec <id>", "Limpa apenas o spec especificado")
|
|
822
917
|
.action((options) => {
|
|
823
918
|
if (options.show) {
|
|
824
919
|
clearShow();
|
|
825
920
|
} else {
|
|
826
|
-
clearTasks({ force: options.force });
|
|
921
|
+
clearTasks({ force: options.force, specId: options.spec });
|
|
827
922
|
}
|
|
828
923
|
});
|
|
829
924
|
|
|
@@ -895,5 +990,19 @@ architectCmd
|
|
|
895
990
|
architectCancel(options);
|
|
896
991
|
});
|
|
897
992
|
|
|
993
|
+
// ═══════════════════════════════════════════════════════════════
|
|
994
|
+
// PLUGIN
|
|
995
|
+
// ═══════════════════════════════════════════════════════════════
|
|
996
|
+
|
|
997
|
+
const pluginCmd = program.command("plugin").description("Comandos de gestao do plugin");
|
|
998
|
+
|
|
999
|
+
pluginCmd
|
|
1000
|
+
.command("sync-agents")
|
|
1001
|
+
.description("Copia agents do plugin para .claude/agents/ do projeto (resolve limitacao de subagent_type)")
|
|
1002
|
+
.option("--force", "Sobrescrever agents existentes")
|
|
1003
|
+
.action((options) => {
|
|
1004
|
+
syncAgents(options);
|
|
1005
|
+
});
|
|
1006
|
+
|
|
898
1007
|
// Parse e executa
|
|
899
1008
|
program.parse();
|