@codexa/cli 9.0.7 → 9.0.9

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.
@@ -13,11 +13,13 @@ import { getDb } from "../db/connection";
13
13
  import { SubagentReturn, Knowledge } from "./subagent-protocol";
14
14
  import { addReasoning, addGraphRelation, upsertUtility, getNextDecisionId } from "../db/schema";
15
15
  import { extractUtilitiesFromFile, inferScopeFromPath } from "../commands/patterns";
16
+ import { detectConflicts } from "../commands/decide";
16
17
 
17
18
  interface ProcessResult {
18
19
  success: boolean;
19
20
  knowledgeAdded: number;
20
21
  decisionsAdded: number;
22
+ conflictsDetected: number;
21
23
  artifactsAdded: number;
22
24
  patternsAdded: number;
23
25
  reasoningAdded: number; // v8.0
@@ -42,6 +44,7 @@ export function processSubagentReturn(
42
44
  success: true,
43
45
  knowledgeAdded: 0,
44
46
  decisionsAdded: 0,
47
+ conflictsDetected: 0,
45
48
  artifactsAdded: 0,
46
49
  patternsAdded: 0,
47
50
  reasoningAdded: 0,
@@ -102,6 +105,39 @@ export function processSubagentReturn(
102
105
  }
103
106
  }
104
107
 
108
+ // 2b. v9.5: Conflict check (WARNING, nao bloqueia subagent)
109
+ if (savedDecisionIds.length > 0) {
110
+ try {
111
+ const existingDecisions = db
112
+ .query("SELECT * FROM decisions WHERE spec_id = ? AND status = 'active'")
113
+ .all(specId) as any[];
114
+
115
+ for (const dec of data.decisions_made!) {
116
+ const othersOnly = existingDecisions.filter(
117
+ (d) => !savedDecisionIds.includes(d.id)
118
+ );
119
+ if (othersOnly.length === 0) continue;
120
+
121
+ const analysis = detectConflicts(dec.title, dec.decision, othersOnly);
122
+ if (analysis.hasConflict) {
123
+ for (const conflict of analysis.conflictingDecisions) {
124
+ db.run(
125
+ `INSERT INTO knowledge (spec_id, task_origin, category, content, severity, broadcast_to, created_at)
126
+ VALUES (?, ?, 'decision', ?, 'warning', 'all', ?)`,
127
+ [specId, taskId,
128
+ `CONFLITO DE DECISAO: "${dec.title}" pode conflitar com "${conflict.title}" (${conflict.id}). Motivo: ${conflict.reason}`,
129
+ now]
130
+ );
131
+ result.conflictsDetected++;
132
+ result.knowledgeAdded++;
133
+ }
134
+ }
135
+ }
136
+ } catch (e) {
137
+ result.errors.push(`Aviso conflict detection: ${(e as Error).message}`);
138
+ }
139
+ }
140
+
105
141
  // 3. Registrar Artifacts (files_created e files_modified)
106
142
  const allFiles = [
107
143
  ...data.files_created.map((f) => ({ path: f, action: "created" })),
@@ -246,7 +282,6 @@ export function processSubagentReturn(
246
282
  targetType: "file",
247
283
  targetId: file,
248
284
  relation: "creates",
249
- strength: 1.0,
250
285
  });
251
286
  result.relationsAdded++;
252
287
  }
@@ -259,7 +294,6 @@ export function processSubagentReturn(
259
294
  targetType: "file",
260
295
  targetId: file,
261
296
  relation: "modifies",
262
- strength: 1.0,
263
297
  });
264
298
  result.relationsAdded++;
265
299
  }
@@ -274,7 +308,6 @@ export function processSubagentReturn(
274
308
  targetType: "file",
275
309
  targetId: file,
276
310
  relation: "implements",
277
- strength: 0.8,
278
311
  });
279
312
  result.relationsAdded++;
280
313
  }
@@ -291,7 +324,6 @@ export function processSubagentReturn(
291
324
  targetType: "file",
292
325
  targetId: file,
293
326
  relation: "extracted_from",
294
- strength: 0.9,
295
327
  });
