nothumanallowed 13.5.136 → 13.5.138
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/LICENSE +1 -1
- package/README.md +100 -2
- package/bin/nha +36 -0
- package/bin/nha.mjs +35 -1
- package/package.json +1 -1
- package/src/commands/ui.mjs +30 -2
- package/src/constants.mjs +1 -1
- package/src/services/web-ui.mjs +14 -11
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# NotHumanAllowed
|
|
2
2
|
|
|
3
|
-
**38 specialized AI agents, 80 tools, Studio visual workflows — all local, all free.** Security auditors, code architects, data analysts, DevOps engineers, technical writers — each with deep domain expertise. Use them individually, run complex multi-agent workflows in Studio, or let
|
|
3
|
+
**38 specialized AI agents, 80 tools, Studio visual workflows, WebCraft full-stack builder — all local, all free.** Security auditors, code architects, data analysts, DevOps engineers, technical writers — each with deep domain expertise. Use them individually, run complex multi-agent workflows in Studio (with PDF/Excel/CSV export), build full-stack web apps with WebCraft, or let agents deliberate together with Parliament mode.
|
|
4
4
|
|
|
5
5
|
## Quick Start
|
|
6
6
|
|
|
@@ -36,9 +36,87 @@ EmailAgent → WebSearchAgent → WriterAgent
|
|
|
36
36
|
|
|
37
37
|
- **No configuration** — works with any LLM provider including Liara (free, no API key)
|
|
38
38
|
- **Live canvas** — see each agent activate, stream output, and hand off to the next
|
|
39
|
-
- **
|
|
39
|
+
- **HTML dashboard** — canvas generates a downloadable visual report (HTML + PDF)
|
|
40
|
+
- **Parliament mode** — enable for 2+ specialist agents to cross-read and deliberate: R1 (independent), R2 (agents read each other), R3 (HERALD mediation), convergence score
|
|
40
41
|
- Open `nha ui` → click **Studio** in the sidebar
|
|
41
42
|
|
|
43
|
+
### Studio Export
|
|
44
|
+
|
|
45
|
+
When a workflow completes, Studio provides three export formats:
|
|
46
|
+
|
|
47
|
+
- **PDF** — full structured report with all agent outputs, typography, token counters
|
|
48
|
+
- **Excel (XLSX)** — professional multi-sheet workbook via SheetJS: one sheet per agent, auto-detected numeric columns with formatting, alternating row colors, freeze panes, auto-column widths, index sheet with token summary. Data tables are extracted from Markdown output automatically.
|
|
49
|
+
- **CSV** — all Markdown tables from the report merged into a single file
|
|
50
|
+
|
|
51
|
+
Export buttons appear in the result panel and in the toolbar after each run.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## WebCraft — Full-Stack Web Apps from a Chat
|
|
56
|
+
|
|
57
|
+
WebCraft is a full-stack web app builder embedded in `nha ui`. Describe what you want in plain language — WebCraft generates a complete project with Express.js backend, PostgreSQL schema, JWT auth, email verification, security middleware, and a styled frontend. Everything runs locally with a live sandbox.
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
Open nha ui → click WebCraft in the sidebar
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### How it works
|
|
64
|
+
|
|
65
|
+
1. **Describe your project** in the chat (or pick an example: MySaaS, MyShop, MyBlog, MyPortfolio...)
|
|
66
|
+
2. **WebCraft generates** all files: `server/`, `public/`, `db/migrations/`, `.env.example`, `package.json`, nginx config
|
|
67
|
+
3. **Click ▶ Sandbox** — runs `npm install && node server/index.js` in an isolated process, live on a local port
|
|
68
|
+
4. **Chat with the agent** to modify, fix, or extend anything — the agent edits files directly on disk, you see diffs in real time
|
|
69
|
+
|
|
70
|
+
### WebCraft Agent
|
|
71
|
+
|
|
72
|
+
An AI assistant permanently available in the chat panel. Powered by Liara (Qwen3 32B, free) or your own API key.
|
|
73
|
+
|
|
74
|
+
**What it can do:**
|
|
75
|
+
- Edit files surgically (old → new string replace) or rewrite them completely
|
|
76
|
+
- Read any project file for context
|
|
77
|
+
- Auto-fix `MODULE_NOT_FOUND` and common require() path errors
|
|
78
|
+
- Restart the sandbox after fixes
|
|
79
|
+
- Process attached screenshots or PDFs (vision) to debug visual issues
|
|
80
|
+
|
|
81
|
+
**Context files** (created automatically for every project, editable via sidebar):
|
|
82
|
+
| File | Type | Purpose |
|
|
83
|
+
|---|---|---|
|
|
84
|
+
| `skills/memory.md` | memory | Architecture decisions, stack choices, developer preferences |
|
|
85
|
+
| `skills/liara.md` | provider | Calibrate AI tone, code style, constraints |
|
|
86
|
+
| `skills/skills.md` | skill | Reusable patterns, snippets, API integrations |
|
|
87
|
+
|
|
88
|
+
Add more skill files (unlimited) for specific integrations (Stripe, email templates, etc.).
|
|
89
|
+
|
|
90
|
+
### Developer Tools (sidebar toolbar)
|
|
91
|
+
|
|
92
|
+
| Tool | Description |
|
|
93
|
+
|---|---|
|
|
94
|
+
| **Diff viewer** | After every agent edit, see before/after for each changed file — color-coded, collapsible |
|
|
95
|
+
| **Syntax check** ✅ | Runs `node --check` on all JS files, reports errors instantly |
|
|
96
|
+
| **Search** 🔍 | Grep across all project files — click a result to jump to that file |
|
|
97
|
+
| **Snapshot** 💾 | Save a full point-in-time backup of all files. Restore any snapshot with one click |
|
|
98
|
+
| **Plan mode** | Type `/plan your request` — agent proposes a plan first, you approve before any file is touched |
|
|
99
|
+
| **Auto-fix** | Sandbox errors (MODULE_NOT_FOUND etc.) trigger automatic Liara fix attempts (3 free, unlimited with own key) |
|
|
100
|
+
|
|
101
|
+
### Example session
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
You: "Add a contact form with SMTP email and honeypot spam protection"
|
|
105
|
+
Agent: → edits server/routes/api.js (add /contact POST route)
|
|
106
|
+
→ edits server/services/email.js (add sendContactEmail)
|
|
107
|
+
→ edits public/index.html (add form HTML)
|
|
108
|
+
→ edits public/js/main.js (add form JS with honeypot)
|
|
109
|
+
[Diff viewer shows 4 files changed]
|
|
110
|
+
[Syntax check: ✅ all files valid]
|
|
111
|
+
[Sandbox restarted automatically]
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
You: "/plan refactor auth to use refresh token rotation"
|
|
116
|
+
Agent: → proposes plan (3 files, 6 changes) — no edits yet
|
|
117
|
+
→ you click Approve → agent executes
|
|
118
|
+
```
|
|
119
|
+
|
|
42
120
|
## Daily Operations (PAO)
|
|
43
121
|
|
|
44
122
|
Connect Gmail + Calendar. 5 specialist agents analyze your day.
|
|
@@ -83,6 +161,26 @@ All data stored locally in `~/.nha/ops/`. Tokens encrypted with AES-256-GCM. You
|
|
|
83
161
|
|
|
84
162
|
38 agents across 11 domains. Each agent is a standalone `.mjs` file you own locally — inspect it, modify it, run it offline.
|
|
85
163
|
|
|
164
|
+
## Code Execution
|
|
165
|
+
|
|
166
|
+
`execute_code` runs Python, JavaScript, or TypeScript in an isolated sandbox:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
# Python with auto-installed packages
|
|
170
|
+
nha chat
|
|
171
|
+
> use execute_code to analyze this CSV with pandas
|
|
172
|
+
|
|
173
|
+
# TypeScript
|
|
174
|
+
> write and run a TypeScript script that parses this JSON
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
- **Isolated sandbox** — dedicated temp dir per run, deleted after execution
|
|
178
|
+
- **Stripped environment** — subprocess never sees NHA API keys
|
|
179
|
+
- **Package install** — `packages: ["pandas", "numpy"]` auto-installs via pip/npm
|
|
180
|
+
- **Multi-file** — pass extra files (CSV, JSON, helper modules) via `files: [{path, content}]`
|
|
181
|
+
- **SIGKILL on timeout** — 30s default, configurable up to 120s
|
|
182
|
+
- **Returns** stdout, stderr, exit code, and list of files created in sandbox
|
|
183
|
+
|
|
86
184
|
### Security
|
|
87
185
|
- **SABER** — Security audit, OWASP, threat modeling, pentest planning
|
|
88
186
|
- **ZERO** — Vulnerability scanning, dependency audit, secret detection
|
package/bin/nha
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* nha — NotHumanAllowed CLI
|
|
4
|
+
*
|
|
5
|
+
* Thin launcher for Legion (multi-agent deliberation) and PIF (agent social client).
|
|
6
|
+
* Zero dependencies. Downloads core files on first run to ~/.nha/.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* npx nha run "Compare React vs Vue for enterprise"
|
|
10
|
+
* npx nha agents
|
|
11
|
+
* npx nha pif register
|
|
12
|
+
* npx nha install nha-code-reviewer
|
|
13
|
+
* npx nha config set provider anthropic
|
|
14
|
+
* npx nha update
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { fileURLToPath, pathToFileURL } from 'url';
|
|
18
|
+
import path from 'path';
|
|
19
|
+
|
|
20
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
21
|
+
const __dirname = path.dirname(__filename);
|
|
22
|
+
|
|
23
|
+
// ── Node.js version gate ────────────────────────────────────────────────────
|
|
24
|
+
const major = parseInt(process.version.slice(1), 10);
|
|
25
|
+
if (major < 20) {
|
|
26
|
+
console.error(`\x1b[31mError: nha requires Node.js 20 or later (found ${process.version}).\x1b[0m`);
|
|
27
|
+
console.error('Install from https://nodejs.org');
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// ── Launch CLI ──────────────────────────────────────────────────────────────
|
|
32
|
+
// On Windows, dynamic import() requires file:// URLs, not raw paths like C:\...
|
|
33
|
+
const cliPath = path.join(__dirname, '..', 'src', 'cli.mjs');
|
|
34
|
+
const cliUrl = pathToFileURL(cliPath).href;
|
|
35
|
+
const { main } = await import(cliUrl);
|
|
36
|
+
await main(process.argv.slice(2));
|
package/bin/nha.mjs
CHANGED
|
@@ -1,2 +1,36 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* nha — NotHumanAllowed CLI
|
|
4
|
+
*
|
|
5
|
+
* Thin launcher for Legion (multi-agent deliberation) and PIF (agent social client).
|
|
6
|
+
* Zero dependencies. Downloads core files on first run to ~/.nha/.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* npx nha run "Compare React vs Vue for enterprise"
|
|
10
|
+
* npx nha agents
|
|
11
|
+
* npx nha pif register
|
|
12
|
+
* npx nha install nha-code-reviewer
|
|
13
|
+
* npx nha config set provider anthropic
|
|
14
|
+
* npx nha update
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { fileURLToPath, pathToFileURL } from 'url';
|
|
18
|
+
import path from 'path';
|
|
19
|
+
|
|
20
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
21
|
+
const __dirname = path.dirname(__filename);
|
|
22
|
+
|
|
23
|
+
// ── Node.js version gate ────────────────────────────────────────────────────
|
|
24
|
+
const major = parseInt(process.version.slice(1), 10);
|
|
25
|
+
if (major < 20) {
|
|
26
|
+
console.error(`\x1b[31mError: nha requires Node.js 20 or later (found ${process.version}).\x1b[0m`);
|
|
27
|
+
console.error('Install from https://nodejs.org');
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// ── Launch CLI ──────────────────────────────────────────────────────────────
|
|
32
|
+
// On Windows, dynamic import() requires file:// URLs, not raw paths like C:\...
|
|
33
|
+
const cliPath = path.join(__dirname, '..', 'src', 'cli.mjs');
|
|
34
|
+
const cliUrl = pathToFileURL(cliPath).href;
|
|
35
|
+
const { main } = await import(cliUrl);
|
|
36
|
+
await main(process.argv.slice(2));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "13.5.
|
|
3
|
+
"version": "13.5.138",
|
|
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": {
|
package/src/commands/ui.mjs
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
8
|
+
export const VERSION = '13.5.138';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
package/src/services/web-ui.mjs
CHANGED
|
@@ -7968,16 +7968,16 @@ function wcChatPanelHtml() {
|
|
|
7968
7968
|
var color = isOk ? 'var(--green)' : 'var(--red)';
|
|
7969
7969
|
var label = isParseErr ? ('JSON err: ' + wcEsc(tool.result)) : wcEsc(tool.path);
|
|
7970
7970
|
var title = isOk ? tool.op + ': ' + tool.path : (tool.result || '');
|
|
7971
|
-
// Build inline diff block for successful edits
|
|
7972
|
-
if (isOk && tool.op === 'edit' && tool.oldSnippet) {
|
|
7973
|
-
var oldLines = tool.oldSnippet.split(String.fromCharCode(10)).map(function(l){ return '<div style="background:#3f0f0f;color:#fca5a5;font-family:var(--mono);font-size:9px;padding:
|
|
7974
|
-
var newLines = tool.newSnippet.split(String.fromCharCode(10)).map(function(l){ return '<div style="background:#0f2f0f;color:#86efac;font-family:var(--mono);font-size:9px;padding:
|
|
7975
|
-
diffBlocks += '<
|
|
7976
|
-
'<
|
|
7977
|
-
'<span style="color:var(--green)">✎</span> '+wcEsc(tool.path)
|
|
7978
|
-
'</
|
|
7971
|
+
// Build inline diff block for successful edits/writes — always visible, no collapse
|
|
7972
|
+
if (isOk && (tool.op === 'edit' || tool.op === 'write') && (tool.oldSnippet || tool.newSnippet)) {
|
|
7973
|
+
var oldLines = tool.oldSnippet ? tool.oldSnippet.split(String.fromCharCode(10)).map(function(l){ return '<div style="background:#3f0f0f;color:#fca5a5;font-family:var(--mono);font-size:9px;padding:1px 8px;white-space:pre-wrap;word-break:break-all">- '+wcEsc(l)+'</div>'; }).join('') : '';
|
|
7974
|
+
var newLines = tool.newSnippet ? tool.newSnippet.split(String.fromCharCode(10)).map(function(l){ return '<div style="background:#0f2f0f;color:#86efac;font-family:var(--mono);font-size:9px;padding:1px 8px;white-space:pre-wrap;word-break:break-all">+ '+wcEsc(l)+'</div>'; }).join('') : '';
|
|
7975
|
+
diffBlocks += '<div style="margin:4px 0;border:1px solid rgba(255,255,255,0.1);border-radius:5px;overflow:hidden">' +
|
|
7976
|
+
'<div style="padding:3px 8px;font-size:9px;font-family:var(--mono);color:var(--dim);background:rgba(255,255,255,0.04);display:flex;align-items:center;gap:4px">' +
|
|
7977
|
+
'<span style="color:var(--green)">✎</span> '+wcEsc(tool.path) +
|
|
7978
|
+
'</div>' +
|
|
7979
7979
|
oldLines + newLines +
|
|
7980
|
-
'</
|
|
7980
|
+
'</div>';
|
|
7981
7981
|
}
|
|
7982
7982
|
return '<span title="'+wcEsc(title)+'" style="display:inline-flex;align-items:center;gap:3px;background:var(--bg3);border:1px solid '+(isOk?'var(--green3)':'var(--red)')+';border-radius:4px;padding:2px 6px;font-size:9px;font-family:var(--mono);color:'+color+'">' +
|
|
7983
7983
|
icon + ' ' + label + '</span>';
|
|
@@ -8371,7 +8371,8 @@ async function wcTriggerCrashFix(errorMsg) {
|
|
|
8371
8371
|
});
|
|
8372
8372
|
if (wcChatRunning) return;
|
|
8373
8373
|
}
|
|
8374
|
-
var
|
|
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
|
-
|
|
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;
|