nothumanallowed 13.5.135 → 13.5.137

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nothumanallowed",
3
- "version": "13.5.135",
3
+ "version": "13.5.137",
4
4
  "description": "NotHumanAllowed — 38 AI agents, 80 tools, Studio (visual agentic workflows). Email, calendar, browser automation, screen capture, canvas, cron/heartbeat, Alexandria E2E messaging, GitHub, Notion, Slack, voice chat, free AI (Liara), 28 languages. Zero-dependency CLI.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -5643,9 +5643,20 @@ module.exports = { validateEmail, sanitizeText, validatePassword, validateUserna
5643
5643
  // Also include: any file whose name appears in the user message, plus error-related files.
5644
5644
  const msgLower = (message || '').toLowerCase();
5645
5645
  const alwaysInclude = ['package.json', 'server/index.js', '.env.example'];
5646
+
5647
+ // For autofix: extract file paths directly from stack trace (e.g. "at Object.<anonymous> (/path/server/routes/auth.js:11:8)")
5648
+ const stackFileMatches = autofix ? [...(message.matchAll(/\(([^)]+\.(?:js|mjs|cjs|ts)):\d+:\d+\)/g))] : [];
5649
+ const stackFiles = new Set(stackFileMatches.map(m => {
5650
+ const abs = m[1];
5651
+ // Make relative to sandboxDir
5652
+ return abs.startsWith(sandboxDir) ? abs.slice(sandboxDir.length + 1) : abs.split('/').slice(-3).join('/');
5653
+ }));
5654
+
5646
5655
  const relevantFiles = allFiles.filter(f => {
5647
5656
  const nameLower = f.name.toLowerCase();
5648
5657
  if (alwaysInclude.some(a => nameLower.endsWith(a))) return true;
5658
+ // Always include files mentioned in stack trace (autofix)
5659
+ if (stackFiles.size > 0 && [...stackFiles].some(sf => f.name.includes(sf) || sf.includes(f.name))) return true;
5649
5660
  // Include if file name or path fragment mentioned in message
5650
5661
  const parts = f.name.split('/');
5651
5662
  if (parts.some(p => msgLower.includes(p.replace(/\.[^.]+$/, '').toLowerCase()))) return true;
@@ -5691,7 +5702,7 @@ Per leggere un file (se hai bisogno di piu contesto):
5691
5702
 
5692
5703
  REGOLE CRITICHE:
5693
5704
  - Spiega SEMPRE in linguaggio naturale cosa stai facendo PRIMA dei blocchi tool
5694
- - Usa "edit" (old/new) quando possibile, "write" solo per file nuovi o riscritture complete
5705
+ - ${autofix ? 'MODALITA AUTO-FIX: usa "write" per riscrivere i file problematici nella loro interezza — è più affidabile di "edit" quando il file ha già subito modifiche. Includi il contenuto COMPLETO del file nel campo "content".' : 'Usa "edit" (old/new) quando possibile, "write" solo per file nuovi o riscritture complete'}
5695
5706
  - old_string deve essere ESATTO come appare nel file (copy-paste)
5696
5707
  - Non inventare moduli npm: usa solo quelli in package.json o standard Node.js
5697
5708
  - Dopo ogni fix spiega brevemente cosa hai cambiato e perche
@@ -5845,7 +5856,24 @@ REGOLE CRITICHE:
5845
5856
  oldSnippet: (toolCall.old || '').slice(0, 300),
5846
5857
  newSnippet: (toolCall.new || '').slice(0, 300) });
5847
5858
  } else {
5848
- sendEv({ type: 'tool', op: 'edit', path: toolCall.path, result: 'old_string non trovato patch fallita' });
5859
+ // edit fallback: old_string not found do a second LLM call with the full file
5860
+ // and ask it to rewrite the file correctly. No client loop needed.
5861
+ sendEv({ type: 'tool', op: 'edit', path: toolCall.path, result: 'patch chirurgica fallita — riscrittura automatica in corso...' });
5862
+ try {
5863
+ const fallbackSys = `Sei un esperto di Node.js. Riscrivi il seguente file correggendo questo problema: ${message.slice(0, 500)}
5864
+ Rispondi SOLO con il contenuto completo del file corretto, senza markdown fence, senza spiegazioni.`;
5865
+ const fallbackUser = `FILE: ${toolCall.path}\n\`\`\`\n${content}\n\`\`\``;
5866
+ const newContent = await callLLM(config, fallbackSys, fallbackUser, { max_tokens: 4096 });
5867
+ const cleaned = newContent.replace(/^```[\w]*\n?/m, '').replace(/\n?```\s*$/m, '').trim();
5868
+ if (cleaned && cleaned.length > 20) {
5869
+ fs.writeFileSync(fp, cleaned, 'utf8');
5870
+ toolResults.push({ op: 'write', path: toolCall.path, ok: true });
5871
+ sendEv({ type: 'tool', op: 'write', path: toolCall.path, result: 'ok (fallback rewrite)',
5872
+ oldSnippet: content.slice(0, 300), newSnippet: cleaned.slice(0, 300) });
5873
+ }
5874
+ } catch(fallbackErr) {
5875
+ sendEv({ type: 'tool', op: 'edit', path: toolCall.path, result: 'fallback rewrite fallito: ' + fallbackErr.message.slice(0, 80) });
5876
+ }
5849
5877
  }