296
328
  result.relationsAdded++;
297
329
  }
@@ -354,6 +386,9 @@ export function formatProcessResult(result: ProcessResult): string {
354
386
  if (result.decisionsAdded > 0) {
355
387
  output += ` + ${result.decisionsAdded} decisao(es) registrada(s)\n`;
356
388
  }
389
+ if (result.conflictsDetected > 0) {
390
+ output += ` [!] ${result.conflictsDetected} conflito(s) de decisao detectado(s) (ver: knowledge list)\n`;
391
+ }
357
392
  if (result.artifactsAdded > 0) {
358
393
  output += ` + ${result.artifactsAdded} artefato(s) registrado(s)\n`;
359
394
  }
package/workflow.ts CHANGED
@@ -4,10 +4,10 @@ import { Command } from "commander";
4
4
  import { planStart, planShow, planTaskAdd, planCancel } from "./commands/plan";
5
5
  import { checkRequest, checkApprove, checkReject } from "./commands/check";
6
6
  import { taskNext, taskStart, taskDone } from "./commands/task";
7
- import { decide, listDecisions } from "./commands/decide";
7
+ import { decide, listDecisions, revokeDecision, supersedeDecision } from "./commands/decide";
8
8
  import { reviewStart, reviewApprove, reviewSkip } from "./commands/review";
9
9
  import { addKnowledge, listKnowledge, acknowledgeKnowledge, queryGraph, resolveKnowledge, compactKnowledge } from "./commands/knowledge";
10
- import { status, contextExport, recover, contextUpdate, contextDetail } from "./commands/utils";
10
+ import { status, contextExport, recover, contextDetail } from "./commands/utils";
11
11
  import {
12
12
  discoverStart,
13
13
  discoverConfirm,
@@ -26,9 +26,8 @@ import {
26
26
  } from "./commands/discover";
27
27
  import { clearTasks, clearShow } from "./commands/clear";
28
28
  import { standardsList, standardsAdd, standardsEdit, standardsRemove, standardsExport } from "./commands/standards";
29
- import { productGuide, productImport, productSet, productGoalAdd, productFeatureAdd, productConfirm, productShow, productReset } from "./commands/product";
29
+ import { productImport, productSet, productConfirm, productShow, productReset } from "./commands/product";
30
30
  import { researchStart, researchShow, researchFill, researchMapAgent, researchReset } from "./commands/research";
31
- import { patternsExtract, patternsAnalyze } from "./commands/patterns";
32
31
  import { syncAgents } from "./commands/sync";
33
32
  import {
34
33
  architectStart,
@@ -327,6 +326,24 @@ program
327
326
  listDecisions(options.json, options.spec);
328
327
  });
329
328
 
329
+ program
330
+ .command("decide:revoke <id>")
331
+ .description("Revoga uma decisao ativa")
332
+ .option("--reason <text>", "Motivo da revogacao")
333
+ .option("--spec <id>", "ID do spec (padrao: mais recente)")
334
+ .action(wrapAction((id: string, options) => {
335
+ revokeDecision(id, options.reason, options.spec);
336
+ }));
337
+
338
+ program
339
+ .command("decide:supersede <id> <title> <decision>")
340
+ .description("Substitui uma decisao ativa por uma nova")
341
+ .option("--rationale <text>", "Justificativa da nova decisao")
342
+ .option("--spec <id>", "ID do spec (padrao: mais recente)")
343
+ .action(wrapAction((id: string, title: string, decision: string, options) => {
344
+ supersedeDecision(id, title, decision, { rationale: options.rationale, specId: options.spec });
345
+ }));
346
+
330
347
  // ═══════════════════════════════════════════════════════════════
331
348
  // KNOWLEDGE BROADCAST
332
349
  // ═══════════════════════════════════════════════════════════════
@@ -458,17 +475,6 @@ contextCmd
458
475
  contextExport({ ...options, json: true, specId: options.spec }); // Sempre JSON
459
476
  });
460
477
 
