deepdebug-local-agent 1.0.13 → 1.0.15

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/server.js +314 -314
package/src/server.js CHANGED
@@ -28,7 +28,7 @@ import { startMCPHttpServer } from "./mcp-http-server.js";
28
28
  const execAsync = promisify(exec);
29
29
 
30
30
  // ============================================
31
- // 🧠 AI VIBE CODING ENGINE
31
+ // AI VIBE CODING ENGINE
32
32
  // Sistema universal de auto-healing que usa AI
33
33
  // para resolver QUALQUER erro automaticamente
34
34
  // ============================================
@@ -48,7 +48,7 @@ class AIVibeCodingEngine extends EventEmitter {
48
48
  this.currentSession = null;
49
49
  this.lastSuccessfulConfig = null;
50
50
 
51
- console.log('🧠 [AI-Engine] Vibe Coding Engine initialized');
51
+ console.log(' [AI-Engine] Vibe Coding Engine initialized');
52
52
  this.setupErrorMonitoring();
53
53
  }
54
54
 
@@ -61,9 +61,9 @@ class AIVibeCodingEngine extends EventEmitter {
61
61
 
62
62
  this.processManager.on('stopped', async ({ serviceId, code, signal }) => {
63
63
  if (this.isActive && code !== 0 && code !== null) {
64
- console.log(`🧠 [AI-Engine] Process ${serviceId} crashed (code: ${code})`);
64
+ console.log(` [AI-Engine] Process ${serviceId} crashed (code: ${code})`);
65
65
  if (this.pendingFixes.length > 0) {
66
- console.log(`💡 [AI-Engine] ${this.pendingFixes.length} fixes pending`);
66
+ console.log(` [AI-Engine] ${this.pendingFixes.length} fixes pending`);
67
67
  }
68
68
  }
69
69
  });
@@ -89,22 +89,22 @@ class AIVibeCodingEngine extends EventEmitter {
89
89
  /cannot.*find.*module/i,
90
90
  /application.*run.*failed/i,
91
91
  /bean.*creation.*exception/i,
92
- /hikaripool.*exception/i, // exceções, não "HikariPool-1 - Starting"
92
+ /hikaripool.*exception/i, // S excees, no "HikariPool-1 - Starting"
93
93
  /jdbc.*exception/i,
94
94
  /datasource.*failed/i
95
95
  ];
96
96
 
97
- // Excluir falsos positivos (linhas normais que contêm palavras de erro)
97
+ // Excluir falsos positivos (linhas normais que contm palavras de erro)
98
98
  const falsePositives = [
99
- /hikaripool.*start/i, // "HikariPool-1 - Starting..." é normal
100
- /hikaripool.*completed/i, // "HikariPool-1 - Start completed" é normal
101
- /no active profile/i, // "No active profile set" é normal
99
+ /hikaripool.*start/i, // "HikariPool-1 - Starting..." normal
100
+ /hikaripool.*completed/i, // "HikariPool-1 - Start completed" normal
101
+ /no active profile/i, // "No active profile set" normal
102
102
  /exposing.*endpoint/i, // Linha normal de startup
103
- /started.*application/i, // "Started PurePilatesCoreApplication" é sucesso!
104
- /tomcat started/i // "Tomcat started on port" é sucesso!
103
+ /started.*application/i, // "Started PurePilatesCoreApplication" sucesso!
104
+ /tomcat started/i // "Tomcat started on port" sucesso!
105
105
  ];
106
106
 
107
- // Se match com falso positivo, não é erro
107
+ // Se match com falso positivo, no erro
108
108
  if (falsePositives.some(p => p.test(message))) {
109
109
  return false;
110
110
  }
@@ -164,12 +164,12 @@ class AIVibeCodingEngine extends EventEmitter {
164
164
  this.errorHistory.push(entry);
165
165
  if (this.errorHistory.length > 200) this.errorHistory = this.errorHistory.slice(-200);
166
166
 
167
- console.log(`🧠 [AI-Engine] Error: ${classification.type} (${classification.severity})`);
167
+ console.log(` [AI-Engine] Error: ${classification.type} (${classification.severity})`);
168
168
 
169
169
  if (classification.autoFixable) {
170
170
  const fix = this.getQuickFix(classification.type, errorMessage);
171
171
  if (fix) {
172
- console.log(`💡 [AI-Engine] Quick fix: ${fix.description}`);
172
+ console.log(` [AI-Engine] Quick fix: ${fix.description}`);
173
173
  this.pendingFixes.push({ errorId: entry.id, fix, timestamp: Date.now() });
174
174
  }
175
175
  }
@@ -204,7 +204,7 @@ class AIVibeCodingEngine extends EventEmitter {
204
204
  }
205
205
 
206
206
  async startWithAutoHealing(config) {
207
- console.log('🧠 [AI-Engine] Starting with auto-healing...');
207
+ console.log(' [AI-Engine] Starting with auto-healing...');
208
208
 
209
209
  this.currentSession = {
210
210
  startTime: Date.now(),
@@ -218,16 +218,16 @@ class AIVibeCodingEngine extends EventEmitter {
218
218
 
219
219
  while (attempts < this.maxRetries) {
220
220
  attempts++;
221
- console.log(`\n🔄 [AI-Engine] Attempt ${attempts}/${this.maxRetries}`);
221
+ console.log(`\n [AI-Engine] Attempt ${attempts}/${this.maxRetries}`);
222
222
 
223
223
  if (attempts > 1 && this.pendingFixes.length > 0) {
224
224
  const fix = this.pendingFixes.shift();
225
- console.log(`💡 Applying: ${fix.fix.description}`);
225
+ console.log(` Applying: ${fix.fix.description}`);
226
226
  currentConfig = this.applyFix(currentConfig, fix.fix);
227
227
  }
228
228
 
229
229
  if (currentConfig.recompile) {
230
- console.log('🔨 Recompiling...');
230
+ console.log(' Recompiling...');
231
231
  await this.recompile();
232
232
  delete currentConfig.recompile;
233
233
  }
@@ -242,7 +242,7 @@ class AIVibeCodingEngine extends EventEmitter {
242
242
  });
243
243
 
244
244
  if (result.success) {
245
- console.log(`\n [AI-Engine] Success after ${attempts} attempt(s)`);
245
+ console.log(`\n [AI-Engine] Success after ${attempts} attempt(s)`);
246
246
  this.lastSuccessfulConfig = { ...currentConfig };
247
247
 
248
248
  if (attempts > 1) {
@@ -257,16 +257,16 @@ class AIVibeCodingEngine extends EventEmitter {
257
257
  }
258
258
 
259
259
  lastError = result.error;
260
- console.log(`❌ Attempt ${attempts} failed: ${lastError?.substring(0, 100)}...`);
260
+ console.log(` Attempt ${attempts} failed: ${lastError?.substring(0, 100)}...`);
261
261
 
262
262
  const fix = this.getFix(result.error, currentConfig);
263
263
  if (fix) {
264
- console.log(`💡 Fix: ${fix.description}`);
264
+ console.log(` Fix: ${fix.description}`);
265
265
  currentConfig = this.applyFix(currentConfig, fix);
266
266
  } else {
267
267
  const ai = await this.analyzeWithAI('startup', lastError, currentConfig);
268
268
  if (ai?.newConfig) {
269
- console.log(`🤖 AI: ${ai.suggestion}`);
269
+ console.log(` AI: ${ai.suggestion}`);
270
270
  currentConfig = ai.newConfig;
271
271
  } else {
272
272
  break;
@@ -274,7 +274,7 @@ class AIVibeCodingEngine extends EventEmitter {
274
274
  }
275
275
  }
276
276
 
277
- console.log(`\n [AI-Engine] Failed after ${attempts} attempts`);
277
+ console.log(`\n [AI-Engine] Failed after ${attempts} attempts`);
278
278
  return { ok: false, attempts, error: lastError, config: currentConfig };
279
279
  }
280
280
 
@@ -305,7 +305,7 @@ class AIVibeCodingEngine extends EventEmitter {
305
305
 
306
306
  // Detectar sucesso nos logs do Spring Boot
307
307
  if (isStartupSuccess(message) && !resolved) {
308
- console.log(`✅ [AI-Engine] Detected startup success: ${message.substring(0, 80)}...`);
308
+ console.log(` [AI-Engine] Detected startup success: ${message.substring(0, 80)}...`);
309
309
  resolved = true;
310
310
  cleanup();
311
311
  resolve({ success: true, logs });
@@ -372,7 +372,7 @@ class AIVibeCodingEngine extends EventEmitter {
372
372
  newConfig.profile = next;
373
373
  newConfig.args = this.updateArgs(config.args, 'profile', next);
374
374
  newConfig.env = { ...config.env, SPRING_PROFILES_ACTIVE: next };
375
- console.log(`Profile: ${config.profile}${next}`);
375
+ console.log(` Profile: ${config.profile} ${next}`);
376
376
  break;
377
377
 
378
378
  case 'change_port':
@@ -380,7 +380,7 @@ class AIVibeCodingEngine extends EventEmitter {
380
380
  newConfig.port = newPort;
381
381
  newConfig.args = this.updateArgs(config.args, 'port', newPort);
382
382
  newConfig.env = { ...config.env, SERVER_PORT: String(newPort), PORT: String(newPort) };
383
- console.log(`Port: ${config.port}${newPort}`);
383
+ console.log(` Port: ${config.port} ${newPort}`);
384
384
  break;
385
385
 
386
386
  case 'recompile':
@@ -418,7 +418,7 @@ class AIVibeCodingEngine extends EventEmitter {
418
418
 
419
419
  if (response.ok) return await response.json();
420
420
  } catch (err) {
421
- console.log(`⚠️ [AI-Engine] AI unavailable: ${err.message}`);
421
+ console.log(` [AI-Engine] AI unavailable: ${err.message}`);
422
422
  }
423
423
 
424
424
  return this.localFallback(errorType, error, config);
@@ -527,7 +527,7 @@ class AIVibeCodingEngine extends EventEmitter {
527
527
 
528
528
  setActive(active) {
529
529
  this.isActive = active;
530
- console.log(`🧠 [AI-Engine] ${active ? 'ENABLED' : 'DISABLED'}`);
530
+ console.log(` [AI-Engine] ${active ? 'ENABLED' : 'DISABLED'}`);
531
531
  }
532
532
 
533
533
  clearHistory() {
@@ -537,15 +537,15 @@ class AIVibeCodingEngine extends EventEmitter {
537
537
  }
538
538
  }
539
539
 
540
- // Instância global do AI Engine
540
+ // Instncia global do AI Engine
541
541
  let aiEngine = null;
542
542
 
543
543
  const app = express();
544
544
 
545
- //FIXED: Support Cloud Run PORT environment variable (GCP uses PORT)
545
+ // FIXED: Support Cloud Run PORT environment variable (GCP uses PORT)
546
546
  const PORT = process.env.PORT || process.env.LOCAL_AGENT_PORT || 5055;
547
547
 
548
- //FIXED: Allow CORS from Cloud Run and local development
548
+ // FIXED: Allow CORS from Cloud Run and local development
549
549
  app.use(cors({
550
550
  origin: [
551
551
  "http://localhost:3010",
@@ -566,18 +566,18 @@ app.use(cors({
566
566
  credentials: true
567
567
  }));
568
568
 
569
- //Handle preflight requests explicitly
569
+ // Handle preflight requests explicitly
570
570
  app.options('*', cors());
571
571
 
572
572
  app.use(bodyParser.json({ limit: "50mb" }));
573
573
 
574
- // 🔧 DEFAULT WORKSPACE - Define o workspace padrão
575
- // Pode ser sobrescrito via variável de ambiente ou POST /workspace/open
574
+ // DEFAULT WORKSPACE - Define o workspace padro
575
+ // Pode ser sobrescrito via varivel de ambiente ou POST /workspace/open
576
576
  const DEFAULT_WORKSPACE = process.env.DEFAULT_WORKSPACE || '/Users/macintosh/IdeaProjects/pure-core-ms';
577
577
 
578
578
  let WORKSPACE_ROOT = fs.existsSync(DEFAULT_WORKSPACE) ? DEFAULT_WORKSPACE : null;
579
579
  if (WORKSPACE_ROOT) {
580
- console.log(`📁 Default workspace: ${WORKSPACE_ROOT}`);
580
+ console.log(` Default workspace: ${WORKSPACE_ROOT}`);
581
581
  }
582
582
 
583
583
  let DETECTED_SERVICES = [];
@@ -593,11 +593,11 @@ function resolveWorkspaceRoot(req) {
593
593
  }
594
594
  const MCP_PORT = process.env.MCP_PORT || 5056;
595
595
 
596
- // 🧠 Inicializar AI Vibe Coding Engine
596
+ // Inicializar AI Vibe Coding Engine
597
597
  aiEngine = new AIVibeCodingEngine(processManager, () => WORKSPACE_ROOT);
598
598
 
599
599
  // ============================================
600
- // 🆕 BACKUP STORAGE (Sprint 1.3)
600
+ // BACKUP STORAGE (Sprint 1.3)
601
601
  // In-memory backup storage with configurable max size
602
602
  // ============================================
603
603
  const BACKUPS = new Map();
@@ -606,7 +606,7 @@ const BACKUP_INDEX_PATH = path.join(os.tmpdir(), 'deepdebug-backups-index.json')
606
606
 
607
607
  /**
608
608
  * Persist backup index to disk so diffs survive server restarts.
609
- * Only saves the index (backupIdfiles paths), not the file contents.
609
+ * Only saves the index (backupId files paths), not the file contents.
610
610
  * File contents are read from the backup directory on disk.
611
611
  */
612
612
  function saveBackupIndex() {
@@ -652,7 +652,7 @@ function loadBackupIndex() {
652
652
  });
653
653
  }
654
654
  }
655
- console.log(`📦 Restored ${BACKUPS.size} backups from disk`);
655
+ console.log(` Restored ${BACKUPS.size} backups from disk`);
656
656
  }
657
657
  } catch (e) {
658
658
  console.warn('Could not load backup index:', e.message);
@@ -664,19 +664,19 @@ loadBackupIndex();
664
664
 
665
665
  // Event listeners do ProcessManager
666
666
  processManager.on("started", ({ serviceId }) => {
667
- console.log(`✅ Service ${serviceId} started successfully`);
667
+ console.log(` Service ${serviceId} started successfully`);
668
668
  updateServiceStatus(serviceId, "running");
669
669
  addServerLog("info", `Service ${serviceId} started successfully`);
670
670
  });
671
671
 
672
672
  processManager.on("stopped", ({ serviceId }) => {
673
- console.log(`ℹ️ Service ${serviceId} stopped`);
673
+ console.log(` Service ${serviceId} stopped`);
674
674
  updateServiceStatus(serviceId, "stopped");
675
675
  addServerLog("info", `Service ${serviceId} stopped`);
676
676
  });
677
677
 
678
678
  processManager.on("error", ({ serviceId, error }) => {
679
- console.error(`❌ Service ${serviceId} error: ${error}`);
679
+ console.error(` Service ${serviceId} error: ${error}`);
680
680
  updateServiceStatus(serviceId, "failed");
681
681
  addServerLog("error", `Service ${serviceId} error: ${error}`);
682
682
  });
@@ -731,10 +731,10 @@ app.post("/workspace/open", async (req, res) => {
731
731
  // CLOUD MODE: Git clone (when Gateway sends repoUrl)
732
732
  // ==========================================
733
733
  if (repoUrl) {
734
- console.log(`📂 [/workspace/open] CLOUD MODEcloning ${repoUrl} (branch: ${branch})`);
734
+ console.log(` [/workspace/open] CLOUD MODE cloning ${repoUrl} (branch: ${branch})`);
735
735
 
736
736
  try {
737
- // Extract repo name: https://github.com/org/repoorg_repo
737
+ // Extract repo name: https://github.com/org/repo org_repo
738
738
  let repoName = repoUrl.split('/').pop().replace('.git', '');
739
739
  const urlParts = repoUrl.replace(/\.git$/, '').split('/');
740
740
  if (urlParts.length >= 2) {
@@ -761,7 +761,7 @@ app.post("/workspace/open", async (req, res) => {
761
761
  // Already in user:pass format (Bitbucket/GitLab)
762
762
  authUrl = cleanUrl.replace('https://', `https://${token}@`);
763
763
  } else {
764
- // Plain tokenGitHub style
764
+ // Plain token GitHub style
765
765
  authUrl = cleanUrl.replace('https://', `https://x-access-token:${token}@`);
766
766
  }
767
767
  } else {
@@ -772,16 +772,16 @@ app.post("/workspace/open", async (req, res) => {
772
772
  const alreadyCloned = await exists(gitDir);
773
773
 
774
774
  if (alreadyCloned) {
775
- console.log(`🔄 [cloud] Repo exists: ${clonePath}, updating...`);
775
+ console.log(` [cloud] Repo exists: ${clonePath}, updating...`);
776
776
  // Update remote URL with fresh token
777
777
  await execAsync(`git remote set-url origin "${authUrl}"`, { cwd: clonePath }).catch(() => {});
778
778
  await execAsync(`git fetch origin`, { cwd: clonePath, timeout: 120000 });
779
779
  // Checkout correct branch and reset to remote (discard previous patches)
780
780
  await execAsync(`git checkout ${branch} 2>/dev/null || git checkout -b ${branch} origin/${branch}`, { cwd: clonePath }).catch(() => {});
781
781
  await execAsync(`git reset --hard origin/${branch}`, { cwd: clonePath });
782
- console.log(`✅ [cloud] Updated to latest ${branch}`);
782
+ console.log(` [cloud] Updated to latest ${branch}`);
783
783
  } else {
784
- console.log(`🔽 [cloud] Cloning ${repoUrl} (branch: ${branch})...`);
784
+ console.log(` [cloud] Cloning ${repoUrl} (branch: ${branch})...`);
785
785
  await execAsync(
786
786
  `git clone --branch ${branch} --single-branch --depth 50 "${authUrl}" "${clonePath}"`,
787
787
  { timeout: 300000 }
@@ -789,7 +789,7 @@ app.post("/workspace/open", async (req, res) => {
789
789
  // Configure git user for future commits
790
790
  await execAsync(`git config user.email "deepdebug-ai@deepdebug.ai"`, { cwd: clonePath });
791
791
  await execAsync(`git config user.name "DeepDebug AI"`, { cwd: clonePath });
792
- console.log(`✅ [cloud] Cloned successfully: ${clonePath}`);
792
+ console.log(` [cloud] Cloned successfully: ${clonePath}`);
793
793
  }
794
794
 
795
795
  // Set as active workspace
@@ -799,7 +799,7 @@ app.post("/workspace/open", async (req, res) => {
799
799
  }
800
800
  const wsId = workspaceId || "default";
801
801
  try { await wsManager.open(wsId, clonePath); } catch (err) {
802
- console.warn(`⚠️ WorkspaceManager.open failed (non-fatal): ${err.message}`);
802
+ console.warn(` WorkspaceManager.open failed (non-fatal): ${err.message}`);
803
803
  }
804
804
 
805
805
  const meta = await detectProject(clonePath);
@@ -815,7 +815,7 @@ app.post("/workspace/open", async (req, res) => {
815
815
  });
816
816
 
817
817
  } catch (gitErr) {
818
- console.error(`❌ [cloud] Git clone failed:`, gitErr.message);
818
+ console.error(` [cloud] Git clone failed:`, gitErr.message);
819
819
  const hint = gitErr.message.includes('Authentication') || gitErr.message.includes('could not read')
820
820
  ? "Authentication failed. Check token and repo URL."
821
821
  : gitErr.message.includes('not found') || gitErr.message.includes('does not exist')
@@ -832,22 +832,22 @@ app.post("/workspace/open", async (req, res) => {
832
832
  const abs = path.resolve(root);
833
833
  if (!(await exists(abs))) return res.status(404).json({ error: "path not found" });
834
834
 
835
+ // Registar no WorkspaceManager (multi-workspace support)
836
+ const wsId = workspaceId || "default";
837
+
835
838
  // TENANT ISOLATION: Only set global for default
836
839
  if (wsId === "default") {
837
840
  WORKSPACE_ROOT = abs;
838
841
  }
839
-
840
- // Registar no WorkspaceManager (multi-workspace support)
841
- const wsId = workspaceId || "default";
842
842
  try {
843
843
  await wsManager.open(wsId, abs);
844
844
  } catch (err) {
845
- console.warn(`⚠️ WorkspaceManager open failed (non-fatal): ${err.message}`);
845
+ console.warn(` WorkspaceManager open failed (non-fatal): ${err.message}`);
846
846
  }
847
847
 
848
- const meta = await detectProject(WORKSPACE_ROOT);
849
- const port = await detectPort(WORKSPACE_ROOT);
850
- res.json({ ok: true, root: WORKSPACE_ROOT, workspaceId: wsId, mode: "local", meta, port });
848
+ const meta = await detectProject(abs);
849
+ const port = await detectPort(abs);
850
+ res.json({ ok: true, root: abs, workspaceId: wsId, mode: "local", meta, port });
851
851
  });
852
852
 
853
853
  /**
@@ -862,7 +862,7 @@ app.post("/workspace/clone", async (req, res) => {
862
862
  if (!targetPath) return res.status(400).json({ ok: false, error: "targetPath is required" });
863
863
 
864
864
  const absTarget = path.resolve(targetPath);
865
- console.log(`📥 Clone request: ${gitUrl} -> ${absTarget}`);
865
+ console.log(` Clone request: ${gitUrl} -> ${absTarget}`);
866
866
 
867
867
  try {
868
868
  // Ensure parent directory exists
@@ -874,13 +874,13 @@ app.post("/workspace/clone", async (req, res) => {
874
874
  const alreadyCloned = await exists(gitDir);
875
875
 
876
876
  if (alreadyCloned) {
877
- console.log(`🔄 Repo already exists at ${absTarget}, running git pull...`);
877
+ console.log(` Repo already exists at ${absTarget}, running git pull...`);
878
878
  const { stdout } = await execAsync('git pull', { cwd: absTarget, timeout: 120000 });
879
- console.log(`✅ git pull: ${stdout.trim()}`);
879
+ console.log(` git pull: ${stdout.trim()}`);
880
880
  } else {
881
- console.log(`🔽 Running: git clone "${gitUrl}" "${absTarget}"`);
881
+ console.log(` Running: git clone "${gitUrl}" "${absTarget}"`);
882
882
  await execAsync(`git clone "${gitUrl}" "${absTarget}"`, { timeout: 300000 });
883
- console.log(`✅ Clone complete: ${absTarget}`);
883
+ console.log(` Clone complete: ${absTarget}`);
884
884
  }
885
885
 
886
886
  // Open the cloned workspace
@@ -889,7 +889,7 @@ app.post("/workspace/clone", async (req, res) => {
889
889
  try {
890
890
  await wsManager.open(wsId, absTarget);
891
891
  } catch (err) {
892
- console.warn(`⚠️ WorkspaceManager.open failed (non-fatal): ${err.message}`);
892
+ console.warn(` WorkspaceManager.open failed (non-fatal): ${err.message}`);
893
893
  }
894
894
 
895
895
  const meta = await detectProject(absTarget);
@@ -905,7 +905,7 @@ app.post("/workspace/clone", async (req, res) => {
905
905
  });
906
906
 
907
907
  } catch (err) {
908
- console.error(`❌ Clone failed: ${err.message}`);
908
+ console.error(` Clone failed: ${err.message}`);
909
909
  const hint = err.message.includes('Authentication') || err.message.includes('could not read')
910
910
  ? "Authentication failed. Ensure the repo is public or GitHub integration is configured."
911
911
  : err.message.includes('not found') || err.message.includes('does not exist')
@@ -938,7 +938,7 @@ app.get("/workspace/scan", async (req, res) => {
938
938
  }
939
939
  });
940
940
 
941
- /** Análise completa: language + framework */
941
+ /** Anlise completa: language + framework */
942
942
  app.get("/workspace/analyze", async (req, res) => {
943
943
  const wsRoot = resolveWorkspaceRoot(req);
944
944
  if (!wsRoot) return res.status(400).json({ error: "workspace not set" });
@@ -970,7 +970,7 @@ app.get("/workspace/analyze", async (req, res) => {
970
970
  }
971
971
  });
972
972
 
973
- /** conteúdo de arquivo específico */
973
+ /** L contedo de arquivo especfico */
974
974
  app.get("/workspace/file-content", async (req, res) => {
975
975
  const wsRoot = resolveWorkspaceRoot(req);
976
976
  if (!wsRoot) return res.status(400).json({ error: "workspace not set" });
@@ -987,7 +987,7 @@ app.get("/workspace/file-content", async (req, res) => {
987
987
  }
988
988
  });
989
989
 
990
- /** múltiplos arquivos */
990
+ /** L mltiplos arquivos */
991
991
  app.post("/workspace/batch-read", async (req, res) => {
992
992
  const wsRoot = resolveWorkspaceRoot(req);
993
993
  if (!wsRoot) return res.status(400).json({ error: "workspace not set" });
@@ -1007,7 +1007,7 @@ app.post("/workspace/batch-read", async (req, res) => {
1007
1007
  });
1008
1008
 
1009
1009
  // ============================================
1010
- // 🆕 FILE VALIDATION ENDPOINTS (Enhanced Analysis)
1010
+ // FILE VALIDATION ENDPOINTS (Enhanced Analysis)
1011
1011
  // ============================================
1012
1012
 
1013
1013
  /**
@@ -1029,7 +1029,7 @@ app.get("/workspace/file-exists", async (req, res) => {
1029
1029
  const fullPath = path.join(wsRoot, relativePath);
1030
1030
  const fileExists = await exists(fullPath);
1031
1031
 
1032
- console.log(`🔍 [file-exists] ${relativePath} -> ${fileExists ? 'EXISTS' : 'NOT FOUND'}`);
1032
+ console.log(` [file-exists] ${relativePath} -> ${fileExists ? 'EXISTS' : 'NOT FOUND'}`);
1033
1033
 
1034
1034
  res.json({
1035
1035
  ok: true,
@@ -1038,7 +1038,7 @@ app.get("/workspace/file-exists", async (req, res) => {
1038
1038
  fullPath: fullPath
1039
1039
  });
1040
1040
  } catch (err) {
1041
- console.error(`❌ [file-exists] Error:`, err.message);
1041
+ console.error(` [file-exists] Error:`, err.message);
1042
1042
  res.status(500).json({ ok: false, error: err.message });
1043
1043
  }
1044
1044
  });
@@ -1070,7 +1070,7 @@ app.post("/workspace/validate-paths", async (req, res) => {
1070
1070
  const allExist = results.every(r => r.exists);
1071
1071
  const missingPaths = results.filter(r => !r.exists).map(r => r.path);
1072
1072
 
1073
- console.log(`🔍 [validate-paths] Checked ${pathList.length} paths, ${missingPaths.length} missing`);
1073
+ console.log(` [validate-paths] Checked ${pathList.length} paths, ${missingPaths.length} missing`);
1074
1074
 
1075
1075
  res.json({
1076
1076
  ok: true,
@@ -1080,7 +1080,7 @@ app.post("/workspace/validate-paths", async (req, res) => {
1080
1080
  totalChecked: pathList.length
1081
1081
  });
1082
1082
  } catch (err) {
1083
- console.error(`❌ [validate-paths] Error:`, err.message);
1083
+ console.error(` [validate-paths] Error:`, err.message);
1084
1084
  res.status(500).json({ ok: false, error: err.message });
1085
1085
  }
1086
1086
  });
@@ -1103,7 +1103,7 @@ app.post("/workspace/search-file", async (req, res) => {
1103
1103
  }
1104
1104
 
1105
1105
  try {
1106
- console.log(`🔍 [search-file] Searching for: ${fileName}`);
1106
+ console.log(` [search-file] Searching for: ${fileName}`);
1107
1107
 
1108
1108
  const rawFiles = await listRecursive(wsRoot, {
1109
1109
  maxDepth: 15,
@@ -1111,7 +1111,7 @@ app.post("/workspace/search-file", async (req, res) => {
1111
1111
  extensions: null
1112
1112
  });
1113
1113
 
1114
- // 🆕 FIXED: Normalize files to string paths
1114
+ // FIXED: Normalize files to string paths
1115
1115
  // listRecursive may return strings OR objects like {path: 'xxx', name: 'yyy'}
1116
1116
  const allFiles = rawFiles.map(f => {
1117
1117
  if (typeof f === 'string') return f;
@@ -1120,7 +1120,7 @@ app.post("/workspace/search-file", async (req, res) => {
1120
1120
  return String(f);
1121
1121
  }).filter(f => f && typeof f === 'string');
1122
1122
 
1123
- console.log(`📁 [search-file] Scanning ${allFiles.length} files`);
1123
+ console.log(` [search-file] Scanning ${allFiles.length} files`);
1124
1124
 
1125
1125
  // Strategy 1: Exact path match
1126
1126
  let foundPath = allFiles.find(f => f.endsWith('/' + fileName) || f === fileName);
@@ -1150,14 +1150,14 @@ app.post("/workspace/search-file", async (req, res) => {
1150
1150
  }
1151
1151
 
1152
1152
  if (foundPath) {
1153
- console.log(`✅ [search-file] Found: ${foundPath}`);
1153
+ console.log(` [search-file] Found: ${foundPath}`);
1154
1154
  res.json({ ok: true, found: true, path: foundPath, fileName });
1155
1155
  } else {
1156
- console.log(`⚠️ [search-file] Not found: ${fileName}`);
1156
+ console.log(` [search-file] Not found: ${fileName}`);
1157
1157
  res.json({ ok: true, found: false, fileName, searchedFiles: allFiles.length });
1158
1158
  }
1159
1159
  } catch (err) {
1160
- console.error(`❌ [search-file] Error:`, err.message);
1160
+ console.error(` [search-file] Error:`, err.message);
1161
1161
  res.status(500).json({ ok: false, error: err.message });
1162
1162
  }
1163
1163
  });
@@ -1181,14 +1181,14 @@ app.post("/workspace/search-by-content", async (req, res) => {
1181
1181
  }
1182
1182
 
1183
1183
  try {
1184
- console.log(`🔍 [search-by-content] Searching for terms: ${terms.join(', ')}`);
1184
+ console.log(` [search-by-content] Searching for terms: ${terms.join(', ')}`);
1185
1185
 
1186
1186
  const rawFiles = await listRecursive(wsRoot, {
1187
1187
  maxDepth: 15,
1188
1188
  includeHidden: false
1189
1189
  });
1190
1190
 
1191
- // 🆕 FIXED: Normalize files to string paths
1191
+ // FIXED: Normalize files to string paths
1192
1192
  const allFiles = rawFiles.map(f => {
1193
1193
  if (typeof f === 'string') return f;
1194
1194
  if (f && typeof f === 'object' && f.path) return f.path;
@@ -1201,7 +1201,7 @@ app.post("/workspace/search-by-content", async (req, res) => {
1201
1201
  return extensions.some(ext => filePath.endsWith(ext));
1202
1202
  });
1203
1203
 
1204
- console.log(`📁 [search-by-content] Scanning ${filteredFiles.length} files`);
1204
+ console.log(` [search-by-content] Scanning ${filteredFiles.length} files`);
1205
1205
 
1206
1206
  const results = [];
1207
1207
 
@@ -1246,7 +1246,7 @@ app.post("/workspace/search-by-content", async (req, res) => {
1246
1246
  return true;
1247
1247
  }).slice(0, maxResults);
1248
1248
 
1249
- console.log(`✅ [search-by-content] Found ${dedupedResults.length} matching files`);
1249
+ console.log(` [search-by-content] Found ${dedupedResults.length} matching files`);
1250
1250
 
1251
1251
  res.json({
1252
1252
  ok: true,
@@ -1255,7 +1255,7 @@ app.post("/workspace/search-by-content", async (req, res) => {
1255
1255
  termsSearched: terms
1256
1256
  });
1257
1257
  } catch (err) {
1258
- console.error(`❌ [search-by-content] Error:`, err.message);
1258
+ console.error(` [search-by-content] Error:`, err.message);
1259
1259
  res.status(500).json({ ok: false, error: err.message });
1260
1260
  }
1261
1261
  });
@@ -1279,14 +1279,14 @@ app.post("/workspace/find-field-definition", async (req, res) => {
1279
1279
  }
1280
1280
 
1281
1281
  try {
1282
- console.log(`🔍 [find-field] Searching for field: ${fieldName}`);
1282
+ console.log(` [find-field] Searching for field: ${fieldName}`);
1283
1283
 
1284
1284
  const rawFiles = await listRecursive(wsRoot, {
1285
1285
  maxDepth: 15,
1286
1286
  includeHidden: false
1287
1287
  });
1288
1288
 
1289
- // 🆕 FIXED: Normalize files to string paths
1289
+ // FIXED: Normalize files to string paths
1290
1290
  const allFiles = rawFiles.map(f => {
1291
1291
  if (typeof f === 'string') return f;
1292
1292
  if (f && typeof f === 'object' && f.path) return f.path;
@@ -1358,7 +1358,7 @@ app.post("/workspace/find-field-definition", async (req, res) => {
1358
1358
  return 0;
1359
1359
  });
1360
1360
 
1361
- console.log(`✅ [find-field] Found ${definitions.length} definitions for '${fieldName}'`);
1361
+ console.log(` [find-field] Found ${definitions.length} definitions for '${fieldName}'`);
1362
1362
 
1363
1363
  res.json({
1364
1364
  ok: true,
@@ -1367,17 +1367,17 @@ app.post("/workspace/find-field-definition", async (req, res) => {
1367
1367
  totalSearched: targetFiles.length
1368
1368
  });
1369
1369
  } catch (err) {
1370
- console.error(`❌ [find-field] Error:`, err.message);
1370
+ console.error(` [find-field] Error:`, err.message);
1371
1371
  res.status(500).json({ ok: false, error: err.message });
1372
1372
  }
1373
1373
  });
1374
1374
 
1375
1375
 
1376
1376
  // ============================================
1377
- // 🆕 RUNTIME MANAGEMENT ENDPOINTS
1377
+ // RUNTIME MANAGEMENT ENDPOINTS
1378
1378
  // ============================================
1379
1379
 
1380
- /** Detecta serviços no workspace */
1380
+ /** Detecta servios no workspace */
1381
1381
  app.get("/workspace/services/detect", async (req, res) => {
1382
1382
  const wsRoot = resolveWorkspaceRoot(req);
1383
1383
  if (!wsRoot) return res.status(400).json({ error: "workspace not set" });
@@ -1414,12 +1414,12 @@ app.get("/workspace/services/detect", async (req, res) => {
1414
1414
  }
1415
1415
  });
1416
1416
 
1417
- /** Lista todos os serviços */
1417
+ /** Lista todos os servios */
1418
1418
  app.get("/workspace/services", (req, res) => {
1419
1419
  const wsRoot = resolveWorkspaceRoot(req);
1420
1420
  if (!wsRoot) return res.status(400).json({ error: "workspace not set" });
1421
1421
 
1422
- // Atualizar status dos serviços com info do ProcessManager
1422
+ // Atualizar status dos servios com info do ProcessManager
1423
1423
  const servicesWithStatus = DETECTED_SERVICES.map(service => {
1424
1424
  const status = processManager.getStatus(service.id);
1425
1425
  return {
@@ -1431,7 +1431,7 @@ app.get("/workspace/services", (req, res) => {
1431
1431
  res.json({ services: servicesWithStatus });
1432
1432
  });
1433
1433
 
1434
- /** Inicia um serviço */
1434
+ /** Inicia um servio */
1435
1435
  app.post("/workspace/services/:serviceId/start", async (req, res) => {
1436
1436
  const wsRoot = resolveWorkspaceRoot(req);
1437
1437
  if (!wsRoot) return res.status(400).json({ error: "workspace not set" });
@@ -1458,7 +1458,7 @@ app.post("/workspace/services/:serviceId/start", async (req, res) => {
1458
1458
  }
1459
1459
  });
1460
1460
 
1461
- /** Para um serviço */
1461
+ /** Para um servio */
1462
1462
  app.post("/workspace/services/:serviceId/stop", async (req, res) => {
1463
1463
  const wsRoot = resolveWorkspaceRoot(req);
1464
1464
  if (!wsRoot) return res.status(400).json({ error: "workspace not set" });
@@ -1473,7 +1473,7 @@ app.post("/workspace/services/:serviceId/stop", async (req, res) => {
1473
1473
  }
1474
1474
  });
1475
1475
 
1476
- /** Retorna status de um serviço */
1476
+ /** Retorna status de um servio */
1477
1477
  app.get("/workspace/services/:serviceId/status", (req, res) => {
1478
1478
  const wsRoot = resolveWorkspaceRoot(req);
1479
1479
  if (!wsRoot) return res.status(400).json({ error: "workspace not set" });
@@ -1484,7 +1484,7 @@ app.get("/workspace/services/:serviceId/status", (req, res) => {
1484
1484
  res.json({ serviceId, ...status });
1485
1485
  });
1486
1486
 
1487
- /** Retorna logs de um serviço */
1487
+ /** Retorna logs de um servio */
1488
1488
  app.get("/workspace/services/:serviceId/logs", (req, res) => {
1489
1489
  const wsRoot = resolveWorkspaceRoot(req);
1490
1490
  if (!wsRoot) return res.status(400).json({ error: "workspace not set" });
@@ -1527,7 +1527,7 @@ app.get("/workspace/services/:serviceId/logs/stream", (req, res) => {
1527
1527
 
1528
1528
  processManager.on("log", logHandler);
1529
1529
 
1530
- // Cleanup ao fechar conexão
1530
+ // Cleanup ao fechar conexo
1531
1531
  req.on("close", () => {
1532
1532
  processManager.off("log", logHandler);
1533
1533
  });
@@ -1572,7 +1572,7 @@ app.post("/workspace/write", async (req, res) => {
1572
1572
  });
1573
1573
 
1574
1574
  // ============================================
1575
- //CORRECTED: /workspace/patch endpoint
1575
+ // CORRECTED: /workspace/patch endpoint
1576
1576
  // ============================================
1577
1577
  app.post("/workspace/patch", async (req, res) => {
1578
1578
  const wsRoot = resolveWorkspaceRoot(req);
@@ -1581,10 +1581,10 @@ app.post("/workspace/patch", async (req, res) => {
1581
1581
  if (!diff) return res.status(400).json({ error: "diff is required" });
1582
1582
 
1583
1583
  try {
1584
- console.log(`📝 Applying patch for incident: ${incidentId || 'unknown'}`);
1584
+ console.log(` Applying patch for incident: ${incidentId || 'unknown'}`);
1585
1585
  const out = await applyUnifiedDiff(wsRoot, diff);
1586
1586
 
1587
- //CRITICAL FIX: Format response as expected by Gateway
1587
+ // CRITICAL FIX: Format response as expected by Gateway
1588
1588
  const response = {
1589
1589
  ok: true,
1590
1590
  filesModified: 1,
@@ -1596,7 +1596,7 @@ app.post("/workspace/patch", async (req, res) => {
1596
1596
  incidentId: incidentId
1597
1597
  };
1598
1598
 
1599
- console.log(`✅ Patch applied successfully:`, {
1599
+ console.log(` Patch applied successfully:`, {
1600
1600
  target: out.target,
1601
1601
  bytes: out.bytes,
1602
1602
  incident: incidentId
@@ -1604,7 +1604,7 @@ app.post("/workspace/patch", async (req, res) => {
1604
1604
 
1605
1605
  res.json(response);
1606
1606
  } catch (e) {
1607
- console.error(`❌ Patch failed:`, e.message);
1607
+ console.error(` Patch failed:`, e.message);
1608
1608
  res.status(400).json({
1609
1609
  ok: false,
1610
1610
  error: "patch failed",
@@ -1633,7 +1633,7 @@ app.post("/workspace/run", async (req, res) => {
1633
1633
  });
1634
1634
 
1635
1635
  // ============================================
1636
- // 🆕 TEST LOCAL ENDPOINTS
1636
+ // TEST LOCAL ENDPOINTS
1637
1637
  // ============================================
1638
1638
 
1639
1639
  /** Store test local state */
@@ -1644,11 +1644,11 @@ let TEST_LOCAL_STATE = {
1644
1644
  endpoints: [],
1645
1645
  config: null,
1646
1646
  testResults: [],
1647
- serverLogs: [] // Buffer circular de logs do servidor (últimos 1000)
1647
+ serverLogs: [] // Buffer circular de logs do servidor (ltimos 1000)
1648
1648
  };
1649
1649
 
1650
1650
  // ============================================
1651
- // 🆕 TEST LOCAL STATE ENDPOINTS (ADDED)
1651
+ // TEST LOCAL STATE ENDPOINTS (ADDED)
1652
1652
  // ============================================
1653
1653
 
1654
1654
  /**
@@ -1656,7 +1656,7 @@ let TEST_LOCAL_STATE = {
1656
1656
  * Returns current test local state with auto-detected port
1657
1657
  */
1658
1658
  app.get("/workspace/test-local/state", async (req, res) => {
1659
- console.log("📊 [TEST-LOCAL] Getting state:", TEST_LOCAL_STATE.status);
1659
+ console.log(" [TEST-LOCAL] Getting state:", TEST_LOCAL_STATE.status);
1660
1660
 
1661
1661
  // Auto-detect port if not set in config
1662
1662
  let port = TEST_LOCAL_STATE.config?.server?.port;
@@ -1695,7 +1695,7 @@ app.post("/workspace/test-local/compile", async (req, res) => {
1695
1695
  if (!wsRoot) return res.status(400).json({ error: "workspace not set" });
1696
1696
 
1697
1697
  try {
1698
- console.log("🔨 [TEST-LOCAL] Starting compilation...");
1698
+ console.log(" [TEST-LOCAL] Starting compilation...");
1699
1699
  TEST_LOCAL_STATE.status = "compiling";
1700
1700
 
1701
1701
  const meta = await detectProject(wsRoot);
@@ -1730,7 +1730,7 @@ app.post("/workspace/test-local/compile", async (req, res) => {
1730
1730
  duration: compileResult.duration
1731
1731
  };
1732
1732
 
1733
- console.log(" [TEST-LOCAL] Compilation successful");
1733
+ console.log(" [TEST-LOCAL] Compilation successful");
1734
1734
 
1735
1735
  res.json({
1736
1736
  ok: true,
@@ -1740,7 +1740,7 @@ app.post("/workspace/test-local/compile", async (req, res) => {
1740
1740
  stdout: compileResult.stdout
1741
1741
  });
1742
1742
  } catch (err) {
1743
- console.error(" [TEST-LOCAL] Compilation failed:", err.message);
1743
+ console.error(" [TEST-LOCAL] Compilation failed:", err.message);
1744
1744
  TEST_LOCAL_STATE.status = "error";
1745
1745
  res.status(500).json({ ok: false, error: err.message });
1746
1746
  }
@@ -1750,7 +1750,7 @@ app.post("/workspace/test-local/compile", async (req, res) => {
1750
1750
  * POST /workspace/test-local/start
1751
1751
  * Starts the local server with AUTO-HEALING
1752
1752
  *
1753
- * 🧠 UPDATED: Now uses AI Vibe Coding Engine for auto-healing
1753
+ * UPDATED: Now uses AI Vibe Coding Engine for auto-healing
1754
1754
  */
1755
1755
  app.post("/workspace/test-local/start", async (req, res) => {
1756
1756
  const wsRoot = resolveWorkspaceRoot(req);
@@ -1759,7 +1759,7 @@ app.post("/workspace/test-local/start", async (req, res) => {
1759
1759
  const { port } = req.body || {};
1760
1760
 
1761
1761
  try {
1762
- console.log(`\n🚀 [TEST-LOCAL] Starting server (SIMPLE MODE)...`);
1762
+ console.log(`\n [TEST-LOCAL] Starting server (SIMPLE MODE)...`);
1763
1763
  TEST_LOCAL_STATE.status = "starting";
1764
1764
 
1765
1765
  const meta = await detectProject(wsRoot);
@@ -1793,15 +1793,15 @@ app.post("/workspace/test-local/start", async (req, res) => {
1793
1793
  const command = 'java';
1794
1794
  const args = ['-jar', jarPath, `--server.port=${serverPort}`];
1795
1795
 
1796
- console.log(`🚀 Command: ${command} ${args.join(' ')}`);
1796
+ console.log(` Command: ${command} ${args.join(' ')}`);
1797
1797
 
1798
- // Env LIMPO - remover TODAS as variáveis Spring que podem interferir
1798
+ // Env LIMPO - remover TODAS as variveis Spring que podem interferir
1799
1799
  const cleanEnv = { ...process.env };
1800
1800
  delete cleanEnv.SPRING_PROFILES_ACTIVE;
1801
1801
  delete cleanEnv.SPRING_DATASOURCE_URL;
1802
1802
  delete cleanEnv.SPRING_DATASOURCE_USERNAME;
1803
1803
  delete cleanEnv.SPRING_DATASOURCE_PASSWORD;
1804
- // Remover qualquer variável que comece com SPRING_
1804
+ // Remover qualquer varivel que comece com SPRING_
1805
1805
  Object.keys(cleanEnv).forEach(key => {
1806
1806
  if (key.startsWith('SPRING_')) {
1807
1807
  delete cleanEnv[key];
@@ -1823,7 +1823,7 @@ app.post("/workspace/test-local/start", async (req, res) => {
1823
1823
  TEST_LOCAL_STATE.status = "running";
1824
1824
  TEST_LOCAL_STATE.config = { port: serverPort };
1825
1825
 
1826
- console.log(`✅ [TEST-LOCAL] Server started on port ${serverPort}`);
1826
+ console.log(` [TEST-LOCAL] Server started on port ${serverPort}`);
1827
1827
 
1828
1828
  res.json({
1829
1829
  ok: true,
@@ -1873,7 +1873,7 @@ app.post("/workspace/test-local/start", async (req, res) => {
1873
1873
  });
1874
1874
  }
1875
1875
  } catch (err) {
1876
- console.error(" [TEST-LOCAL] Server start failed:", err.message);
1876
+ console.error(" [TEST-LOCAL] Server start failed:", err.message);
1877
1877
  TEST_LOCAL_STATE.status = "error";
1878
1878
  res.status(500).json({ ok: false, error: err.message });
1879
1879
  }
@@ -1885,19 +1885,19 @@ app.post("/workspace/test-local/start", async (req, res) => {
1885
1885
  */
1886
1886
  app.post("/workspace/test-local/stop", async (req, res) => {
1887
1887
  try {
1888
- console.log("🛑 [TEST-LOCAL] Stopping server...");
1888
+ console.log(" [TEST-LOCAL] Stopping server...");
1889
1889
 
1890
1890
  await processManager.stop('test-local');
1891
1891
  TEST_LOCAL_STATE.status = "stopped";
1892
1892
 
1893
- console.log(" [TEST-LOCAL] Server stopped");
1893
+ console.log(" [TEST-LOCAL] Server stopped");
1894
1894
 
1895
1895
  res.json({
1896
1896
  ok: true,
1897
1897
  status: "stopped"
1898
1898
  });
1899
1899
  } catch (err) {
1900
- console.error(" [TEST-LOCAL] Server stop failed:", err.message);
1900
+ console.error(" [TEST-LOCAL] Server stop failed:", err.message);
1901
1901
  res.status(500).json({ ok: false, error: err.message });
1902
1902
  }
1903
1903
  });
@@ -1911,7 +1911,7 @@ app.get("/workspace/test-local/endpoints", async (req, res) => {
1911
1911
  if (!wsRoot) return res.status(400).json({ error: "workspace not set" });
1912
1912
 
1913
1913
  try {
1914
- console.log("📋 [TEST-LOCAL] Getting endpoints...");
1914
+ console.log(" [TEST-LOCAL] Getting endpoints...");
1915
1915
 
1916
1916
  // If endpoints are cached, return them
1917
1917
  if (TEST_LOCAL_STATE.endpoints && TEST_LOCAL_STATE.endpoints.length > 0) {
@@ -1934,7 +1934,7 @@ app.get("/workspace/test-local/endpoints", async (req, res) => {
1934
1934
 
1935
1935
  TEST_LOCAL_STATE.endpoints = payloadDocs.endpoints;
1936
1936
 
1937
- console.log(`✅ [TEST-LOCAL] Discovered ${payloadDocs.endpoints.length} endpoints`);
1937
+ console.log(` [TEST-LOCAL] Discovered ${payloadDocs.endpoints.length} endpoints`);
1938
1938
 
1939
1939
  res.json({
1940
1940
  ok: true,
@@ -1942,7 +1942,7 @@ app.get("/workspace/test-local/endpoints", async (req, res) => {
1942
1942
  cached: false
1943
1943
  });
1944
1944
  } catch (err) {
1945
- console.error(" [TEST-LOCAL] Failed to get endpoints:", err.message);
1945
+ console.error(" [TEST-LOCAL] Failed to get endpoints:", err.message);
1946
1946
  res.status(500).json({ ok: false, error: err.message });
1947
1947
  }
1948
1948
  });
@@ -1962,7 +1962,7 @@ app.post("/workspace/test-local/execute", async (req, res) => {
1962
1962
  const serverPort = port || TEST_LOCAL_STATE.config?.server?.port || 8080;
1963
1963
  const url = `http://localhost:${serverPort}${reqPath}`;
1964
1964
 
1965
- console.log(`🧪 [TEST-LOCAL] Executing: ${method} ${url}`);
1965
+ console.log(` [TEST-LOCAL] Executing: ${method} ${url}`);
1966
1966
 
1967
1967
  const startTime = Date.now();
1968
1968
 
@@ -2011,14 +2011,14 @@ app.post("/workspace/test-local/execute", async (req, res) => {
2011
2011
  TEST_LOCAL_STATE.testResults.shift();
2012
2012
  }
2013
2013
 
2014
- console.log(`✅ [TEST-LOCAL] Test result: ${response.status} (${duration}ms)`);
2014
+ console.log(` [TEST-LOCAL] Test result: ${response.status} (${duration}ms)`);
2015
2015
 
2016
2016
  res.json({
2017
2017
  ok: true,
2018
2018
  result
2019
2019
  });
2020
2020
  } catch (err) {
2021
- console.error(" [TEST-LOCAL] Test execution failed:", err.message);
2021
+ console.error(" [TEST-LOCAL] Test execution failed:", err.message);
2022
2022
  res.json({
2023
2023
  ok: false,
2024
2024
  error: err.message,
@@ -2037,7 +2037,7 @@ app.post("/workspace/test-local/execute", async (req, res) => {
2037
2037
  * Returns stored test results
2038
2038
  */
2039
2039
  app.get("/workspace/test-local/results", (req, res) => {
2040
- console.log("📊 [TEST-LOCAL] Getting test results...");
2040
+ console.log(" [TEST-LOCAL] Getting test results...");
2041
2041
 
2042
2042
  res.json({
2043
2043
  ok: true,
@@ -2051,7 +2051,7 @@ app.get("/workspace/test-local/results", (req, res) => {
2051
2051
  * Clears stored test results
2052
2052
  */
2053
2053
  app.post("/workspace/test-local/clear-results", (req, res) => {
2054
- console.log("🗑️ [TEST-LOCAL] Clearing test results...");
2054
+ console.log(" [TEST-LOCAL] Clearing test results...");
2055
2055
 
2056
2056
  TEST_LOCAL_STATE.testResults = [];
2057
2057
 
@@ -2068,7 +2068,7 @@ app.post("/workspace/test-local/clear-results", (req, res) => {
2068
2068
  app.get("/workspace/test-local/logs", (req, res) => {
2069
2069
  const limit = parseInt(req.query.limit) || 500;
2070
2070
 
2071
- console.log(`📋 [TEST-LOCAL] Getting logs (limit: ${limit})`);
2071
+ console.log(` [TEST-LOCAL] Getting logs (limit: ${limit})`);
2072
2072
 
2073
2073
  const logs = TEST_LOCAL_STATE.serverLogs.slice(-limit);
2074
2074
 
@@ -2087,7 +2087,7 @@ app.get("/workspace/controllers", async (req, res) => {
2087
2087
  if (!wsRoot) return res.status(400).json({ error: "workspace not set" });
2088
2088
 
2089
2089
  try {
2090
- console.log("🔍 [CONTROLLERS] Discovering controllers...");
2090
+ console.log(" [CONTROLLERS] Discovering controllers...");
2091
2091
 
2092
2092
  const scanner = new WorkspaceScanner(wsRoot);
2093
2093
  const structure = await scanner.scan();
@@ -2095,14 +2095,14 @@ app.get("/workspace/controllers", async (req, res) => {
2095
2095
  const controllerAnalyzer = new ControllerAnalyzer(wsRoot);
2096
2096
  const apiDocs = await controllerAnalyzer.generateApiDocs(structure.files);
2097
2097
 
2098
- console.log(`✅ [CONTROLLERS] Found ${apiDocs.totalEndpoints} endpoints in ${apiDocs.totalControllers} controllers`);
2098
+ console.log(` [CONTROLLERS] Found ${apiDocs.totalEndpoints} endpoints in ${apiDocs.totalControllers} controllers`);
2099
2099
 
2100
2100
  res.json({
2101
2101
  ok: true,
2102
2102
  ...apiDocs
2103
2103
  });
2104
2104
  } catch (err) {
2105
- console.error(" [CONTROLLERS] Failed:", err.message);
2105
+ console.error(" [CONTROLLERS] Failed:", err.message);
2106
2106
  res.status(500).json({ ok: false, error: err.message });
2107
2107
  }
2108
2108
  });
@@ -2113,7 +2113,7 @@ app.get("/workspace/dtos", async (req, res) => {
2113
2113
  if (!wsRoot) return res.status(400).json({ error: "workspace not set" });
2114
2114
 
2115
2115
  try {
2116
- console.log("📦 [DTOS] Analyzing DTOs...");
2116
+ console.log(" [DTOS] Analyzing DTOs...");
2117
2117
 
2118
2118
  const scanner = new WorkspaceScanner(wsRoot);
2119
2119
  const structure = await scanner.scan();
@@ -2124,14 +2124,14 @@ app.get("/workspace/dtos", async (req, res) => {
2124
2124
  const dtoAnalyzer = new DTOAnalyzer(wsRoot);
2125
2125
  const payloadDocs = await dtoAnalyzer.generatePayloadDocs(structure.files, apiDocs.endpoints);
2126
2126
 
2127
- console.log(`✅ [DTOS] Found ${payloadDocs.totalDtos} DTOs`);
2127
+ console.log(` [DTOS] Found ${payloadDocs.totalDtos} DTOs`);
2128
2128
 
2129
2129
  res.json({
2130
2130
  ok: true,
2131
2131
  ...payloadDocs
2132
2132
  });
2133
2133
  } catch (err) {
2134
- console.error(" [DTOS] Failed:", err.message);
2134
+ console.error(" [DTOS] Failed:", err.message);
2135
2135
  res.status(500).json({ ok: false, error: err.message });
2136
2136
  }
2137
2137
  });
@@ -2142,25 +2142,25 @@ app.get("/workspace/config", async (req, res) => {
2142
2142
  if (!wsRoot) return res.status(400).json({ error: "workspace not set" });
2143
2143
 
2144
2144
  try {
2145
- console.log("⚙️ [CONFIG] Analyzing configuration...");
2145
+ console.log(" [CONFIG] Analyzing configuration...");
2146
2146
 
2147
2147
  const configAnalyzer = new ConfigAnalyzer(wsRoot);
2148
2148
  const config = await configAnalyzer.analyze();
2149
2149
 
2150
- console.log(`✅ [CONFIG] Server port: ${config.server.port}`);
2150
+ console.log(` [CONFIG] Server port: ${config.server.port}`);
2151
2151
 
2152
2152
  res.json({
2153
2153
  ok: true,
2154
2154
  ...config
2155
2155
  });
2156
2156
  } catch (err) {
2157
- console.error(" [CONFIG] Failed:", err.message);
2157
+ console.error(" [CONFIG] Failed:", err.message);
2158
2158
  res.status(500).json({ ok: false, error: err.message });
2159
2159
  }
2160
2160
  });
2161
2161
 
2162
2162
  // ============================================
2163
- // 🆕 BACKUP & ROLLBACK ENDPOINTS (Sprint 1.3)
2163
+ // BACKUP & ROLLBACK ENDPOINTS (Sprint 1.3)
2164
2164
  // Added without modifying existing endpoints
2165
2165
  // ============================================
2166
2166
 
@@ -2223,7 +2223,7 @@ app.post("/workspace/safe-patch", async (req, res) => {
2223
2223
  const { diff, incidentId } = req.body || {};
2224
2224
  if (!diff) return res.status(400).json({ error: "diff is required" });
2225
2225
 
2226
- console.log(`🔧 Safe patch requested for incident: ${incidentId || 'unknown'}`);
2226
+ console.log(` Safe patch requested for incident: ${incidentId || 'unknown'}`);
2227
2227
 
2228
2228
  try {
2229
2229
  // 1. Validate diff
@@ -2238,7 +2238,7 @@ app.post("/workspace/safe-patch", async (req, res) => {
2238
2238
 
2239
2239
  // 2. Extract target files
2240
2240
  const targetFiles = extractTargetFiles(diff);
2241
- console.log(`📂 Target files: ${targetFiles.join(', ')}`);
2241
+ console.log(` Target files: ${targetFiles.join(', ')}`);
2242
2242
 
2243
2243
  // 3. Create backup
2244
2244
  const backupId = `backup-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
@@ -2269,23 +2269,23 @@ app.post("/workspace/safe-patch", async (req, res) => {
2269
2269
  }
2270
2270
  saveBackupIndex();
2271
2271
  } catch (e) {
2272
- console.warn(`⚠️ Could not persist backup to disk: ${e.message}`);
2272
+ console.warn(` Could not persist backup to disk: ${e.message}`);
2273
2273
  }
2274
2274
 
2275
2275
  // Cleanup old backups if exceeded max
2276
2276
  if (BACKUPS.size > MAX_BACKUPS) {
2277
2277
  const oldest = Array.from(BACKUPS.keys())[0];
2278
2278
  BACKUPS.delete(oldest);
2279
- console.log(`🗑️ Removed old backup: ${oldest}`);
2279
+ console.log(` Removed old backup: ${oldest}`);
2280
2280
  saveBackupIndex();
2281
2281
  }
2282
2282
 
2283
- console.log(`💾 Backup created: ${backupId} (${backupFiles.length} files)`);
2283
+ console.log(` Backup created: ${backupId} (${backupFiles.length} files)`);
2284
2284
 
2285
2285
  // 4. Apply patch
2286
2286
  try {
2287
2287
  const result = await applyUnifiedDiff(wsRoot, diff);
2288
- console.log(`✅ Patch applied successfully: ${result.target}`);
2288
+ console.log(` Patch applied successfully: ${result.target}`);
2289
2289
 
2290
2290
  res.json({
2291
2291
  ok: true,
@@ -2296,7 +2296,7 @@ app.post("/workspace/safe-patch", async (req, res) => {
2296
2296
  });
2297
2297
  } catch (patchError) {
2298
2298
  // 5. Rollback on failure
2299
- console.error(`❌ Patch failed, rolling back: ${patchError.message}`);
2299
+ console.error(` Patch failed, rolling back: ${patchError.message}`);
2300
2300
 
2301
2301
  for (const file of backupFiles) {
2302
2302
  const fullPath = path.join(wsRoot, file.path);
@@ -2313,7 +2313,7 @@ app.post("/workspace/safe-patch", async (req, res) => {
2313
2313
  });
2314
2314
  }
2315
2315
  } catch (err) {
2316
- console.error(`❌ Safe patch error: ${err.message}`);
2316
+ console.error(` Safe patch error: ${err.message}`);
2317
2317
  res.status(500).json({ ok: false, error: err.message });
2318
2318
  }
2319
2319
  });
@@ -2334,7 +2334,7 @@ app.post("/workspace/patch/dry-run", async (req, res) => {
2334
2334
  const { diff } = req.body || {};
2335
2335
  if (!diff) return res.status(400).json({ error: "diff is required" });
2336
2336
 
2337
- console.log(`🔍 Dry-run patch validation requested`);
2337
+ console.log(` Dry-run patch validation requested`);
2338
2338
 
2339
2339
  try {
2340
2340
  // 1. Validate diff format
@@ -2385,7 +2385,7 @@ app.post("/workspace/patch/dry-run", async (req, res) => {
2385
2385
  const allFilesExist = fileChecks.every(f => f.exists || diff.includes('--- /dev/null'));
2386
2386
  const missingFiles = fileChecks.filter(f => !f.exists && !diff.includes('--- /dev/null'));
2387
2387
 
2388
- console.log(`✅ Dry-run complete: ${targetFiles.length} files, ${hunkCount} hunks`);
2388
+ console.log(` Dry-run complete: ${targetFiles.length} files, ${hunkCount} hunks`);
2389
2389
 
2390
2390
  res.json({
2391
2391
  ok: true,
@@ -2398,7 +2398,7 @@ app.post("/workspace/patch/dry-run", async (req, res) => {
2398
2398
  warnings: missingFiles.length > 0 ? [`${missingFiles.length} file(s) not found`] : []
2399
2399
  });
2400
2400
  } catch (err) {
2401
- console.error(`❌ Dry-run error: ${err.message}`);
2401
+ console.error(` Dry-run error: ${err.message}`);
2402
2402
  res.status(500).json({ ok: false, error: err.message });
2403
2403
  }
2404
2404
  });
@@ -2466,7 +2466,7 @@ app.post("/workspace/backup", async (req, res) => {
2466
2466
  incidentId: incidentId || null
2467
2467
  });
2468
2468
 
2469
- console.log(`💾 Manual backup created: ${backupId}`);
2469
+ console.log(` Manual backup created: ${backupId}`);
2470
2470
 
2471
2471
  res.json({
2472
2472
  ok: true,
@@ -2475,7 +2475,7 @@ app.post("/workspace/backup", async (req, res) => {
2475
2475
  timestamp: new Date().toISOString()
2476
2476
  });
2477
2477
  } catch (err) {
2478
- console.error(`❌ Backup error: ${err.message}`);
2478
+ console.error(` Backup error: ${err.message}`);
2479
2479
  res.status(500).json({ ok: false, error: err.message });
2480
2480
  }
2481
2481
  });
@@ -2507,14 +2507,14 @@ app.post("/workspace/rollback", async (req, res) => {
2507
2507
  }
2508
2508
 
2509
2509
  try {
2510
- console.log(`♻️ Rolling back to backup: ${backupId}`);
2510
+ console.log(` Rolling back to backup: ${backupId}`);
2511
2511
 
2512
2512
  for (const file of backup.files) {
2513
2513
  const fullPath = path.join(wsRoot, file.path);
2514
2514
  await writeFile(fullPath, file.content, 'utf8');
2515
2515
  }
2516
2516
 
2517
- console.log(`✅ Rollback completed: ${backup.files.length} files restored`);
2517
+ console.log(` Rollback completed: ${backup.files.length} files restored`);
2518
2518
 
2519
2519
  res.json({
2520
2520
  ok: true,
@@ -2523,7 +2523,7 @@ app.post("/workspace/rollback", async (req, res) => {
2523
2523
  timestamp: backup.timestamp
2524
2524
  });
2525
2525
  } catch (err) {
2526
- console.error(`❌ Rollback error: ${err.message}`);
2526
+ console.error(` Rollback error: ${err.message}`);
2527
2527
  res.status(500).json({ ok: false, error: err.message });
2528
2528
  }
2529
2529
  });
@@ -2563,7 +2563,7 @@ app.delete("/workspace/backups/:backupId", (req, res) => {
2563
2563
  }
2564
2564
 
2565
2565
  BACKUPS.delete(backupId);
2566
- console.log(`🗑️ Backup deleted: ${backupId}`);
2566
+ console.log(` Backup deleted: ${backupId}`);
2567
2567
 
2568
2568
  res.json({
2569
2569
  ok: true,
@@ -2572,7 +2572,7 @@ app.delete("/workspace/backups/:backupId", (req, res) => {
2572
2572
  });
2573
2573
 
2574
2574
  // ============================================
2575
- // 📊 DIFF VIEWER ENDPOINT
2575
+ // DIFF VIEWER ENDPOINT
2576
2576
  // Returns before/after content for files modified by a patch
2577
2577
  // Used by the frontend diff viewer
2578
2578
  // ============================================
@@ -2622,7 +2622,7 @@ app.get("/workspace/diff/by-incident/:incidentId", async (req, res) => {
2622
2622
  }
2623
2623
 
2624
2624
  if (!matchedBackup) {
2625
- console.log(`⚠️ No backup found for incident ${incidentId}. Available backups:`, Array.from(BACKUPS.keys()));
2625
+ console.log(` No backup found for incident ${incidentId}. Available backups:`, Array.from(BACKUPS.keys()));
2626
2626
  return res.status(404).json({
2627
2627
  ok: false,
2628
2628
  error: "No backup found for this incident",
@@ -2631,7 +2631,7 @@ app.get("/workspace/diff/by-incident/:incidentId", async (req, res) => {
2631
2631
  });
2632
2632
  }
2633
2633
 
2634
- console.log(`📊 Found backup ${matchedBackupId} for incident ${incidentId}`);
2634
+ console.log(` Found backup ${matchedBackupId} for incident ${incidentId}`);
2635
2635
 
2636
2636
  // Reuse the diff logic
2637
2637
  try {
@@ -2668,7 +2668,7 @@ app.get("/workspace/diff/by-incident/:incidentId", async (req, res) => {
2668
2668
  files: diffs
2669
2669
  });
2670
2670
  } catch (err) {
2671
- console.error(`❌ Diff error: ${err.message}`);
2671
+ console.error(` Diff error: ${err.message}`);
2672
2672
  res.status(500).json({ ok: false, error: err.message });
2673
2673
  }
2674
2674
  });
@@ -2740,7 +2740,7 @@ app.get("/workspace/diff/:backupId", async (req, res) => {
2740
2740
  }
2741
2741
  }
2742
2742
 
2743
- console.log(`📊 Diff for ${backupId}: ${diffs.length} file(s) changed`);
2743
+ console.log(` Diff for ${backupId}: ${diffs.length} file(s) changed`);
2744
2744
 
2745
2745
  res.json({
2746
2746
  ok: true,
@@ -2752,13 +2752,13 @@ app.get("/workspace/diff/:backupId", async (req, res) => {
2752
2752
  files: diffs
2753
2753
  });
2754
2754
  } catch (err) {
2755
- console.error(`❌ Diff error: ${err.message}`);
2755
+ console.error(` Diff error: ${err.message}`);
2756
2756
  res.status(500).json({ ok: false, error: err.message });
2757
2757
  }
2758
2758
  });
2759
2759
 
2760
2760
  // ============================================
2761
- // 🆕 DETECT PORT ENDPOINT (Sprint 1.2)
2761
+ // DETECT PORT ENDPOINT (Sprint 1.2)
2762
2762
  // Multi-language port detection
2763
2763
  // ============================================
2764
2764
 
@@ -2785,7 +2785,7 @@ app.get("/workspace/detect-port", async (req, res) => {
2785
2785
 
2786
2786
  try {
2787
2787
  const fullPath = path.join(wsRoot, servicePath);
2788
- console.log(`🔍 Detecting port for service at: ${fullPath}`);
2788
+ console.log(` Detecting port for service at: ${fullPath}`);
2789
2789
 
2790
2790
  let port = null;
2791
2791
  let detectionMethod = null;
@@ -2820,7 +2820,7 @@ app.get("/workspace/detect-port", async (req, res) => {
2820
2820
  detectionMethod = 'global-detection';
2821
2821
  }
2822
2822
 
2823
- console.log(`✅ Detected port: ${port || 'default'} via ${detectionMethod}`);
2823
+ console.log(` Detected port: ${port || 'default'} via ${detectionMethod}`);
2824
2824
 
2825
2825
  res.json({
2826
2826
  ok: true,
@@ -2831,7 +2831,7 @@ app.get("/workspace/detect-port", async (req, res) => {
2831
2831
  servicePath: servicePath || '/'
2832
2832
  });
2833
2833
  } catch (err) {
2834
- console.error(' Error detecting port:', err.message);
2834
+ console.error(' Error detecting port:', err.message);
2835
2835
  res.status(500).json({ ok: false, error: err.message });
2836
2836
  }
2837
2837
  });
@@ -3042,7 +3042,7 @@ app.post("/workspace/test-local/prepare", async (req, res) => {
3042
3042
  if (!wsRoot) return res.status(400).json({ error: "workspace not set" });
3043
3043
 
3044
3044
  try {
3045
- console.log("🔧 [TEST-LOCAL] Preparing test environment...");
3045
+ console.log(" [TEST-LOCAL] Preparing test environment...");
3046
3046
  TEST_LOCAL_STATE.status = "compiling";
3047
3047
 
3048
3048
  // Step 1: Compile
@@ -3082,7 +3082,7 @@ app.post("/workspace/test-local/prepare", async (req, res) => {
3082
3082
  const config = await configAnalyzer.analyze();
3083
3083
  TEST_LOCAL_STATE.config = config;
3084
3084
 
3085
- console.log(`✅ [TEST-LOCAL] Prepared: ${payloadDocs.endpoints.length} endpoints discovered`);
3085
+ console.log(` [TEST-LOCAL] Prepared: ${payloadDocs.endpoints.length} endpoints discovered`);
3086
3086
 
3087
3087
  res.json({
3088
3088
  ok: true,
@@ -3105,7 +3105,7 @@ app.post("/workspace/test-local/prepare", async (req, res) => {
3105
3105
  endpoints: payloadDocs.endpoints
3106
3106
  });
3107
3107
  } catch (err) {
3108
- console.error(" [TEST-LOCAL] Prepare failed:", err.message);
3108
+ console.error(" [TEST-LOCAL] Prepare failed:", err.message);
3109
3109
  TEST_LOCAL_STATE.status = "error";
3110
3110
  res.status(500).json({ ok: false, error: err.message });
3111
3111
  }
@@ -3288,7 +3288,7 @@ app.get("/workspace/test-local/logs/stream", async (req, res) => {
3288
3288
  });
3289
3289
 
3290
3290
  // ============================================
3291
- // 🆕 AUTO-TRAINING ENDPOINTS
3291
+ // AUTO-TRAINING ENDPOINTS
3292
3292
  // Escanear e ler arquivos para treinamento AI
3293
3293
  // ============================================
3294
3294
 
@@ -3307,7 +3307,7 @@ app.post("/workspace/scan-files", async (req, res) => {
3307
3307
  });
3308
3308
  }
3309
3309
 
3310
- console.log(`📂 [SCAN-FILES] Scanning: ${workspaceRoot}`);
3310
+ console.log(` [SCAN-FILES] Scanning: ${workspaceRoot}`);
3311
3311
  console.log(` Extensions: ${includeExtensions.join(", ")}`);
3312
3312
  console.log(` Exclude: ${excludePatterns.join(", ")}`);
3313
3313
 
@@ -3316,7 +3316,7 @@ app.post("/workspace/scan-files", async (req, res) => {
3316
3316
  const fs = await import("fs/promises");
3317
3317
  const pathModule = await import("path");
3318
3318
 
3319
- // Padrões padrão para excluir
3319
+ // Padres padro para excluir
3320
3320
  const defaultExcludes = [
3321
3321
  "node_modules", "target", "build", "dist", ".git", ".idea",
3322
3322
  ".vscode", "__pycache__", ".gradle", "bin", "obj",
@@ -3324,7 +3324,7 @@ app.post("/workspace/scan-files", async (req, res) => {
3324
3324
  ];
3325
3325
  const allExcludes = [...defaultExcludes, ...excludePatterns];
3326
3326
 
3327
- // Função recursiva para escanear
3327
+ // Funo recursiva para escanear
3328
3328
  async function scanDir(dir, depth = 0) {
3329
3329
  if (depth > maxDepth || files.length >= maxFiles) return;
3330
3330
 
@@ -3351,7 +3351,7 @@ app.post("/workspace/scan-files", async (req, res) => {
3351
3351
  if (entry.isDirectory()) {
3352
3352
  await scanDir(fullPath, depth + 1);
3353
3353
  } else if (entry.isFile()) {
3354
- // Verificar extensão
3354
+ // Verificar extenso
3355
3355
  const ext = pathModule.extname(entry.name).toLowerCase();
3356
3356
  if (includeExtensions.length === 0 || includeExtensions.includes(ext)) {
3357
3357
  files.push(relativePath);
@@ -3359,13 +3359,13 @@ app.post("/workspace/scan-files", async (req, res) => {
3359
3359
  }
3360
3360
  }
3361
3361
  } catch (error) {
3362
- console.warn(`⚠️ Cannot read directory ${dir}: ${error.message}`);
3362
+ console.warn(` Cannot read directory ${dir}: ${error.message}`);
3363
3363
  }
3364
3364
  }
3365
3365
 
3366
3366
  await scanDir(workspaceRoot);
3367
3367
 
3368
- console.log(`✅ [SCAN-FILES] Found ${files.length} files`);
3368
+ console.log(` [SCAN-FILES] Found ${files.length} files`);
3369
3369
 
3370
3370
  res.json({
3371
3371
  success: true,
@@ -3375,7 +3375,7 @@ app.post("/workspace/scan-files", async (req, res) => {
3375
3375
  });
3376
3376
 
3377
3377
  } catch (error) {
3378
- console.error(`❌ [SCAN-FILES] Error: ${error.message}`);
3378
+ console.error(` [SCAN-FILES] Error: ${error.message}`);
3379
3379
  res.status(500).json({
3380
3380
  success: false,
3381
3381
  error: error.message,
@@ -3386,7 +3386,7 @@ app.post("/workspace/scan-files", async (req, res) => {
3386
3386
 
3387
3387
  /**
3388
3388
  * POST /workspace/read-file
3389
- * conteúdo de um arquivo específico
3389
+ * L contedo de um arquivo especfico
3390
3390
  */
3391
3391
  app.post("/workspace/read-file", async (req, res) => {
3392
3392
  const { root, filePath } = req.body;
@@ -3404,7 +3404,7 @@ app.post("/workspace/read-file", async (req, res) => {
3404
3404
  });
3405
3405
  }
3406
3406
 
3407
- console.log(`📄 [READ-FILE] Reading: ${filePath}`);
3407
+ console.log(` [READ-FILE] Reading: ${filePath}`);
3408
3408
 
3409
3409
  try {
3410
3410
  const fs = await import("fs/promises");
@@ -3435,7 +3435,7 @@ app.post("/workspace/read-file", async (req, res) => {
3435
3435
  });
3436
3436
 
3437
3437
  } catch (error) {
3438
- console.error(`❌ [READ-FILE] Error: ${error.message}`);
3438
+ console.error(` [READ-FILE] Error: ${error.message}`);
3439
3439
  res.status(404).json({
3440
3440
  success: false,
3441
3441
  error: error.message,
@@ -3446,7 +3446,7 @@ app.post("/workspace/read-file", async (req, res) => {
3446
3446
 
3447
3447
  /**
3448
3448
  * POST /workspace/read-files
3449
- * múltiplos arquivos de uma vez (batch)
3449
+ * L mltiplos arquivos de uma vez (batch)
3450
3450
  */
3451
3451
  app.post("/workspace/read-files", async (req, res) => {
3452
3452
  const { root, filePaths } = req.body;
@@ -3464,7 +3464,7 @@ app.post("/workspace/read-files", async (req, res) => {
3464
3464
  });
3465
3465
  }
3466
3466
 
3467
- console.log(`📚 [READ-FILES] Reading ${filePaths.length} files`);
3467
+ console.log(` [READ-FILES] Reading ${filePaths.length} files`);
3468
3468
 
3469
3469
  try {
3470
3470
  const fs = await import("fs/promises");
@@ -3491,7 +3491,7 @@ app.post("/workspace/read-files", async (req, res) => {
3491
3491
  }
3492
3492
  }
3493
3493
 
3494
- console.log(`✅ [READ-FILES] Read ${Object.keys(files).length} files, ${errors.length} errors`);
3494
+ console.log(` [READ-FILES] Read ${Object.keys(files).length} files, ${errors.length} errors`);
3495
3495
 
3496
3496
  res.json({
3497
3497
  success: true,
@@ -3501,7 +3501,7 @@ app.post("/workspace/read-files", async (req, res) => {
3501
3501
  });
3502
3502
 
3503
3503
  } catch (error) {
3504
- console.error(`❌ [READ-FILES] Error: ${error.message}`);
3504
+ console.error(` [READ-FILES] Error: ${error.message}`);
3505
3505
  res.status(500).json({
3506
3506
  success: false,
3507
3507
  error: error.message
@@ -3510,7 +3510,7 @@ app.post("/workspace/read-files", async (req, res) => {
3510
3510
  });
3511
3511
 
3512
3512
  // ============================================
3513
- // 🆕 SYSTEM FOLDER PICKER ENDPOINT
3513
+ // SYSTEM FOLDER PICKER ENDPOINT
3514
3514
  // Abre file picker nativo do SO (Windows/Mac/Linux)
3515
3515
  // ============================================
3516
3516
 
@@ -3519,7 +3519,7 @@ app.post("/workspace/read-files", async (req, res) => {
3519
3519
  * Abre o file picker nativo do sistema operacional
3520
3520
  */
3521
3521
  app.get("/system/folder-picker", async (req, res) => {
3522
- console.log(`📂 [FOLDER-PICKER] Opening native folder picker...`);
3522
+ console.log(` [FOLDER-PICKER] Opening native folder picker...`);
3523
3523
 
3524
3524
  try {
3525
3525
  const platform = process.platform;
@@ -3532,7 +3532,7 @@ app.get("/system/folder-picker", async (req, res) => {
3532
3532
  const { stdout } = await execAsync(script);
3533
3533
  selectedPath = stdout.trim();
3534
3534
  } catch (error) {
3535
- // Usuário cancelou
3535
+ // Usurio cancelou
3536
3536
  if (error.code === 1) {
3537
3537
  return res.json({
3538
3538
  success: true,
@@ -3602,7 +3602,7 @@ app.get("/system/folder-picker", async (req, res) => {
3602
3602
  selectedPath = selectedPath.slice(0, -1);
3603
3603
  }
3604
3604
 
3605
- console.log(`✅ [FOLDER-PICKER] Selected: ${selectedPath}`);
3605
+ console.log(` [FOLDER-PICKER] Selected: ${selectedPath}`);
3606
3606
 
3607
3607
  res.json({
3608
3608
  success: true,
@@ -3611,7 +3611,7 @@ app.get("/system/folder-picker", async (req, res) => {
3611
3611
  });
3612
3612
 
3613
3613
  } catch (error) {
3614
- console.error(`❌ [FOLDER-PICKER] Error:`, error.message);
3614
+ console.error(` [FOLDER-PICKER] Error:`, error.message);
3615
3615
  res.status(500).json({
3616
3616
  success: false,
3617
3617
  error: error.message,
@@ -3623,7 +3623,7 @@ app.get("/system/folder-picker", async (req, res) => {
3623
3623
 
3624
3624
  /**
3625
3625
  * GET /system/info
3626
- * Retorna informações do sistema
3626
+ * Retorna informaes do sistema
3627
3627
  */
3628
3628
  app.get("/system/info", (req, res) => {
3629
3629
  res.json({
@@ -3636,7 +3636,7 @@ app.get("/system/info", (req, res) => {
3636
3636
  });
3637
3637
 
3638
3638
  // ============================================
3639
- // 🆕 API DOCS ENDPOINT
3639
+ // API DOCS ENDPOINT
3640
3640
  // Retorna endpoints detectados das controllers
3641
3641
  // ============================================
3642
3642
 
@@ -3653,7 +3653,7 @@ app.get("/workspace/api-docs", async (req, res) => {
3653
3653
  });
3654
3654
  }
3655
3655
 
3656
- console.log(`📚 [API-DOCS] Analyzing controllers in ${wsRoot}`);
3656
+ console.log(` [API-DOCS] Analyzing controllers in ${wsRoot}`);
3657
3657
 
3658
3658
  try {
3659
3659
  // Primeiro, escanear arquivos do workspace
@@ -3692,13 +3692,13 @@ app.get("/workspace/api-docs", async (req, res) => {
3692
3692
 
3693
3693
  await scanDir(wsRoot);
3694
3694
 
3695
- console.log(`📁 [API-DOCS] Found ${files.length} Java files`);
3695
+ console.log(` [API-DOCS] Found ${files.length} Java files`);
3696
3696
 
3697
3697
  // Agora analisar os controllers
3698
3698
  const controllerAnalyzer = new ControllerAnalyzer(wsRoot);
3699
3699
  const apiDocs = await controllerAnalyzer.generateApiDocs(files);
3700
3700
 
3701
- console.log(`✅ [API-DOCS] Found ${apiDocs.totalEndpoints} endpoints in ${apiDocs.totalControllers} controllers`);
3701
+ console.log(` [API-DOCS] Found ${apiDocs.totalEndpoints} endpoints in ${apiDocs.totalControllers} controllers`);
3702
3702
 
3703
3703
  res.json({
3704
3704
  success: true,
@@ -3710,7 +3710,7 @@ app.get("/workspace/api-docs", async (req, res) => {
3710
3710
  });
3711
3711
 
3712
3712
  } catch (error) {
3713
- console.error(`❌ [API-DOCS] Error:`, error.message);
3713
+ console.error(` [API-DOCS] Error:`, error.message);
3714
3714
 
3715
3715
  res.json({
3716
3716
  success: false,
@@ -3725,7 +3725,7 @@ app.get("/workspace/api-docs", async (req, res) => {
3725
3725
 
3726
3726
  /**
3727
3727
  * GET /workspace/api-docs/:controller
3728
- * Retorna endpoints de uma controller específica
3728
+ * Retorna endpoints de uma controller especfica
3729
3729
  */
3730
3730
  app.get("/workspace/api-docs/:controller", async (req, res) => {
3731
3731
  const wsRoot = resolveWorkspaceRoot(req);
@@ -3737,7 +3737,7 @@ app.get("/workspace/api-docs/:controller", async (req, res) => {
3737
3737
  }
3738
3738
 
3739
3739
  const { controller } = req.params;
3740
- console.log(`📚 [API-DOCS] Getting endpoints for controller: ${controller}`);
3740
+ console.log(` [API-DOCS] Getting endpoints for controller: ${controller}`);
3741
3741
 
3742
3742
  try {
3743
3743
  // Primeiro, escanear arquivos do workspace
@@ -3812,7 +3812,7 @@ app.get("/workspace/api-docs/:controller", async (req, res) => {
3812
3812
  });
3813
3813
 
3814
3814
  } catch (error) {
3815
- console.error(`❌ [API-DOCS] Error:`, error.message);
3815
+ console.error(` [API-DOCS] Error:`, error.message);
3816
3816
  res.status(500).json({
3817
3817
  success: false,
3818
3818
  error: error.message
@@ -3821,7 +3821,7 @@ app.get("/workspace/api-docs/:controller", async (req, res) => {
3821
3821
  });
3822
3822
 
3823
3823
  // ============================================
3824
- // 🧠 AI ENGINE ENDPOINTS
3824
+ // AI ENGINE ENDPOINTS
3825
3825
  // ============================================
3826
3826
 
3827
3827
  /**
@@ -3848,7 +3848,7 @@ app.post("/ai-engine/toggle", (req, res) => {
3848
3848
 
3849
3849
  /**
3850
3850
  * POST /ai-engine/clear-history
3851
- * Limpa histórico de erros e fixes
3851
+ * Limpa histrico de erros e fixes
3852
3852
  */
3853
3853
  app.post("/ai-engine/clear-history", (req, res) => {
3854
3854
  if (aiEngine) {
@@ -3861,7 +3861,7 @@ app.post("/ai-engine/clear-history", (req, res) => {
3861
3861
 
3862
3862
  /**
3863
3863
  * GET /ai-engine/errors
3864
- * Retorna histórico de erros
3864
+ * Retorna histrico de erros
3865
3865
  */
3866
3866
  app.get("/ai-engine/errors", (req, res) => {
3867
3867
  const { limit = 50 } = req.query;
@@ -3878,7 +3878,7 @@ app.get("/ai-engine/errors", (req, res) => {
3878
3878
 
3879
3879
  /**
3880
3880
  * GET /ai-engine/fixes
3881
- * Retorna histórico de fixes
3881
+ * Retorna histrico de fixes
3882
3882
  */
3883
3883
  app.get("/ai-engine/fixes", (req, res) => {
3884
3884
  if (aiEngine) {
@@ -3894,7 +3894,7 @@ app.get("/ai-engine/fixes", (req, res) => {
3894
3894
 
3895
3895
  /**
3896
3896
  * GET /workspace/smart-config
3897
- * Recolhe ficheiros de configuração para análise AI
3897
+ * Recolhe ficheiros de configurao para anlise AI
3898
3898
  */
3899
3899
  app.get("/workspace/smart-config", async (req, res) => {
3900
3900
  const wsRoot = resolveWorkspaceRoot(req);
@@ -3902,7 +3902,7 @@ app.get("/workspace/smart-config", async (req, res) => {
3902
3902
  return res.status(400).json({ error: "workspace not set" });
3903
3903
  }
3904
3904
 
3905
- console.log("🧠 [SMART-CONFIG] Collecting configuration files...");
3905
+ console.log(" [SMART-CONFIG] Collecting configuration files...");
3906
3906
 
3907
3907
  try {
3908
3908
  const configPatterns = [
@@ -3936,14 +3936,14 @@ app.get("/workspace/smart-config", async (req, res) => {
3936
3936
  : content,
3937
3937
  size: content.length
3938
3938
  });
3939
- console.log(`📄 Found: ${pattern}`);
3939
+ console.log(` Found: ${pattern}`);
3940
3940
  } catch (err) {
3941
- console.error(`❌ Error reading ${pattern}: ${err.message}`);
3941
+ console.error(` Error reading ${pattern}: ${err.message}`);
3942
3942
  }
3943
3943
  }
3944
3944
  }
3945
3945
 
3946
- // Detectar profiles disponíveis
3946
+ // Detectar profiles disponveis
3947
3947
  const availableProfiles = [];
3948
3948
  const resourcesDir = path.join(wsRoot, 'src/main/resources');
3949
3949
  if (fs.existsSync(resourcesDir)) {
@@ -3954,7 +3954,7 @@ app.get("/workspace/smart-config", async (req, res) => {
3954
3954
  });
3955
3955
  }
3956
3956
 
3957
- console.log(`✅ Collected ${collectedFiles.length} files, profiles: ${availableProfiles.join(', ')}`);
3957
+ console.log(` Collected ${collectedFiles.length} files, profiles: ${availableProfiles.join(', ')}`);
3958
3958
 
3959
3959
  res.json({
3960
3960
  ok: true,
@@ -3968,7 +3968,7 @@ app.get("/workspace/smart-config", async (req, res) => {
3968
3968
  });
3969
3969
 
3970
3970
  } catch (err) {
3971
- console.error(" [SMART-CONFIG] Error:", err.message);
3971
+ console.error(" [SMART-CONFIG] Error:", err.message);
3972
3972
  res.status(500).json({ ok: false, error: err.message });
3973
3973
  }
3974
3974
  });
@@ -3979,7 +3979,7 @@ app.get("/workspace/smart-config", async (req, res) => {
3979
3979
  */
3980
3980
  app.post("/workspace/test-local/restart", async (req, res) => {
3981
3981
  try {
3982
- console.log("🔄 [TEST-LOCAL] Restarting server...");
3982
+ console.log(" [TEST-LOCAL] Restarting server...");
3983
3983
 
3984
3984
  // Stop
3985
3985
  await processManager.stop('test-local');
@@ -3987,7 +3987,7 @@ app.post("/workspace/test-local/restart", async (req, res) => {
3987
3987
  // Esperar um pouco
3988
3988
  await new Promise(r => setTimeout(r, 2000));
3989
3989
 
3990
- // Usar última config que funcionou
3990
+ // Usar ltima config que funcionou
3991
3991
  const config = (aiEngine && aiEngine.lastSuccessfulConfig) || TEST_LOCAL_STATE.config;
3992
3992
 
3993
3993
  if (!config) {
@@ -4024,13 +4024,13 @@ app.post("/workspace/test-local/restart", async (req, res) => {
4024
4024
  }
4025
4025
 
4026
4026
  } catch (err) {
4027
- console.error(" [TEST-LOCAL] Restart failed:", err.message);
4027
+ console.error(" [TEST-LOCAL] Restart failed:", err.message);
4028
4028
  res.status(500).json({ ok: false, error: err.message });
4029
4029
  }
4030
4030
  });
4031
4031
 
4032
4032
  // ============================================
4033
- // 🤖 AGENTIC TOOLS ENDPOINTS
4033
+ // AGENTIC TOOLS ENDPOINTS
4034
4034
  // Used by the agentic Claude loop for autonomous debugging
4035
4035
  // ============================================
4036
4036
 
@@ -4058,7 +4058,7 @@ app.post("/workspace/search", async (req, res) => {
4058
4058
  return res.status(400).json({ ok: false, error: "pattern is required" });
4059
4059
  }
4060
4060
 
4061
- console.log(`🔍 [workspace/search] pattern="${pattern}" filter="${fileFilter || '*'}"`);
4061
+ console.log(` [workspace/search] pattern="${pattern}" filter="${fileFilter || '*'}"`);
4062
4062
 
4063
4063
  try {
4064
4064
  const { execSync } = await import('child_process');
@@ -4116,7 +4116,7 @@ app.post("/workspace/search", async (req, res) => {
4116
4116
  .join('\n');
4117
4117
 
4118
4118
  const count = results.split('\n').filter(l => l.trim()).length;
4119
- console.log(`Found ${count} matches`);
4119
+ console.log(` Found ${count} matches`);
4120
4120
 
4121
4121
  res.json({
4122
4122
  ok: true,
@@ -4124,7 +4124,7 @@ app.post("/workspace/search", async (req, res) => {
4124
4124
  count: count
4125
4125
  });
4126
4126
  } catch (err) {
4127
- console.error(`❌ [workspace/search] Error:`, err.message);
4127
+ console.error(` [workspace/search] Error:`, err.message);
4128
4128
  res.status(500).json({ ok: false, error: err.message });
4129
4129
  }
4130
4130
  });
@@ -4164,14 +4164,14 @@ app.post("/workspace/exec", async (req, res) => {
4164
4164
  ];
4165
4165
  const lowerCmd = command.toLowerCase().trim();
4166
4166
  if (dangerous.some(d => lowerCmd.includes(d))) {
4167
- console.warn(`⚠️ [workspace/exec] BLOCKED dangerous command: ${command}`);
4167
+ console.warn(` [workspace/exec] BLOCKED dangerous command: ${command}`);
4168
4168
  return res.status(403).json({
4169
4169
  ok: false,
4170
4170
  error: "Command blocked for security reasons"
4171
4171
  });
4172
4172
  }
4173
4173
 
4174
- console.log(`⚡ [workspace/exec] Running: ${command.substring(0, 120)}...`);
4174
+ console.log(` [workspace/exec] Running: ${command.substring(0, 120)}...`);
4175
4175
 
4176
4176
  try {
4177
4177
  const { exec: execCb } = await import('child_process');
@@ -4185,7 +4185,7 @@ app.post("/workspace/exec", async (req, res) => {
4185
4185
  env: { ...process.env, FORCE_COLOR: '0' }
4186
4186
  });
4187
4187
 
4188
- console.log(`Command completed (stdout: ${result.stdout.length} chars)`);
4188
+ console.log(` Command completed (stdout: ${result.stdout.length} chars)`);
4189
4189
 
4190
4190
  res.json({
4191
4191
  ok: true,
@@ -4194,7 +4194,7 @@ app.post("/workspace/exec", async (req, res) => {
4194
4194
  exitCode: 0
4195
4195
  });
4196
4196
  } catch (err) {
4197
- console.error(`Command failed (exit: ${err.code}):`, err.message?.substring(0, 200));
4197
+ console.error(` Command failed (exit: ${err.code}):`, err.message?.substring(0, 200));
4198
4198
  res.json({
4199
4199
  ok: false,
4200
4200
  stdout: err.stdout || '',
@@ -4205,7 +4205,7 @@ app.post("/workspace/exec", async (req, res) => {
4205
4205
  });
4206
4206
 
4207
4207
  // ============================================
4208
- // 🧪 ENDPOINT TESTING
4208
+ // ENDPOINT TESTING
4209
4209
  // Execute curl-like requests and capture full request/response
4210
4210
  // ============================================
4211
4211
 
@@ -4227,7 +4227,7 @@ app.post("/workspace/test-endpoint", async (req, res) => {
4227
4227
  return res.status(403).json({ error: "Only localhost URLs allowed for security" });
4228
4228
  }
4229
4229
 
4230
- console.log(`🧪 Testing: ${method} ${url} (${testName || 'unnamed'})`);
4230
+ console.log(` Testing: ${method} ${url} (${testName || 'unnamed'})`);
4231
4231
 
4232
4232
  const startTime = Date.now();
4233
4233
 
@@ -4277,12 +4277,12 @@ app.post("/workspace/test-endpoint", async (req, res) => {
4277
4277
  : response.status >= 200 && response.status < 400
4278
4278
  };
4279
4279
 
4280
- console.log(`${response.status} ${response.statusText} (${durationMs}ms) ${result.passed ? '' : ''}`);
4280
+ console.log(` ${response.status} ${response.statusText} (${durationMs}ms) ${result.passed ? '' : ''}`);
4281
4281
  res.json(result);
4282
4282
 
4283
4283
  } catch (err) {
4284
4284
  const durationMs = Date.now() - startTime;
4285
- console.error(` → ❌ Failed: ${err.message} (${durationMs}ms)`);
4285
+ console.error(` Failed: ${err.message} (${durationMs}ms)`);
4286
4286
 
4287
4287
  res.json({
4288
4288
  ok: false,
@@ -4299,7 +4299,7 @@ app.post("/workspace/test-endpoint", async (req, res) => {
4299
4299
  });
4300
4300
 
4301
4301
  // ============================================
4302
- // 🔀 GIT INTEGRATION
4302
+ // GIT INTEGRATION
4303
4303
  // Create branch, commit, push for auto-fix PRs
4304
4304
  // ============================================
4305
4305
 
@@ -4353,7 +4353,7 @@ app.post("/workspace/git/create-fix-branch", async (req, res) => {
4353
4353
  try {
4354
4354
  const stashResult = execSync('git stash --include-untracked 2>&1', opts).trim();
4355
4355
  hadStash = !stashResult.includes('No local changes');
4356
- if (hadStash) console.log('📦 Stashed uncommitted changes');
4356
+ if (hadStash) console.log(' Stashed uncommitted changes');
4357
4357
  } catch {}
4358
4358
 
4359
4359
  // 4. Create and checkout new branch (with unique name if exists)
@@ -4361,7 +4361,7 @@ app.post("/workspace/git/create-fix-branch", async (req, res) => {
4361
4361
  try {
4362
4362
  execSync(`git checkout -b ${finalBranchName}`, opts);
4363
4363
  } catch (e) {
4364
- // Branch already existsadd timestamp suffix
4364
+ // Branch already exists add timestamp suffix
4365
4365
  finalBranchName = `${branchName}-${Date.now() % 100000}`;
4366
4366
  try {
4367
4367
  execSync(`git checkout -b ${finalBranchName}`, opts);
@@ -4377,7 +4377,7 @@ app.post("/workspace/git/create-fix-branch", async (req, res) => {
4377
4377
  try {
4378
4378
  execSync('git stash pop', opts);
4379
4379
  } catch (e) {
4380
- console.warn('⚠️ Stash pop had conflicts, trying apply:', e.message);
4380
+ console.warn(' Stash pop had conflicts, trying apply:', e.message);
4381
4381
  try { execSync('git stash apply', opts); } catch {}
4382
4382
  }
4383
4383
  }
@@ -4406,7 +4406,7 @@ app.post("/workspace/git/create-fix-branch", async (req, res) => {
4406
4406
  let pushResult = '';
4407
4407
  let pushed = false;
4408
4408
 
4409
- console.log(`🔑 Git pushgitToken provided: ${!!gitToken}, repoUrl provided: ${!!repoUrl}`);
4409
+ console.log(` Git push gitToken provided: ${!!gitToken}, repoUrl provided: ${!!repoUrl}`);
4410
4410
 
4411
4411
  // If gitToken provided, set up authenticated remote URL for push
4412
4412
  if (gitToken) {
@@ -4415,14 +4415,14 @@ app.post("/workspace/git/create-fix-branch", async (req, res) => {
4415
4415
  try {
4416
4416
  remoteUrlRaw = execSync('git remote get-url origin 2>/dev/null', opts).trim();
4417
4417
  } catch {
4418
- // No remote configureduse repoUrl from integration if available
4418
+ // No remote configured use repoUrl from integration if available
4419
4419
  if (repoUrl) {
4420
4420
  remoteUrlRaw = repoUrl;
4421
- console.log(`📍 No git remote, using repoUrl from integration: ${repoUrl}`);
4421
+ console.log(` No git remote, using repoUrl from integration: ${repoUrl}`);
4422
4422
  }
4423
4423
  }
4424
4424
 
4425
- console.log(`📍 Remote URL: ${remoteUrlRaw.replace(gitToken, '***')}`);
4425
+ console.log(` Remote URL: ${remoteUrlRaw.replace(gitToken, '***')}`);
4426
4426
  let authenticatedUrl = '';
4427
4427
 
4428
4428
  if (remoteUrlRaw.includes('github.com')) {
@@ -4431,7 +4431,7 @@ app.post("/workspace/git/create-fix-branch", async (req, res) => {
4431
4431
  .replace(/^git@github\.com:/, '')
4432
4432
  .replace(/\.git$/, '');
4433
4433
  authenticatedUrl = `https://x-access-token:${gitToken}@github.com/${repoPath}.git`;
4434
- console.log(`📍 GitHub auth URL: https://x-access-token:***@github.com/${repoPath}.git`);
4434
+ console.log(` GitHub auth URL: https://x-access-token:***@github.com/${repoPath}.git`);
4435
4435
  } else if (remoteUrlRaw.includes('gitlab.com') || remoteUrlRaw.includes('gitlab')) {
4436
4436
  const repoPath = remoteUrlRaw
4437
4437
  .replace(/^https?:\/\/(.*@)?[^\/]+\//, '')
@@ -4439,47 +4439,47 @@ app.post("/workspace/git/create-fix-branch", async (req, res) => {
4439
4439
  .replace(/\.git$/, '');
4440
4440
  const host = remoteUrlRaw.match(/https?:\/\/([^\/]+)/)?.[1] || 'gitlab.com';
4441
4441
  authenticatedUrl = `https://oauth2:${gitToken}@${host}/${repoPath}.git`;
4442
- console.log(`📍 GitLab auth URL: https://oauth2:***@${host}/${repoPath}.git`);
4442
+ console.log(` GitLab auth URL: https://oauth2:***@${host}/${repoPath}.git`);
4443
4443
  } else if (remoteUrlRaw.includes('bitbucket.org') || remoteUrlRaw.includes('bitbucket')) {
4444
4444
  const repoPath = remoteUrlRaw
4445
4445
  .replace(/^https?:\/\/(.*@)?bitbucket\.org\//, '')
4446
4446
  .replace(/^git@bitbucket\.org:/, '')
4447
4447
  .replace(/\.git$/, '');
4448
- //FIXED: Bitbucket App Password authtoken está no formato "username:appPassword"
4449
- // x-token-auth não funciona; Basic Auth via URL é o método correcto
4448
+ // FIXED: Bitbucket App Password auth token j est no formato "username:appPassword"
4449
+ // x-token-auth no funciona; Basic Auth via URL o mtodo correcto
4450
4450
  authenticatedUrl = `https://${gitToken}@bitbucket.org/${repoPath}.git`;
4451
4451
  } else if (remoteUrlRaw) {
4452
- // Unknown providertry generic https with token
4452
+ // Unknown provider try generic https with token
4453
4453
  const urlObj = new URL(remoteUrlRaw.replace(/^git@([^:]+):/, 'https://$1/'));
4454
4454
  authenticatedUrl = `https://oauth2:${gitToken}@${urlObj.host}${urlObj.pathname}`;
4455
4455
  if (!authenticatedUrl.endsWith('.git')) authenticatedUrl += '.git';
4456
- console.log(`📍 Generic auth URL for ${urlObj.host}`);
4456
+ console.log(` Generic auth URL for ${urlObj.host}`);
4457
4457
  }
4458
4458
 
4459
4459
  if (authenticatedUrl) {
4460
- console.log(`🚀 Pushing ${finalBranchName} with token auth...`);
4460
+ console.log(` Pushing ${finalBranchName} with token auth...`);
4461
4461
  try {
4462
- // Don't use 2>&1let execSync capture stderr separately
4462
+ // Don't use 2>&1 let execSync capture stderr separately
4463
4463
  pushResult = execSync(`git push ${authenticatedUrl} ${finalBranchName}`, {
4464
4464
  ...opts,
4465
4465
  timeout: 60000, // 60s for slow connections
4466
4466
  stdio: ['pipe', 'pipe', 'pipe'] // capture stdin, stdout, stderr separately
4467
4467
  }).toString();
4468
4468
  pushed = true;
4469
- console.log(`✅ Pushed with token authentication`);
4469
+ console.log(` Pushed with token authentication`);
4470
4470
  } catch (innerErr) {
4471
4471
  // Mask token in error messages before logging
4472
4472
  const maskToken = (str) => str ? str.replace(gitToken, '***TOKEN***') : '';
4473
4473
  const errMsg = maskToken(innerErr.stderr?.toString() || innerErr.stdout?.toString() || innerErr.message || '');
4474
- console.warn(`⚠️ Authenticated push failed: ${errMsg}`);
4474
+ console.warn(` Authenticated push failed: ${errMsg}`);
4475
4475
  pushResult = errMsg;
4476
4476
  }
4477
4477
  } else {
4478
- console.warn(`⚠️ Could not construct authenticated URL from: ${remoteUrlRaw}`);
4478
+ console.warn(` Could not construct authenticated URL from: ${remoteUrlRaw}`);
4479
4479
  }
4480
4480
  } catch (pushErr) {
4481
4481
  const maskToken = (str) => str ? str.replace(gitToken, '***TOKEN***') : '';
4482
- console.warn(`⚠️ Git auth setup failed: ${maskToken(pushErr.message)}`);
4482
+ console.warn(` Git auth setup failed: ${maskToken(pushErr.message)}`);
4483
4483
  pushResult = maskToken(pushErr.message) || 'Push setup failed';
4484
4484
  }
4485
4485
  }
@@ -4494,8 +4494,8 @@ app.post("/workspace/git/create-fix-branch", async (req, res) => {
4494
4494
  pushResult = execSync(`git push origin ${finalBranchName} 2>&1`, opts).toString();
4495
4495
  pushed = true;
4496
4496
  } catch (pushErr2) {
4497
- console.warn(`⚠️ Git push failed: ${pushErr2.message}`);
4498
- pushResult = pushErr2.message || 'Push failedno remote configured or auth required';
4497
+ console.warn(` Git push failed: ${pushErr2.message}`);
4498
+ pushResult = pushErr2.message || 'Push failed no remote configured or auth required';
4499
4499
  }
4500
4500
  }
4501
4501
  }
@@ -4506,7 +4506,7 @@ app.post("/workspace/git/create-fix-branch", async (req, res) => {
4506
4506
  // 9. Get remote URL and generate MR/PR link
4507
4507
  let remoteUrl = '';
4508
4508
  let mrUrl = '';
4509
- let targetBranch = 'develop'; // default targetalways prefer develop
4509
+ let targetBranch = 'develop'; // default target always prefer develop
4510
4510
  try {
4511
4511
  remoteUrl = execSync('git remote get-url origin 2>/dev/null', opts).trim();
4512
4512
  // Always target develop if it exists, regardless of repo default branch
@@ -4519,13 +4519,13 @@ app.post("/workspace/git/create-fix-branch", async (req, res) => {
4519
4519
  execSync('git rev-parse --verify develop 2>/dev/null', opts);
4520
4520
  targetBranch = 'develop';
4521
4521
  } catch {
4522
- // No develop branch at alluse main as last resort
4522
+ // No develop branch at all use main as last resort
4523
4523
  targetBranch = 'main';
4524
4524
  }
4525
4525
  }
4526
4526
 
4527
4527
  // Generate MR/PR URL based on provider
4528
- // 🔒 SECURITY FIX: Remove any embedded tokens from URL before constructing MR link
4528
+ // SECURITY FIX: Remove any embedded tokens from URL before constructing MR link
4529
4529
  // This prevents tokens from appearing in logs, UI, or being shared accidentally
4530
4530
  const cleanUrl = remoteUrl
4531
4531
  .replace(/\.git$/, '')
@@ -4546,15 +4546,15 @@ app.post("/workspace/git/create-fix-branch", async (req, res) => {
4546
4546
  } else if (cleanUrl.includes('bitbucket.org') || cleanUrl.includes('bitbucket')) {
4547
4547
  mrUrl = `${cleanUrl}/pull-requests/new?source=${finalBranchName}&dest=${targetBranch}`;
4548
4548
  } else {
4549
- // Generictry GitHub-style URL
4549
+ // Generic try GitHub-style URL
4550
4550
  mrUrl = `${cleanUrl}/compare/${targetBranch}...${finalBranchName}?expand=1`;
4551
4551
  }
4552
4552
  } catch (e) {
4553
4553
  console.warn('Could not detect remote URL:', e.message);
4554
4554
  }
4555
4555
 
4556
- console.log(`✅ Fix branch created: ${finalBranchName} (${commitSha.substring(0, 8)}) pushed=${pushed}`);
4557
- if (mrUrl) console.log(`🔗 MR URL: ${mrUrl}`);
4556
+ console.log(` Fix branch created: ${finalBranchName} (${commitSha.substring(0, 8)}) pushed=${pushed}`);
4557
+ if (mrUrl) console.log(` MR URL: ${mrUrl}`);
4558
4558
 
4559
4559
  // 10. Switch back to original branch and merge fix to keep changes on disk
4560
4560
  try {
@@ -4563,7 +4563,7 @@ app.post("/workspace/git/create-fix-branch", async (req, res) => {
4563
4563
  // This keeps the diff viewer working (disk has patched version)
4564
4564
  try {
4565
4565
  execSync(`git merge ${finalBranchName} --no-edit`, opts);
4566
- console.log(`✅ Merged ${finalBranchName} into ${currentBranch}`);
4566
+ console.log(` Merged ${finalBranchName} into ${currentBranch}`);
4567
4567
  } catch (mergeErr) {
4568
4568
  // If merge fails (conflicts), just cherry-pick the changes without committing
4569
4569
  try {
@@ -4577,27 +4577,27 @@ app.post("/workspace/git/create-fix-branch", async (req, res) => {
4577
4577
  execSync(`git checkout ${finalBranchName} -- ${f}`, opts);
4578
4578
  } catch {}
4579
4579
  }
4580
- console.log(`✅ Cherry-picked ${changedFiles.length} file(s) from ${finalBranchName}`);
4580
+ console.log(` Cherry-picked ${changedFiles.length} file(s) from ${finalBranchName}`);
4581
4581
  } catch {}
4582
4582
  }
4583
4583
  } catch {}
4584
4584
 
4585
4585
  // 11. Auto-create Pull Request if pushed and token available
4586
- //FIXED: suporta GitHub, GitLab e Bitbucket; branding Insptech AI
4586
+ // FIXED: suporta GitHub, GitLab e Bitbucket; branding Insptech AI
4587
4587
  let prUrl = '';
4588
4588
  const prBodyText =
4589
- `## 🤖 Auto-fix by Insptech AI\n\n` +
4589
+ `## Auto-fix by Insptech AI\n\n` +
4590
4590
  `**Branch:** \`${finalBranchName}\`\n` +
4591
4591
  `**Files changed:** ${status.split('\n').length}\n` +
4592
4592
  `**Commit:** ${commitSha.substring(0, 8)}\n\n` +
4593
4593
  `This pull request was automatically created by Insptech AI after detecting and fixing a production error.\n\n` +
4594
4594
  `### Changes\n` +
4595
4595
  status.split('\n').map(l => `- \`${l.trim()}\``).join('\n') + '\n\n' +
4596
- `---\n*Generated by [Insptech AI](https://app.insptech.pt)Autonomous Debugging Platform*`;
4596
+ `---\n*Generated by [Insptech AI](https://app.insptech.pt) Autonomous Debugging Platform*`;
4597
4597
 
4598
4598
  if (pushed && gitToken && remoteUrl) {
4599
4599
 
4600
- // ── GitHub ──────────────────────────────────────────────────────
4600
+ // GitHub
4601
4601
  if (remoteUrl.includes('github.com')) {
4602
4602
  try {
4603
4603
  const repoPath = remoteUrl
@@ -4624,18 +4624,18 @@ app.post("/workspace/git/create-fix-branch", async (req, res) => {
4624
4624
  if (response.ok) {
4625
4625
  const prData = await response.json();
4626
4626
  prUrl = prData.html_url;
4627
- console.log(`✅ GitHub PR created: ${prUrl}`);
4627
+ console.log(` GitHub PR created: ${prUrl}`);
4628
4628
  } else {
4629
4629
  const errText = await response.text();
4630
- console.warn(`⚠️ GitHub PR creation failed (${response.status}): ${errText.substring(0, 200)}`);
4630
+ console.warn(` GitHub PR creation failed (${response.status}): ${errText.substring(0, 200)}`);
4631
4631
  prUrl = mrUrl;
4632
4632
  }
4633
4633
  } catch (prErr) {
4634
- console.warn(`⚠️ GitHub PR error: ${prErr.message}`);
4634
+ console.warn(` GitHub PR error: ${prErr.message}`);
4635
4635
  prUrl = mrUrl;
4636
4636
  }
4637
4637
 
4638
- // ── GitLab ──────────────────────────────────────────────────────
4638
+ // GitLab
4639
4639
  } else if (remoteUrl.includes('gitlab.com') || remoteUrl.includes('gitlab')) {
4640
4640
  try {
4641
4641
  const hostMatch = remoteUrl.match(/https?:\/\/([^\/]+)/);
@@ -4644,7 +4644,7 @@ app.post("/workspace/git/create-fix-branch", async (req, res) => {
4644
4644
  .replace(/^https?:\/\/(.*@)?[^\/]+\//, '')
4645
4645
  .replace(/^git@[^:]+:/, '')
4646
4646
  .replace(/\.git$/, '');
4647
- // GitLab API requer o path encoded (ex: "mygroup/myrepo""mygroup%2Fmyrepo")
4647
+ // GitLab API requer o path encoded (ex: "mygroup/myrepo" "mygroup%2Fmyrepo")
4648
4648
  const encodedPath = encodeURIComponent(repoPath);
4649
4649
 
4650
4650
  const response = await fetch(`https://${host}/api/v4/projects/${encodedPath}/merge_requests`, {
@@ -4665,18 +4665,18 @@ app.post("/workspace/git/create-fix-branch", async (req, res) => {
4665
4665
  if (response.ok) {
4666
4666
  const mrData = await response.json();
4667
4667
  prUrl = mrData.web_url;
4668
- console.log(`✅ GitLab MR created: ${prUrl}`);
4668
+ console.log(` GitLab MR created: ${prUrl}`);
4669
4669
  } else {
4670
4670
  const errText = await response.text();
4671
- console.warn(`⚠️ GitLab MR creation failed (${response.status}): ${errText.substring(0, 200)}`);
4671
+ console.warn(` GitLab MR creation failed (${response.status}): ${errText.substring(0, 200)}`);
4672
4672
  prUrl = mrUrl;
4673
4673
  }
4674
4674
  } catch (glErr) {
4675
- console.warn(`⚠️ GitLab MR error: ${glErr.message}`);
4675
+ console.warn(` GitLab MR error: ${glErr.message}`);
4676
4676
  prUrl = mrUrl;
4677
4677
  }
4678
4678
 
4679
- // ── Bitbucket ────────────────────────────────────────────────────
4679
+ // Bitbucket
4680
4680
  } else if (remoteUrl.includes('bitbucket.org') || remoteUrl.includes('bitbucket')) {
4681
4681
  try {
4682
4682
  const repoPath = remoteUrl
@@ -4691,18 +4691,18 @@ app.post("/workspace/git/create-fix-branch", async (req, res) => {
4691
4691
  // - plain TOKEN (Repository Access Token)
4692
4692
  let authHeader;
4693
4693
  if (gitToken.includes(':')) {
4694
- // Contains coloncould be user:pass (App Password) or x-token-auth:token
4694
+ // Contains colon could be user:pass (App Password) or x-token-auth:token
4695
4695
  const [user, pass] = gitToken.split(':', 2);
4696
4696
  if (user === 'x-token-auth') {
4697
- // Repository Access Tokenuse Bearer with the token part
4697
+ // Repository Access Token use Bearer with the token part
4698
4698
  authHeader = `Bearer ${pass}`;
4699
4699
  } else {
4700
- // App Passworduse Basic auth
4700
+ // App Password use Basic auth
4701
4701
  const credentials = Buffer.from(gitToken).toString('base64');
4702
4702
  authHeader = `Basic ${credentials}`;
4703
4703
  }
4704
4704
  } else {
4705
- // Plain tokenuse Bearer (Repository Access Token)
4705
+ // Plain token use Bearer (Repository Access Token)
4706
4706
  authHeader = `Bearer ${gitToken}`;
4707
4707
  }
4708
4708
 
@@ -4725,14 +4725,14 @@ app.post("/workspace/git/create-fix-branch", async (req, res) => {
4725
4725
  if (response.ok) {
4726
4726
  const prData = await response.json();
4727
4727
  prUrl = prData.links && prData.links.html ? prData.links.html.href : mrUrl;
4728
- console.log(`✅ Bitbucket PR created: ${prUrl}`);
4728
+ console.log(` Bitbucket PR created: ${prUrl}`);
4729
4729
  } else {
4730
4730
  const errText = await response.text();
4731
- console.warn(`⚠️ Bitbucket PR creation failed (${response.status}): ${errText.substring(0, 200)}`);
4731
+ console.warn(` Bitbucket PR creation failed (${response.status}): ${errText.substring(0, 200)}`);
4732
4732
  prUrl = mrUrl;
4733
4733
  }
4734
4734
  } catch (bbErr) {
4735
- console.warn(`⚠️ Bitbucket PR error: ${bbErr.message}`);
4735
+ console.warn(` Bitbucket PR error: ${bbErr.message}`);
4736
4736
  prUrl = mrUrl;
4737
4737
  }
4738
4738
  }
@@ -4755,7 +4755,7 @@ app.post("/workspace/git/create-fix-branch", async (req, res) => {
4755
4755
  });
4756
4756
 
4757
4757
  } catch (err) {
4758
- console.error(`❌ Git branch creation failed: ${err.message}`);
4758
+ console.error(` Git branch creation failed: ${err.message}`);
4759
4759
  res.status(500).json({ ok: false, error: err.message });
4760
4760
  }
4761
4761
  });
@@ -4799,7 +4799,7 @@ app.get("/workspace/git/status", async (req, res) => {
4799
4799
  });
4800
4800
 
4801
4801
  // ============================================
4802
- // 💬 PULL REQUEST COMMENTS ENDPOINTS
4802
+ // PULL REQUEST COMMENTS ENDPOINTS
4803
4803
  // Read, reply, and resolve PR comments via git providers
4804
4804
  // Used by the frontend "Code Review" tab in incident detail
4805
4805
  // ============================================
@@ -4867,7 +4867,7 @@ app.get("/workspace/git/pr/comments", async (req, res) => {
4867
4867
  unresolvedCount: comments.filter(c => c.resolved === false || c.resolved === undefined).length
4868
4868
  });
4869
4869
  } catch (err) {
4870
- console.error(' Failed to fetch PR comments:', err.message);
4870
+ console.error(' Failed to fetch PR comments:', err.message);
4871
4871
  res.status(500).json({ ok: false, error: err.message });
4872
4872
  }
4873
4873
  });
@@ -4904,7 +4904,7 @@ app.get("/workspace/git/pr/comments/:commentId", async (req, res) => {
4904
4904
 
4905
4905
  res.json({ ok: true, comment });
4906
4906
  } catch (err) {
4907
- console.error(' Failed to fetch PR comment:', err.message);
4907
+ console.error(' Failed to fetch PR comment:', err.message);
4908
4908
  res.status(500).json({ ok: false, error: err.message });
4909
4909
  }
4910
4910
  });
@@ -4966,10 +4966,10 @@ app.post("/workspace/git/pr/comments", async (req, res) => {
4966
4966
  comment = await provider.instance.addPRComment(owner, repo, Number(prNumber), body);
4967
4967
  }
4968
4968
 
4969
- console.log(`💬 PR comment added to PR #${prNumber}: ${body.substring(0, 50)}...`);
4969
+ console.log(` PR comment added to PR #${prNumber}: ${body.substring(0, 50)}...`);
4970
4970
  res.json({ ok: true, comment });
4971
4971
  } catch (err) {
4972
- console.error(' Failed to add PR comment:', err.message);
4972
+ console.error(' Failed to add PR comment:', err.message);
4973
4973
  res.status(500).json({ ok: false, error: err.message });
4974
4974
  }
4975
4975
  });
@@ -5004,10 +5004,10 @@ app.post("/workspace/git/pr/comments/:commentId/resolve", async (req, res) => {
5004
5004
  const { owner, repo } = provider.info;
5005
5005
  const result = await provider.instance.resolvePRComment(owner, repo, Number(prNumber), commentId);
5006
5006
 
5007
- console.log(`✅ PR comment ${commentId} resolved on PR #${prNumber}`);
5007
+ console.log(` PR comment ${commentId} resolved on PR #${prNumber}`);
5008
5008
  res.json({ ok: true, commentId, ...result });
5009
5009
  } catch (err) {
5010
- console.error(' Failed to resolve PR comment:', err.message);
5010
+ console.error(' Failed to resolve PR comment:', err.message);
5011
5011
  res.status(500).json({ ok: false, error: err.message });
5012
5012
  }
5013
5013
  });
@@ -5042,10 +5042,10 @@ app.post("/workspace/git/pr/comments/:commentId/unresolve", async (req, res) =>
5042
5042
  const { owner, repo } = provider.info;
5043
5043
  const result = await provider.instance.unresolvePRComment(owner, repo, Number(prNumber), commentId);
5044
5044
 
5045
- console.log(`🔄 PR comment ${commentId} unresolve on PR #${prNumber}`);
5045
+ console.log(` PR comment ${commentId} unresolve on PR #${prNumber}`);
5046
5046
  res.json({ ok: true, commentId, ...result });
5047
5047
  } catch (err) {
5048
- console.error(' Failed to unresolve PR comment:', err.message);
5048
+ console.error(' Failed to unresolve PR comment:', err.message);
5049
5049
  res.status(500).json({ ok: false, error: err.message });
5050
5050
  }
5051
5051
  });
@@ -5090,7 +5090,7 @@ app.post("/workspace/git/pr/comments/:commentId/fix-and-resolve", async (req, re
5090
5090
  return res.status(404).json({ error: "Comment not found" });
5091
5091
  }
5092
5092
 
5093
- console.log(`🤖 AI Fix & Resolve: PR #${prNumber}, comment ${commentId}`);
5093
+ console.log(` AI Fix & Resolve: PR #${prNumber}, comment ${commentId}`);
5094
5094
  console.log(` File: ${comment.path || '(general)'}, Line: ${comment.line || 'N/A'}`);
5095
5095
  console.log(` Request: ${comment.body.substring(0, 100)}...`);
5096
5096
 
@@ -5122,14 +5122,14 @@ app.post("/workspace/git/pr/comments/:commentId/fix-and-resolve", async (req, re
5122
5122
  message: 'Comment fetched. Gateway should now: 1) Read file, 2) AI analyze, 3) Apply patch, 4) Commit, 5) Reply, 6) Resolve'
5123
5123
  });
5124
5124
  } catch (err) {
5125
- console.error(' Failed to prepare fix-and-resolve:', err.message);
5125
+ console.error(' Failed to prepare fix-and-resolve:', err.message);
5126
5126
  res.status(500).json({ ok: false, error: err.message });
5127
5127
  }
5128
5128
  });
5129
5129
 
5130
5130
 
5131
5131
  // ============================================
5132
- // 🔧 GIT PROVIDER HELPER (internal)
5132
+ // GIT PROVIDER HELPER (internal)
5133
5133
  // Detects provider from remote URL and configures with token
5134
5134
  // ============================================
5135
5135
 
@@ -5145,7 +5145,7 @@ async function _getGitProvider() {
5145
5145
  try {
5146
5146
  remoteUrl = execSync('git remote get-url origin', opts).trim();
5147
5147
  } catch {
5148
- console.warn('⚠️ No git remote found');
5148
+ console.warn(' No git remote found');
5149
5149
  return null;
5150
5150
  }
5151
5151
 
@@ -5155,7 +5155,7 @@ async function _getGitProvider() {
5155
5155
  const providerId = registry.detectProviderFromUrl(remoteUrl);
5156
5156
 
5157
5157
  if (!providerId) {
5158
- console.warn(`⚠️ Unknown git provider for URL: ${remoteUrl}`);
5158
+ console.warn(` Unknown git provider for URL: ${remoteUrl}`);
5159
5159
  return null;
5160
5160
  }
5161
5161
 
@@ -5170,7 +5170,7 @@ async function _getGitProvider() {
5170
5170
  }
5171
5171
 
5172
5172
  if (!token) {
5173
- console.warn(`⚠️ No token found for ${providerId}. Set ${providerId.toUpperCase()}_TOKEN or GIT_TOKEN env var.`);
5173
+ console.warn(` No token found for ${providerId}. Set ${providerId.toUpperCase()}_TOKEN or GIT_TOKEN env var.`);
5174
5174
  return null;
5175
5175
  }
5176
5176
 
@@ -5190,12 +5190,12 @@ async function _getGitProvider() {
5190
5190
 
5191
5191
  return { instance, info, providerId, remoteUrl };
5192
5192
  } catch (err) {
5193
- console.error(' Failed to initialize git provider:', err.message);
5193
+ console.error(' Failed to initialize git provider:', err.message);
5194
5194
  return null;
5195
5195
  }
5196
5196
  }
5197
5197
  // ============================================
5198
- // 📂 MULTI-WORKSPACE ENDPOINTS
5198
+ // MULTI-WORKSPACE ENDPOINTS
5199
5199
  // ============================================
5200
5200
 
5201
5201
  /** Lista todos os workspaces abertos */
@@ -5232,7 +5232,7 @@ app.post("/workspace/:workspaceId/open", async (req, res) => {
5232
5232
  }
5233
5233
  });
5234
5234
 
5235
- /** Aplica patch num workspace específico */
5235
+ /** Aplica patch num workspace especfico */
5236
5236
  app.post("/workspace/:workspaceId/patch", async (req, res) => {
5237
5237
  const { workspaceId } = req.params;
5238
5238
  const { diff } = req.body || {};
@@ -5246,7 +5246,7 @@ app.post("/workspace/:workspaceId/patch", async (req, res) => {
5246
5246
  }
5247
5247
  });
5248
5248
 
5249
- /** Compila e testa num workspace específico */
5249
+ /** Compila e testa num workspace especfico */
5250
5250
  app.post("/workspace/:workspaceId/test", async (req, res) => {
5251
5251
  const { workspaceId } = req.params;
5252
5252
  try {
@@ -5259,7 +5259,7 @@ app.post("/workspace/:workspaceId/test", async (req, res) => {
5259
5259
  }
5260
5260
  });
5261
5261
 
5262
- /** Executa comando num workspace específico */
5262
+ /** Executa comando num workspace especfico */
5263
5263
  app.post("/workspace/:workspaceId/run", async (req, res) => {
5264
5264
  const { workspaceId } = req.params;
5265
5265
  const { cmd, args = [] } = req.body || {};
@@ -5275,12 +5275,12 @@ app.post("/workspace/:workspaceId/run", async (req, res) => {
5275
5275
 
5276
5276
 
5277
5277
  // ============================================
5278
- // 🔌 WEBSOCKET REVERSE TUNNEL
5279
- // Connects Local Agent to Gatewayno public URL needed
5278
+ // WEBSOCKET REVERSE TUNNEL
5279
+ // Connects Local Agent to Gateway no public URL needed
5280
5280
  // ============================================
5281
5281
  async function startWebSocketTunnel(port, gatewayUrl, apiKey, tenantId) {
5282
5282
  if (!gatewayUrl || !apiKey || !tenantId) {
5283
- console.log('⚠️ WebSocket tunnel skipped: missing gatewayUrl, apiKey or tenantId in ~/.deepdebug/config.json');
5283
+ console.log(' WebSocket tunnel skipped: missing gatewayUrl, apiKey or tenantId in ~/.deepdebug/config.json');
5284
5284
  return;
5285
5285
  }
5286
5286
 
@@ -5298,7 +5298,7 @@ async function startWebSocketTunnel(port, gatewayUrl, apiKey, tenantId) {
5298
5298
  ws = new WebSocket(fullUrl);
5299
5299
 
5300
5300
  ws.on('open', () => {
5301
- console.log(`✅ WebSocket tunnel connected to Gateway`);
5301
+ console.log(` WebSocket tunnel connected to Gateway`);
5302
5302
  reconnectDelay = 2000;
5303
5303
  ws.send(JSON.stringify({ type: 'register', tenantId, port, workspacePath: WORKSPACE_ROOT || null }));
5304
5304
  const hb = setInterval(() => {
@@ -5314,7 +5314,7 @@ async function startWebSocketTunnel(port, gatewayUrl, apiKey, tenantId) {
5314
5314
  try { request = JSON.parse(text); } catch { return; }
5315
5315
  const { requestId, command, params } = request;
5316
5316
  if (!requestId || !command) return;
5317
- console.log(`📨 WS command: ${command}`);
5317
+ console.log(` WS command: ${command}`);
5318
5318
  let result;
5319
5319
  try { result = await handleWsCommand(command, params || {}); }
5320
5320
  catch (err) { result = { error: err.message }; }
@@ -5323,19 +5323,19 @@ async function startWebSocketTunnel(port, gatewayUrl, apiKey, tenantId) {
5323
5323
 
5324
5324
  ws.on('close', () => {
5325
5325
  if (!isShuttingDown) {
5326
- console.log(`🔌 WS disconnected. Reconnecting in ${reconnectDelay/1000}s...`);
5326
+ console.log(` WS disconnected. Reconnecting in ${reconnectDelay/1000}s...`);
5327
5327
  setTimeout(connect, reconnectDelay);
5328
5328
  reconnectDelay = Math.min(reconnectDelay * 2, 30000);
5329
5329
  }
5330
5330
  });
5331
5331
 
5332
- ws.on('error', (err) => console.warn(`⚠️ WS error: ${err.message}`));
5332
+ ws.on('error', (err) => console.warn(` WS error: ${err.message}`));
5333
5333
 
5334
5334
  } catch (err) {
5335
5335
  if (err.code === 'ERR_MODULE_NOT_FOUND') {
5336
- console.warn('⚠️ WebSocket tunnel requires "ws" package. Run: npm install ws');
5336
+ console.warn(' WebSocket tunnel requires "ws" package. Run: npm install ws');
5337
5337
  } else {
5338
- console.warn(`⚠️ WS tunnel error: ${err.message}`);
5338
+ console.warn(` WS tunnel error: ${err.message}`);
5339
5339
  setTimeout(connect, reconnectDelay);
5340
5340
  reconnectDelay = Math.min(reconnectDelay * 2, 30000);
5341
5341
  }
@@ -5392,7 +5392,7 @@ async function startWebSocketTunnel(port, gatewayUrl, apiKey, tenantId) {
5392
5392
  }
5393
5393
 
5394
5394
  // ============================================
5395
- // WORKSPACE DIFFReturns before/after for patches
5395
+ // WORKSPACE DIFF Returns before/after for patches
5396
5396
  // ============================================
5397
5397
  case 'workspace.diff': {
5398
5398
  const { backupId, incidentId } = params;
@@ -5406,7 +5406,7 @@ async function startWebSocketTunnel(port, gatewayUrl, apiKey, tenantId) {
5406
5406
  return { error: 'backupId or incidentId is required' };
5407
5407
  }
5408
5408
 
5409
- console.log(`📊 WS workspace.diff${endpoint}`);
5409
+ console.log(` WS workspace.diff ${endpoint}`);
5410
5410
  const res = await fetch(`${localBase}${endpoint}`, {
5411
5411
  method: 'GET',
5412
5412
  headers: { 'Content-Type': 'application/json' }
@@ -5415,7 +5415,7 @@ async function startWebSocketTunnel(port, gatewayUrl, apiKey, tenantId) {
5415
5415
  }
5416
5416
 
5417
5417
  // ============================================
5418
- // MCP TOOLSrouted via MCP HTTP Bridge (port 5056)
5418
+ // MCP TOOLS routed via MCP HTTP Bridge (port 5056)
5419
5419
  // ============================================
5420
5420
  case 'mcp.read-file': {
5421
5421
  const mcpBase = `http://localhost:5056`;
@@ -5543,18 +5543,18 @@ async function startWebSocketTunnel(port, gatewayUrl, apiKey, tenantId) {
5543
5543
  // START SERVER
5544
5544
  // ============================================
5545
5545
  app.listen(PORT, '0.0.0.0', async () => {
5546
- console.log(`\n🔌 DeepDebug Local Agent listening on port ${PORT}`);
5547
- console.log(`📦 Environment: ${process.env.NODE_ENV || 'development'}`);
5548
- console.log(`📦 Process Manager initialized`);
5549
- console.log(`💾 Backup system ready (max: ${MAX_BACKUPS} backups)`);
5550
- console.log(`🧠 AI Vibe Coding Engine: ${aiEngine?.isActive ? 'ACTIVE' : 'DISABLED'}`);
5546
+ console.log(`\n DeepDebug Local Agent listening on port ${PORT}`);
5547
+ console.log(` Environment: ${process.env.NODE_ENV || 'development'}`);
5548
+ console.log(` Process Manager initialized`);
5549
+ console.log(` Backup system ready (max: ${MAX_BACKUPS} backups)`);
5550
+ console.log(` AI Vibe Coding Engine: ${aiEngine?.isActive ? 'ACTIVE' : 'DISABLED'}`);
5551
5551
  if (aiEngine) {
5552
5552
  console.log(` Gateway URL: ${aiEngine.gatewayUrl}`);
5553
5553
  console.log(` Max Retries: ${aiEngine.maxRetries}`);
5554
5554
  }
5555
- console.log(`\n🚀 Ready to receive requests!\n`);
5555
+ console.log(`\n Ready to receive requests!\n`);
5556
5556
 
5557
- // 🔌 Start WebSocket reverse tunnel
5557
+ // Start WebSocket reverse tunnel
5558
5558
  const homeDir = process.env.HOME || process.env.USERPROFILE;
5559
5559
  const configPath = path.join(homeDir, '.deepdebug', 'config.json');
5560
5560
  let cfg = {};
@@ -5579,7 +5579,7 @@ app.listen(PORT, '0.0.0.0', async () => {
5579
5579
  try {
5580
5580
  startMCPHttpServer(wsManager, parseInt(MCP_PORT));
5581
5581
  } catch (err) {
5582
- console.warn(`⚠️ MCP HTTP Server failed to start: ${err.message}`);
5582
+ console.warn(` MCP HTTP Server failed to start: ${err.message}`);
5583
5583
  console.warn(` (MCP features disabled, REST API continues normally)`);
5584
5584
  }
5585
5585