@codexa/cli 8.6.12 → 8.6.14

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.
@@ -2,6 +2,8 @@ import { getDb } from "../db/connection";
2
2
  import { initSchema } from "../db/schema";
3
3
  import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
4
4
  import { join } from "path";
5
+ import { spawnSync } from "child_process";
6
+ import pkg from "../package.json";
5
7
  import {
6
8
  detectUniversal,
7
9
  detectStackLegacy,
@@ -181,9 +183,9 @@ export function discoverConfirm(): void {
181
183
  // Mover de pending para default
182
184
  db.run("DELETE FROM project WHERE id = 'pending'");
183
185
  db.run(
184
- `INSERT INTO project (id, name, stack, discovered_at, updated_at)
185
- VALUES ('default', ?, ?, ?, ?)`,
186
- ["Projeto", JSON.stringify(data.stack), now, now]
186
+ `INSERT INTO project (id, name, stack, discovered_at, updated_at, cli_version)
187
+ VALUES ('default', ?, ?, ?, ?, ?)`,
188
+ ["Projeto", JSON.stringify(data.stack), now, now, pkg.version]
187
189
  );
188
190
 
189
191
  // Criar standards baseados na estrutura detectada
@@ -996,6 +998,26 @@ export function discoverExportPatterns(): void {
996
998
  export function ensureDeepExploreAgent(): void {
997
999
  const agentPath = join(process.cwd(), ".claude", "agents", "deep-explore.md");
998
1000
 
1001
+ // Check grepai availability (grepai uses "help" not "--version")
1002
+ const grepaiCheck = spawnSync("grepai", ["help"], { encoding: "utf-8", timeout: 5000 });
1003
+ if (grepaiCheck.error) {
1004
+ console.warn("\n⚠ grepai nao encontrado no PATH.");
1005
+ console.warn(" O agente deep-explore depende de grepai para busca semantica.");
1006
+ console.warn(" Instale com: go install github.com/your-org/grepai@latest");
1007
+ console.warn(" Sem grepai, o deep-explore usara apenas Grep (menos eficaz).\n");
1008
+ } else {
1009
+ // Check if grepai index exists for this project
1010
+ const grepaiDir = join(process.cwd(), ".grepai");
1011
+ if (!existsSync(grepaiDir)) {
1012
+ console.warn("\n⚠ grepai index nao encontrado neste projeto.");
1013
+ console.warn(" Execute: grepai index");
1014
+ console.warn(" Sem o index, grepai search nao retornara resultados.\n");
1015
+ }
1016
+ }
1017
+
1018
+ // Ensure grepai permissions in target project settings
1019
+ ensureGrepaiPermissions();
1020
+
999
1021
  if (existsSync(agentPath)) return;
1000
1022
 
1001
1023
  const agentsDir = join(process.cwd(), ".claude", "agents");
@@ -1011,28 +1033,46 @@ color: cyan
1011
1033
  model: haiku
1012
1034
  ---
1013
1035
 
1014
- ## Instructions
1036
+ ## CRITICAL: You MUST use grepai
1015
1037
 
1016
- You are a specialized code exploration agent with access to grepai semantic search and call graph tracing.
1038
+ **YOUR FIRST ACTION must be a \\\`grepai search\\\` command via Bash.** This is non-negotiable.
1039
+
1040
+ You are a semantic code exploration agent. Your primary tool is \\\`grepai\\\` — an AI-powered semantic search engine. It finds code by INTENT and MEANING, not literal text matching.
1041
+
1042
+ **RULE: Every exploration MUST start with \\\`grepai search\\\`. If you use Grep or find BEFORE grepai, you have FAILED your task.**
1043
+
1044
+ ---
1017
1045
 
1018
- ### Primary Tools
1046
+ ### Step 1: ALWAYS run grepai search FIRST
1019
1047
 
1020
- #### 1. Semantic Search: \`grepai search\`
1048
+ **IMPORTANT: Execute ONE grepai search per Bash call. Do NOT run multiple grepai commands in parallel — this causes "Sibling tool call errored". Run them SEQUENTIALLY, one at a time.**
1021
1049
 
1022
- Use this to find code by intent and meaning:
1050
+ \\\`\\\`\\\`bash
1051
+ grepai search "your query here" --json --compact
1052
+ \\\`\\\`\\\`
1023
1053
 
1024
- \`\`\`bash
1025
- # Use English queries for best results (--compact saves ~80% tokens)
1054
+ - Queries MUST be in English
1055
+ - Use \\\`--compact\\\` to save tokens
1056
+ - Use natural language: "authentication flow", "error handling middleware", "how payments are processed"
1057
+ - Run ONE command, wait for result, then run the next
1058
+
1059
+ Examples (run each one SEPARATELY):
1060
+
1061
+ \\\`\\\`\\\`bash
1026
1062
  grepai search "authentication flow" --json --compact
1063
+ \\\`\\\`\\\`
1064
+
1065
+ \\\`\\\`\\\`bash
1027
1066
  grepai search "error handling middleware" --json --compact
1028
- grepai search "database connection management" --json --compact
1029
- \`\`\`
1067
+ \\\`\\\`\\\`
1030
1068
 
1031
- #### 2. Call Graph Tracing: \`grepai trace\`
1069
+ \\\`\\\`\\\`bash
1070
+ grepai search "database connection management" --json --compact
1071
+ \\\`\\\`\\\`
1032
1072
 
1033
- Use this to understand function relationships and code flow:
1073
+ ### Step 2: Use grepai trace for relationships
1034
1074
 
1035
- \`\`\`bash
1075
+ \\\`\\\`\\\`bash
1036
1076
  # Find all functions that call a symbol
1037
1077
  grepai trace callers "HandleRequest" --json
1038
1078
 
@@ -1041,32 +1081,78 @@ grepai trace callees "ProcessOrder" --json
1041
1081
 
1042
1082
  # Build complete call graph
1043
1083
  grepai trace graph "ValidateToken" --depth 3 --json
1044
- \`\`\`
1084
+ \\\`\\\`\\\`
1085
+
1086
+ ### Step 3: Read files identified by grepai
1087
+
1088
+ Use \\\`Read\\\` to examine files that grepai found relevant.
1089
+
1090
+ ### Step 4: Grep ONLY for exact literals (optional)
1045
1091
 
1046
- Use \`grepai trace\` when you need to:
1092
+ Use Grep ONLY if you need exact string match (variable name, import path). Never use Grep for exploration — grepai is always better for that.
1047
1093
 
1048
- - Find all callers of a function
1049
- - Understand the call hierarchy
1050
- - Analyze the impact of changes to a function
1051
- - Map dependencies between components
1094
+ ---
1095
+
1096
+ ### FORBIDDEN
1052
1097
 
1053
- ### When to use standard tools
1098
+ - **DO NOT** use \\\`find\\\` or \\\`ls\\\` to explore code — use \\\`grepai search\\\`
1099
+ - **DO NOT** use \\\`Grep\\\` for semantic exploration — use \\\`grepai search\\\`
1100
+ - **DO NOT** skip grepai and go straight to Read/Grep
1101
+ - **DO NOT** write custom exploration logic when grepai can answer it
1054
1102
 
1055
- Only fall back to Grep/Glob when:
1103
+ ### If grepai fails
1056
1104
 
1057
- - You need exact text matching (variable names, imports)
1058
- - grepai is not available or returns errors
1059
- - You need file path patterns
1105
+ If \\\`grepai search\\\` returns an error (command not found, index missing), report this in your response:
1060
1106
 
1061
- ### Workflow
1107
+ \\\`\\\`\\\`json
1108
+ {"status": "blocked", "blockers": ["grepai not available: <error message>"]}
1109
+ \\\`\\\`\\\`
1062
1110
 
1063
- 1. Start with \`grepai search\` to find relevant code semantically
1064
- 2. Use \`grepai trace\` to understand function relationships and call graphs
1065
- 3. Use \`Read\` to examine promising files in detail
1066
- 4. Use Grep only for exact string searches if needed
1067
- 5. Synthesize findings into a clear summary
1111
+ Do NOT silently fall back to Grep. The orchestrator needs to know grepai is not working.
1068
1112
  `;
1069
1113
 
1070
1114
  writeFileSync(agentPath, content);
1071
1115
  console.log("✓ Agent deep-explore instalado em .claude/agents/deep-explore.md");
1116
+ }
1117
+
1118
+ // Ensure grepai Bash permissions exist in the target project's .claude/settings.local.json
1119
+ function ensureGrepaiPermissions(): void {
1120
+ const settingsPath = join(process.cwd(), ".claude", "settings.local.json");
1121
+ const claudeDir = join(process.cwd(), ".claude");
1122
+
1123
+ if (!existsSync(claudeDir)) {
1124
+ mkdirSync(claudeDir, { recursive: true });
1125
+ }
1126
+
1127
+ const requiredPermissions = [
1128
+ "Bash(grepai search:*)",
1129
+ "Bash(grepai trace:*)",
1130
+ "Bash(grepai:*)",
1131
+ ];
1132
+
1133
+ let settings: { permissions?: { allow?: string[] } } = {};
1134
+
1135
+ if (existsSync(settingsPath)) {
1136
+ try {
1137
+ settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
1138
+ } catch {
1139
+ settings = {};
1140
+ }
1141
+ }
1142
+
1143
+ if (!settings.permissions) settings.permissions = {};
1144
+ if (!settings.permissions.allow) settings.permissions.allow = [];
1145
+
1146
+ let added = false;
1147
+ for (const perm of requiredPermissions) {
1148
+ if (!settings.permissions.allow.includes(perm)) {
1149
+ settings.permissions.allow.push(perm);
1150
+ added = true;
1151
+ }
1152
+ }
1153
+
1154
+ if (added) {
1155
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
1156
+ console.log("✓ Permissoes de grepai adicionadas em .claude/settings.local.json");
1157
+ }
1072
1158
  }
@@ -76,8 +76,8 @@ const PATTERN_QUERIES: PatternQuery[] = [
76
76
 
77
77
  function isGrepaiAvailable(): boolean {
78
78
  try {
79
- const result = spawnSync("grepai", ["--version"], { encoding: "utf-8" });
80
- return result.status === 0;
79
+ const result = spawnSync("grepai", ["help"], { encoding: "utf-8", timeout: 5000 });
80
+ return !result.error;
81
81
  } catch {
82
82
  return false;
83
83
  }
package/db/schema.ts CHANGED
@@ -383,6 +383,13 @@ export function initSchema(): void {
383
383
  } catch {
384
384
  // Coluna ja existe - ignorar
385
385
  }
386
+
387
+ // v8.7: Migracao - adicionar cli_version na tabela project
388
+ try {
389
+ db.exec(`ALTER TABLE project ADD COLUMN cli_version TEXT`);
390
+ } catch {
391
+ // Coluna ja existe - ignorar
392
+ }
386
393
  }
387
394
 
388
395
  export function getPatternsByScope(scope: string): any[] {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codexa/cli",
3
- "version": "8.6.12",
3
+ "version": "8.6.14",
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": {
package/workflow.ts CHANGED
@@ -38,23 +38,60 @@ import {
38
38
  architectCancel,
39
39
  } from "./commands/architect";
40
40
  import { initSchema } from "./db/schema";
41
+ import { getDb } from "./db/connection";
41
42
  import { execSync } from "child_process";
42
43
  import { existsSync, readFileSync } from "fs";
43
44
  import { join } from "path";
44
45
  import pkg from "./package.json";
45
46
 
46
47
  function checkVersionSync(): void {
48
+ // 1. Check CLI vs Plugin (dev repo only)
47
49
  try {
48
50
  const gitRoot = execSync("git rev-parse --show-toplevel", { encoding: "utf-8" }).trim();
49
51
  const pluginJson = join(gitRoot, "plugins", "codexa-workflow", ".claude-plugin", "plugin.json");
50
- if (!existsSync(pluginJson)) return;
51
- const plugin = JSON.parse(readFileSync(pluginJson, "utf-8"));
52
- if (plugin.version && plugin.version !== pkg.version) {
53
- console.warn(`\nVersao desatualizada: CLI=${pkg.version} Plugin=${plugin.version}`);
54
- console.warn(` Atualize o CLI: bun add -g @codexa/cli\n`);
52
+ if (existsSync(pluginJson)) {
53
+ const plugin = JSON.parse(readFileSync(pluginJson, "utf-8"));
54
+ if (plugin.version && plugin.version !== pkg.version) {
55
+ console.error(`\nVersao incompativel: CLI=${pkg.version} Plugin=${plugin.version}`);
56
+ console.error(` O CLI e o plugin DEVEM ter a mesma versao.`);
57
+ console.error(` Atualize o CLI: bun add -g @codexa/cli@${plugin.version}\n`);
58
+ process.exit(1);
59
+ }
55
60
  }
56
61
  } catch {
57
- // Not in a git repo or plugin not found — skip silently
62
+ // Not in dev repo — skip
63
+ }
64
+
65
+ // 2. Check CLI vs project's stored version (client projects)
66
+ try {
67
+ const dbPath = join(process.cwd(), ".codexa", "db", "workflow.db");
68
+ if (!existsSync(dbPath)) return;
69
+
70
+ initSchema();
71
+ const db = getDb();
72
+ const project = db.query("SELECT cli_version FROM project WHERE id = 'default'").get() as any;
73
+ if (!project) return;
74
+
75
+ if (!project.cli_version) {
76
+ // Projeto existente sem versao gravada (pre-v8.7) — registrar versao atual
77
+ db.run(
78
+ `UPDATE project SET cli_version = ? WHERE id = 'default'`,
79
+ [pkg.version]
80
+ );
81
+ console.log(`✓ Versao do CLI (${pkg.version}) registrada no projeto.`);
82
+ return;
83
+ }
84
+
85
+ if (project.cli_version !== pkg.version) {
86
+ console.error(`\n✘ Versao incompativel: CLI=${pkg.version} Projeto=${project.cli_version}`);
87
+ console.error(` O projeto foi configurado com CLI v${project.cli_version} mas voce esta usando v${pkg.version}.`);
88
+ console.error(` Opcoes:`);
89
+ console.error(` 1. Atualize o CLI: bun add -g @codexa/cli@${project.cli_version}`);
90
+ console.error(` 2. Reconfigure o projeto: codexa discover reset && codexa discover start\n`);
91
+ process.exit(1);
92
+ }
93
+ } catch {
94
+ // DB not available or column doesn't exist yet — skip
58
95
  }
59
96
  }
60
97