461
- contextCmd
462
- .command("update")
463
- .description("Atualiza contexto durante implementacao")
464
- .option("--approach <text>", "Adiciona nova abordagem descoberta")
465
- .option("--pattern <text>", "Registra padrao identificado no codigo")
466
- .option("--constraint <text>", "Adiciona nova limitacao encontrada")
467
- .option("--spec <id>", "ID do spec (padrao: mais recente)")
468
- .action((options) => {
469
- contextUpdate({ ...options, specId: options.spec });
470
- });
471
-
472
478
  contextCmd
473
479
  .command("detail <section>")
474
480
  .description("Mostra secao especifica do contexto (standards, decisions, patterns, knowledge, architecture)")
@@ -546,8 +552,29 @@ discoverCmd
546
552
  .option("--styling <value>", "Styling (tailwind, styled-components)")
547
553
  .option("--auth <value>", "Auth (supabase, next-auth, clerk)")
548
554
  .option("--testing <value>", "Testing (vitest, jest, playwright)")
549
- .action((options) => {
550
- discoverSetStack(options);
555
+ .option("--typecheck-command <cmd>", "Comando custom de typecheck (ex: 'mypy --strict', 'go vet ./...'). Vazio para usar preset automatico.")
556
+ .action((options) => {
557
+ // Tratar typecheck-command separadamente
558
+ if (options.typecheckCommand !== undefined) {
559
+ const { initSchema } = require("./db/schema");
560
+ const { getDb } = require("./db/connection");
561
+ initSchema();
562
+ const db = getDb();
563
+ const value = options.typecheckCommand === "" ? null : options.typecheckCommand;
564
+ db.run("UPDATE project SET typecheck_command = ? WHERE id = 'default'", [value]);
565
+ if (value) {
566
+ console.log(`\n[ok] Typecheck command configurado: ${value}`);
567
+ } else {
568
+ console.log(`\n[ok] Typecheck command removido (usando preset automatico da stack)`);
569
+ }
570
+ console.log(" Sera usado no gate 4.5 (typecheck-pass) em cada task done.\n");
571
+ }
572
+ // Tratar stack options normalmente
573
+ const stackOptions = { ...options };
574
+ delete stackOptions.typecheckCommand;
575
+ if (Object.keys(stackOptions).length > 0) {
576
+ discoverSetStack(stackOptions);
577
+ }
551
578
  });
552
579
 
553
580
  discoverCmd
@@ -656,45 +683,6 @@ discoverCmd
656
683
  discoverRefreshPatterns();
657
684
  });
658
685
 
659
- // v8.0: Extração automática de patterns via grepai
660
- discoverCmd
661
- .command("extract-patterns")
662
- .description("Extrai patterns automaticamente via grepai (busca semântica)")
663
- .option("--scope <scope>", "Escopo (frontend, backend, database, testing)")
664
- .option("--all", "Extrair de todos os escopos")
665
- .option("--dry-run", "Apenas mostrar o que seria extraido")
666
- .option("--json", "Saida em JSON")
667
- .action((options) => {
668
- patternsExtract(options);
669
- });
670
-
671
- discoverCmd
672
- .command("analyze-file <path>", { hidden: true })
673
- .description("Analisa estrutura de um arquivo (imports, exports, convencoes)")
674
- .option("--json", "Saida em JSON")
675
- .action((path, options) => {
676
- patternsAnalyze(path, options.json);
677
- });
678
-
679
- // v9.0: Analise profunda com metadata enriquecida + grepai
680
- discoverCmd
681
- .command("analyze-deep <files...>", { hidden: true })
682
- .description("Analise profunda de arquivos (hooks, patterns, directives)")
683
- .option("--json", "Saida em JSON")
684
- .action((files, options) => {
685
- const { patternsAnalyzeDeep } = require("./commands/patterns");
686
- patternsAnalyzeDeep(files, options.json);
687
- });
688
-
689
- // v9.0: Anti-patterns de gate bypasses
690
- discoverCmd
691
- .command("extract-anti-patterns", { hidden: true })
692
- .description("Extrai anti-patterns do historico de gate bypasses")
693
- .action(() => {
694
- const { extractAntiPatternsFromHistory } = require("./commands/patterns");
695
- extractAntiPatternsFromHistory();
696
- });
697
-
698
686
  discoverCmd
