nothumanallowed 13.5.58 → 13.5.60
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/README.md +78 -1
- package/package.json +1 -1
- package/src/commands/ui.mjs +29 -1
- package/src/constants.mjs +1 -1
- package/src/services/web-ui.mjs +32 -11
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# NotHumanAllowed
|
|
2
2
|
|
|
3
|
-
**38 specialized AI agents,
|
|
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
|
|
|
@@ -40,6 +40,83 @@ EmailAgent → WebSearchAgent → WriterAgent
|
|
|
40
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
|
|
41
41
|
- Open `nha ui` → click **Studio** in the sidebar
|
|
42
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
|
+
|
|
43
120
|
## Daily Operations (PAO)
|
|
44
121
|
|
|
45
122
|
Connect Gmail + Calendar. 5 specialist agents analyze your day.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "13.5.
|
|
3
|
+
"version": "13.5.60",
|
|
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
|
@@ -4632,12 +4632,40 @@ REGOLE CRITICHE:
|
|
|
4632
4632
|
}
|
|
4633
4633
|
|
|
4634
4634
|
// Parse and execute tool calls from response
|
|
4635
|
+
// Sanitize JSON from LLM: replace literal newlines inside JSON strings with \n
|
|
4636
|
+
// Models often write multiline strings without escaping, which breaks JSON.parse
|
|
4637
|
+
const sanitizeToolJson = (raw) => {
|
|
4638
|
+
// Replace literal CR/LF inside JSON string values with escaped versions
|
|
4639
|
+
// Strategy: walk char by char, track if we're inside a JSON string
|
|
4640
|
+
let out = '';
|
|
4641
|
+
let inStr = false;
|
|
4642
|
+
let escaped = false;
|
|
4643
|
+
for (let ci = 0; ci < raw.length; ci++) {
|
|
4644
|
+
const ch = raw[ci];
|
|
4645
|
+
if (escaped) { out += ch; escaped = false; continue; }
|
|
4646
|
+
if (ch === '\\') { out += ch; escaped = true; continue; }
|
|
4647
|
+
if (ch === '"') { inStr = !inStr; out += ch; continue; }
|
|
4648
|
+
if (inStr && (ch === '\n' || ch === '\r')) {
|
|
4649
|
+
out += ch === '\n' ? '\\n' : '\\r';
|
|
4650
|
+
continue;
|
|
4651
|
+
}
|
|
4652
|
+
out += ch;
|
|
4653
|
+
}
|
|
4654
|
+
return out;
|
|
4655
|
+
};
|
|
4656
|
+
|
|
4635
4657
|
const toolRegex = /<tool>([\s\S]*?)<\/tool>/g;
|
|
4636
4658
|
let toolMatch;
|
|
4637
4659
|
const toolResults = [];
|
|
4638
4660
|
while ((toolMatch = toolRegex.exec(fullResponse)) !== null) {
|
|
4639
4661
|
let toolCall;
|
|
4640
|
-
try {
|
|
4662
|
+
try {
|
|
4663
|
+
const raw = toolMatch[1].trim();
|
|
4664
|
+
toolCall = JSON.parse(sanitizeToolJson(raw));
|
|
4665
|
+
} catch(e) {
|
|
4666
|
+
sendEv({ type: 'tool', op: 'parse_error', path: '?', result: 'JSON malformato: ' + e.message.slice(0, 80) });
|
|
4667
|
+
continue;
|
|
4668
|
+
}
|
|
4641
4669
|
|
|
4642
4670
|
if (toolCall.op === 'read') {
|
|
4643
4671
|
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.60';
|
|
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
|
@@ -6984,16 +6984,23 @@ function wcChatPanelHtml() {
|
|
|
6984
6984
|
}
|
|
6985
6985
|
} else {
|
|
6986
6986
|
var toolBadges = (msg.tools || []).map(function(tool){
|
|
6987
|
-
var
|
|
6988
|
-
var
|
|
6989
|
-
|
|
6987
|
+
var isOk = tool.result === 'ok';
|
|
6988
|
+
var isParseErr = tool.op === 'parse_error';
|
|
6989
|
+
var icon = isParseErr ? '❓' : (tool.op === 'edit' ? '✎' : (tool.op === 'write' ? '➕' : '👁'));
|
|
6990
|
+
var color = isOk ? 'var(--green)' : 'var(--red)';
|
|
6991
|
+
var label = isParseErr ? ('JSON err: ' + wcEsc(tool.result)) : wcEsc(tool.path);
|
|
6992
|
+
var title = isOk ? tool.op + ': ' + tool.path : (tool.result || '');
|
|
6993
|
+
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+'">' +
|
|
6994
|
+
icon + ' ' + label + '</span>';
|
|
6990
6995
|
}).join(' ');
|
|
6991
|
-
|
|
6992
|
-
|
|
6993
|
-
|
|
6996
|
+
var agentText = wcEsc(msg.text.replace(new RegExp('<tool>[\\s\\S]*?<\\/tool>', 'g'), '').trim());
|
|
6997
|
+
messagesHtml += '<div style="margin:6px 12px;border:1px solid rgba(255,255,255,0.12);border-radius:10px;background:var(--bg3);overflow:hidden">' +
|
|
6998
|
+
'<div style="display:flex;align-items:center;gap:6px;padding:6px 10px;border-bottom:1px solid rgba(255,255,255,0.06);background:rgba(255,255,255,0.03)">' +
|
|
6999
|
+
'<span style="font-size:13px">🤖</span>' +
|
|
7000
|
+
'<span style="font-size:10px;font-weight:700;color:var(--green)">WebCraft Agent</span>' +
|
|
6994
7001
|
'</div>' +
|
|
6995
|
-
'<div style="font-size:11px;color:var(--text);line-height:1.6;white-space:pre-wrap
|
|
6996
|
-
(toolBadges ? '<div style="display:flex;flex-wrap:wrap;gap:4px;
|
|
7002
|
+
'<div style="padding:8px 10px;font-size:11px;color:var(--text);line-height:1.6;white-space:pre-wrap">'+agentText+'</div>' +
|
|
7003
|
+
(toolBadges ? '<div style="display:flex;flex-wrap:wrap;gap:4px;padding:6px 10px;border-top:1px solid rgba(255,255,255,0.06)">'+toolBadges+'</div>' : '') +
|
|
6997
7004
|
'</div>';
|
|
6998
7005
|
}
|
|
6999
7006
|
}
|
|
@@ -7024,9 +7031,9 @@ function wcChatPanelHtml() {
|
|
|
7024
7031
|
'</div>'
|
|
7025
7032
|
: '<div style="padding:4px 12px 0;font-size:10px;color:var(--dim)">📄 <strong style="color:var(--green)">'+wcEsc(wcState.projectName)+'</strong> — scrivi per modificare o migliorare il progetto</div>';
|
|
7026
7033
|
|
|
7027
|
-
return '<div style="border-top:1px solid var(--border);background:var(--bg2);flex-shrink:0;display:flex;flex-direction:column">' +
|
|
7034
|
+
return '<div style="border-top:1px solid var(--border);background:var(--bg2);flex-shrink:0;display:flex;flex-direction:column;min-height:220px">' +
|
|
7028
7035
|
// Messages
|
|
7029
|
-
'<div id="wcChatMessages" style="max-height:
|
|
7036
|
+
'<div id="wcChatMessages" style="max-height:240px;overflow-y:auto;padding:6px 0">' +
|
|
7030
7037
|
messagesHtml +
|
|
7031
7038
|
'</div>' +
|
|
7032
7039
|
// Attachments
|
|
@@ -7039,7 +7046,7 @@ function wcChatPanelHtml() {
|
|
|
7039
7046
|
'📎' +
|
|
7040
7047
|
'<input type="file" id="wcFileInput" multiple accept="image/*,.pdf" style="display:none" onchange="wcHandleFileAttach(this)">' +
|
|
7041
7048
|
'</label>' +
|
|
7042
|
-
'<textarea id="wcChatInput" rows="
|
|
7049
|
+
'<textarea id="wcChatInput" rows="4" placeholder="'+placeholder+'" '+(inputDisabled?'disabled':'')+' style="flex:1;padding:8px 10px;font-size:12px;border-radius:8px;border:1px solid var(--border2);background:var(--bg3);color:var(--text);resize:vertical;min-height:80px;line-height:1.5;font-family:inherit" onkeydown="wcChatKeydown(event)"></textarea>' +
|
|
7043
7050
|
'<button onclick="wcChatSend()" '+(inputDisabled?'disabled':'')+' style="padding:8px 14px;background:var(--green3);border:none;border-radius:8px;color:var(--bg);font-size:13px;font-weight:700;cursor:pointer;flex-shrink:0;height:38px">'+sendBtnLabel+'</button>' +
|
|
7044
7051
|
'</div>' +
|
|
7045
7052
|
'</div>';
|
|
@@ -7909,6 +7916,20 @@ async function wcStartSandbox() {
|
|
|
7909
7916
|
wcState.sandbox.running = false;
|
|
7910
7917
|
wcState.sandbox.error = evt.msg;
|
|
7911
7918
|
renderWebCraft(document.getElementById('content'));
|
|
7919
|
+
// Auto-fix: try to detect MODULE_NOT_FOUND in crash message and fix it
|
|
7920
|
+
var errMsg = evt.msg || '';
|
|
7921
|
+
var modMatch = errMsg.match(new RegExp("Cannot find module '([^']+)'")) ||
|
|
7922
|
+
errMsg.match(new RegExp('Cannot find module "([^"]+)"'));
|
|
7923
|
+
if (modMatch && _wcAutoFixAttempts < 3) {
|
|
7924
|
+
_wcAutoFixAttempts++;
|
|
7925
|
+
wcTriggerAutoFix(modMatch[1]);
|
|
7926
|
+
} else if (errMsg && !modMatch && _wcAutoFixAttempts < 3) {
|
|
7927
|
+
// Generic crash: post error to chat so agent can see it
|
|
7928
|
+
_wcAutoFixAttempts++;
|
|
7929
|
+
wcChat.push({ role: 'system', text: '❌ Errore sandbox: ' + errMsg });
|
|
7930
|
+
renderWebCraft(document.getElementById('content'));
|
|
7931
|
+
wcScrollChatToBottom();
|
|
7932
|
+
}
|
|
7912
7933
|
}
|
|
7913
7934
|
} catch(_) {}
|
|
7914
7935
|
}
|