5850
5878
  } else if (toolCall.op === 'write') {
5851
5879
  const fp = path.join(sandboxDir, toolCall.path.replace(/^\/+/, ''));
package/src/constants.mjs CHANGED
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'url';
5
5
  const __filename = fileURLToPath(import.meta.url);
6
6
  const __dirname = path.dirname(__filename);
7
7
 
8
- export const VERSION = '13.5.135';
8
+ export const VERSION = '13.5.137';
9
9
  export const BASE_URL = 'https://nothumanallowed.com/cli';
10
10
  export const API_BASE = 'https://nothumanallowed.com/api/v1';
11
11
 
@@ -8371,7 +8371,8 @@ async function wcTriggerCrashFix(errorMsg) {
8371
8371
  });
8372
8372
  if (wcChatRunning) return;
8373
8373
  }
8374
- var fixMsg = 'CRASH FIX RICHIESTO.' + String.fromCharCode(10) + 'ERRORE:' + String.fromCharCode(10) + errorMsg + String.fromCharCode(10) + String.fromCharCode(10) + 'ISTRUZIONI OBBLIGATORIE:' + String.fromCharCode(10) + '1. Leggi i file coinvolti nello stack trace' + String.fromCharCode(10) + '2. Individua la riga esatta del problema' + String.fromCharCode(10) + '3. Usa OBBLIGATORIAMENTE il tool edit_file o write_file per correggere il codice' + String.fromCharCode(10) + '4. NON limitarti a spiegare il problema - DEVI modificare i file' + String.fromCharCode(10) + '5. Dopo aver modificato, il sandbox verrà riavviato automaticamente';
8374
+ var attemptNum = _wcAutoFixAttempts;
8375
+ var fixMsg = 'CRASH FIX RICHIESTO (tentativo ' + attemptNum + '/3).' + String.fromCharCode(10) + 'ERRORE:' + String.fromCharCode(10) + errorMsg + String.fromCharCode(10) + String.fromCharCode(10) + 'REGOLE OBBLIGATORIE:' + String.fromCharCode(10) + '1. Leggi i file coinvolti nello stack trace con view_file' + String.fromCharCode(10) + '2. Individua la riga esatta del problema' + String.fromCharCode(10) + '3. Usa edit_file per patch chirurgiche. SE edit_file fallisce con "old_string non trovato", usa SUBITO write_file per riscrivere il file intero correttamente' + String.fromCharCode(10) + '4. NON spiegare - MODIFICA i file. Se non usi edit_file o write_file il problema non viene risolto' + String.fromCharCode(10) + (attemptNum > 1 ? '5. ATTENZIONE: tentativi precedenti sono falliti. Usa write_file per riscrivere completamente i file problematici invece di patch parziali.' : '5. Dopo la modifica il sandbox si riavvia automaticamente');
8375
8376
  wcChat.push({ role: 'user', text: '\uD83E\uDD16 Auto-fix crash: ' + errorMsg });
8376
8377
  wcChatRunning = true;
8377
8378
  renderWebCraft(document.getElementById('content'));
@@ -9310,7 +9311,9 @@ async function wcStartSandbox() {
9310
9311
  wcState.sandbox.running = false;
9311
9312
  wcState.sandbox.port = evt.port;
9312
9313
  wcState.sandbox.dir = evt.dir;
9313
- _wcAutoFixAttempts = 0;
9314
+ // Reset counter only after stable uptime (5s), not immediately on first ready
9315
+ // This prevents infinite loop: crash → fix → restart → crash → reset → crash → ...
9316
+ setTimeout(function() { _wcAutoFixAttempts = 0; }, 5000);
9314
9317
  wcStartAutoFixPoller();
9315
9318
  // Reload skills so newly written log file appears in the panel
9316
9319
  _wcSkillsLoaded = false;