699
687
  .command("export-patterns", { hidden: true })
700
688
  .description("Regenera arquivo patterns.md")
@@ -729,6 +717,8 @@ standardsCmd
729
717
  .option("--enforcement <level>", "Nivel de enforcement (required, recommended)")
730
718
  .option("--required", "Alias para --enforcement required")
731
719
  .option("--recommended", "Alias para --enforcement recommended")
720
+ .option("--semantic-query <query>", "Query semantica para grepai (ingles)")
721
+ .option("--expect <type>", "Expectativa: no_match ou must_match", "no_match")
732
722
  .action((options) => {
733
723
  // Resolver aliases de enforcement
734
724
  let enforcement = options.enforcement;
@@ -742,6 +732,8 @@ standardsCmd
742
732
  examples: options.examples,
743
733
  antiExamples: options.antiExamples,
744
734
  enforcement: enforcement,
735
+ semanticQuery: options.semanticQuery,
736
+ expect: options.expect,
745
737
  });
746
738
  });
747
739
 
@@ -752,12 +744,16 @@ standardsCmd
752
744
  .option("--examples <list>", "Novos exemplos")
753
745
  .option("--anti-examples <list>", "Novos anti-exemplos")
754
746
  .option("--enforcement <level>", "Novo nivel de enforcement")
747
+ .option("--semantic-query <query>", "Query semantica para grepai (ingles)")
748
+ .option("--expect <type>", "Expectativa: no_match ou must_match")
755
749
  .action((id, options) => {
756
750
  standardsEdit(id, {
757
751
  rule: options.rule,
758
752
  examples: options.examples,
759
753
  antiExamples: options.antiExamples,
760
754
  enforcement: options.enforcement,
755
+ semanticQuery: options.semanticQuery,
756
+ expect: options.expect,
761
757
  });
762
758
  });
763
759
 
@@ -781,14 +777,6 @@ standardsCmd
781
777
 
782
778
  const productCmd = program.command("product").description("Comandos de contexto de produto (PRD)");
783
779
 
784
- productCmd
785
- .command("guide")
786
- .description("Inicia modo guiado para definir contexto de produto")
787
- .option("--json", "Saida em JSON")
788
- .action((options) => {
789
- productGuide(options.json);
790
- });
791
-
792
780
  productCmd
793
781
  .command("import")
794
782
  .description("Importa PRD existente")
@@ -809,30 +797,12 @@ productCmd
809
797
  .option("--successMetrics <list>", "Metricas de sucesso (separadas por virgula)")
810
798
  .option("--outOfScope <list>", "Itens fora do escopo (separados por virgula)")
811
799
  .option("--constraints <list>", "Restricoes (separadas por virgula)")
800
+ .option("--goal <spec>", "Adiciona objetivo (formato: categoria:texto:prioridade)")
801
+ .option("--feature <spec>", "Adiciona feature (formato: nome:descricao:prioridade)")
812
802
  .action((options) => {
813
803
  productSet(options);
814
804
  });
815
805
 
816
- productCmd
817
- .command("goal-add")
818
- .description("Adiciona um objetivo do produto")
819
- .requiredOption("--category <cat>", "Categoria (negocio, tecnico, usuario, operacional)")
820
- .requiredOption("--goal <text>", "Descricao do objetivo")
821
- .option("--priority <level>", "Prioridade (high, medium, low)", "medium")
822
- .action((options) => {
823
- productGoalAdd(options);
824
- });
825
-
826
- productCmd
827
- .command("feature-add")
828
- .description("Adiciona uma feature core do produto")
829
- .requiredOption("--name <name>", "Nome da feature")
830
- .option("--description <text>", "Descricao da feature")
831
- .option("--priority <level>", "Prioridade (high, medium, low)", "medium")
832
- .action((options) => {
833
- productFeatureAdd(options);
834
- });
835
-
836
806
  productCmd
837
807
  .command("show")
838
808
  .description("Mostra contexto de produto")