nothumanallowed 13.5.59 → 13.5.61
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 +1 -1
- package/src/commands/ui.mjs +33 -2
- package/src/constants.mjs +1 -1
- package/src/services/web-ui.mjs +89 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "13.5.
|
|
3
|
+
"version": "13.5.61",
|
|
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
|
@@ -4225,7 +4225,10 @@ function sentinelMiddleware(req, res, next) {
|
|
|
4225
4225
|
}
|
|
4226
4226
|
next();
|
|
4227
4227
|
}
|
|
4228
|
-
|
|
4228
|
+
// Export both ways: default function (for require('./middleware/sentinel'))
|
|
4229
|
+
// and named export (for require('./middleware/sentinel').sentinelMiddleware)
|
|
4230
|
+
module.exports = sentinelMiddleware;
|
|
4231
|
+
module.exports.sentinelMiddleware = sentinelMiddleware;
|
|
4229
4232
|
`;
|
|
4230
4233
|
fs.mkdirSync(path.join(sandboxDir, 'server', 'middleware'), { recursive: true });
|
|
4231
4234
|
fs.writeFileSync(path.join(sandboxDir, 'server', 'middleware', 'sentinel.js'), sentinelShim, 'utf8');
|
|
@@ -4632,12 +4635,40 @@ REGOLE CRITICHE:
|
|
|
4632
4635
|
}
|
|
4633
4636
|
|
|
4634
4637
|
// Parse and execute tool calls from response
|
|
4638
|
+
// Sanitize JSON from LLM: replace literal newlines inside JSON strings with \n
|
|
4639
|
+
// Models often write multiline strings without escaping, which breaks JSON.parse
|
|
4640
|
+
const sanitizeToolJson = (raw) => {
|
|
4641
|
+
// Replace literal CR/LF inside JSON string values with escaped versions
|
|
4642
|
+
// Strategy: walk char by char, track if we're inside a JSON string
|
|
4643
|
+
let out = '';
|
|
4644
|
+
let inStr = false;
|
|
4645
|
+
let escaped = false;
|
|
4646
|
+
for (let ci = 0; ci < raw.length; ci++) {
|
|
4647
|
+
const ch = raw[ci];
|
|
4648
|
+
if (escaped) { out += ch; escaped = false; continue; }
|
|
4649
|
+
if (ch === '\\') { out += ch; escaped = true; continue; }
|
|
4650
|
+
if (ch === '"') { inStr = !inStr; out += ch; continue; }
|
|
4651
|
+
if (inStr && (ch === '\n' || ch === '\r')) {
|
|
4652
|
+
out += ch === '\n' ? '\\n' : '\\r';
|
|
4653
|
+
continue;
|
|
4654
|
+
}
|
|
4655
|
+
out += ch;
|
|
4656
|
+
}
|
|
4657
|
+
return out;
|
|
4658
|
+
};
|
|
4659
|
+
|
|
4635
4660
|
const toolRegex = /<tool>([\s\S]*?)<\/tool>/g;
|
|
4636
4661
|
let toolMatch;
|
|
4637
4662
|
const toolResults = [];
|
|
4638
4663
|
while ((toolMatch = toolRegex.exec(fullResponse)) !== null) {
|
|
4639
4664
|
let toolCall;
|
|
4640
|
-
try {
|
|
4665
|
+
try {
|
|
4666
|
+
const raw = toolMatch[1].trim();
|
|
4667
|
+
toolCall = JSON.parse(sanitizeToolJson(raw));
|
|
4668
|
+
} catch(e) {
|
|
4669
|
+
sendEv({ type: 'tool', op: 'parse_error', path: '?', result: 'JSON malformato: ' + e.message.slice(0, 80) });
|
|
4670
|
+
continue;
|
|
4671
|
+
}
|
|
4641
4672
|
|
|
4642
4673
|
if (toolCall.op === 'read') {
|
|
4643
4674
|
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.61';
|
|
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
|
@@ -6975,8 +6975,14 @@ function wcChatPanelHtml() {
|
|
|
6975
6975
|
'</div>';
|
|
6976
6976
|
}
|
|
6977
6977
|
} else if (msg.role === 'system') {
|
|
6978
|
-
// System messages: compact notices (snapshot, syntax check,
|
|
6979
|
-
|
|
6978
|
+
// System messages: compact notices (snapshot, syntax check, error with fix button)
|
|
6979
|
+
var isSandboxErr = (msg.text || '').indexOf('Errore sandbox') !== -1;
|
|
6980
|
+
var borderColor = isSandboxErr ? '#ef4444' : 'var(--border2)';
|
|
6981
|
+
var textColor = isSandboxErr ? '#fca5a5' : 'var(--dim)';
|
|
6982
|
+
messagesHtml += '<div style="margin:4px 12px;padding:6px 10px;background:var(--bg3);border-left:2px solid '+borderColor+';border-radius:4px;font-size:10px;color:'+textColor+';display:flex;align-items:center;gap:8px">' +
|
|
6983
|
+
'<span style="flex:1">' + (msg.text||'') + '</span>' +
|
|
6984
|
+
(isSandboxErr ? '<button onclick="wcFixSandboxError()" style="flex-shrink:0;padding:4px 10px;background:#7f1d1d;border:1px solid #ef4444;border-radius:5px;color:#fca5a5;font-size:10px;font-weight:700;cursor:pointer">🤖 Correggi</button>' : '') +
|
|
6985
|
+
'</div>';
|
|
6980
6986
|
if (msg.syntaxErrors && msg.syntaxErrors.length) {
|
|
6981
6987
|
messagesHtml += '<div style="margin:2px 12px">' + msg.syntaxErrors.map(function(e2){
|
|
6982
6988
|
return '<div style="font-size:10px;font-family:var(--mono);color:#f87171;padding:2px 0">✕ ' + wcEsc(e2.file) + ': ' + wcEsc(e2.error) + '</div>';
|
|
@@ -6984,16 +6990,23 @@ function wcChatPanelHtml() {
|
|
|
6984
6990
|
}
|
|
6985
6991
|
} else {
|
|
6986
6992
|
var toolBadges = (msg.tools || []).map(function(tool){
|
|
6987
|
-
var
|
|
6988
|
-
var
|
|
6989
|
-
|
|
6993
|
+
var isOk = tool.result === 'ok';
|
|
6994
|
+
var isParseErr = tool.op === 'parse_error';
|
|
6995
|
+
var icon = isParseErr ? '❓' : (tool.op === 'edit' ? '✎' : (tool.op === 'write' ? '➕' : '👁'));
|
|
6996
|
+
var color = isOk ? 'var(--green)' : 'var(--red)';
|
|
6997
|
+
var label = isParseErr ? ('JSON err: ' + wcEsc(tool.result)) : wcEsc(tool.path);
|
|
6998
|
+
var title = isOk ? tool.op + ': ' + tool.path : (tool.result || '');
|
|
6999
|
+
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+'">' +
|
|
7000
|
+
icon + ' ' + label + '</span>';
|
|
6990
7001
|
}).join(' ');
|
|
6991
|
-
|
|
6992
|
-
|
|
6993
|
-
|
|
7002
|
+
var agentText = wcEsc(msg.text.replace(new RegExp('<tool>[\\s\\S]*?<\\/tool>', 'g'), '').trim());
|
|
7003
|
+
messagesHtml += '<div style="margin:6px 12px;border:1px solid rgba(255,255,255,0.12);border-radius:10px;background:var(--bg3);overflow:hidden">' +
|
|
7004
|
+
'<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)">' +
|
|
7005
|
+
'<span style="font-size:13px">🤖</span>' +
|
|
7006
|
+
'<span style="font-size:10px;font-weight:700;color:var(--green)">WebCraft Agent</span>' +
|
|
6994
7007
|
'</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;
|
|
7008
|
+
'<div style="padding:8px 10px;font-size:11px;color:var(--text);line-height:1.6;white-space:pre-wrap">'+agentText+'</div>' +
|
|
7009
|
+
(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
7010
|
'</div>';
|
|
6998
7011
|
}
|
|
6999
7012
|
}
|
|
@@ -7850,7 +7863,12 @@ function wcSandboxPanelHtml() {
|
|
|
7850
7863
|
|
|
7851
7864
|
return '<div style="display:flex;flex-direction:column;flex:1;min-height:0;overflow-y:auto">' +
|
|
7852
7865
|
phasesHtml +
|
|
7853
|
-
(sb.error ?
|
|
7866
|
+
(sb.error ?
|
|
7867
|
+
'<div style="padding:10px 14px;border-top:1px solid var(--border);display:flex;align-items:flex-start;gap:10px;flex-wrap:wrap">' +
|
|
7868
|
+
'<div style="flex:1;min-width:0;font-size:11px;font-family:var(--mono);color:var(--red);white-space:pre-wrap;word-break:break-all">❌ '+wcEsc(sb.error)+'</div>' +
|
|
7869
|
+
'<button onclick="wcFixSandboxError()" style="flex-shrink:0;padding:6px 14px;background:#7f1d1d;border:1px solid #ef4444;border-radius:6px;color:#fca5a5;font-size:11px;font-weight:700;cursor:pointer;white-space:nowrap">🤖 Correggi</button>' +
|
|
7870
|
+
'</div>'
|
|
7871
|
+
: '') +
|
|
7854
7872
|
'</div>';
|
|
7855
7873
|
}
|
|
7856
7874
|
|
|
@@ -7941,6 +7959,66 @@ async function wcStopSandbox() {
|
|
|
7941
7959
|
renderWebCraft(document.getElementById('content'));
|
|
7942
7960
|
}
|
|
7943
7961
|
|
|
7962
|
+
// "Correggi" button — sends full sandbox error to the agent for repair
|
|
7963
|
+
async function wcFixSandboxError() {
|
|
7964
|
+
var errText = wcState.sandbox.error || 'Errore sconosciuto avviando il server sandbox';
|
|
7965
|
+
// Put error in chat input so user can see it, then fire agent
|
|
7966
|
+
var fixMsg = 'ERRORE SANDBOX — il server Node.js non si avvia. Analizza tutti i file del progetto, trova la causa e correggi.' +
|
|
7967
|
+
String.fromCharCode(10) + String.fromCharCode(10) +
|
|
7968
|
+
'STACKTRACE COMPLETO:' + String.fromCharCode(10) + errText;
|
|
7969
|
+
// Push as user message so it appears in chat
|
|
7970
|
+
wcChat.push({ role: 'user', text: '🤖 Correggi errore sandbox' });
|
|
7971
|
+
wcScrollChatToBottom();
|
|
7972
|
+
wcChatRunning = true;
|
|
7973
|
+
renderWebCraft(document.getElementById('content'));
|
|
7974
|
+
|
|
7975
|
+
try {
|
|
7976
|
+
var r = await fetch(API + '/api/studio/webcraft/agent', {
|
|
7977
|
+
method: 'POST',
|
|
7978
|
+
headers: { 'Content-Type': 'application/json' },
|
|
7979
|
+
body: JSON.stringify({ projectName: wcState.projectName, message: fixMsg, autofix: true })
|
|
7980
|
+
});
|
|
7981
|
+
if (!r.ok) { wcChatRunning = false; renderWebCraft(document.getElementById('content')); return; }
|
|
7982
|
+
var agentMsg = { role: 'agent', text: '', tools: [] };
|
|
7983
|
+
wcChat.push(agentMsg);
|
|
7984
|
+
var reader4 = r.body.getReader();
|
|
7985
|
+
var dec4 = new TextDecoder();
|
|
7986
|
+
var buf4 = '';
|
|
7987
|
+
while (true) {
|
|
7988
|
+
var res4 = await reader4.read();
|
|
7989
|
+
if (res4.done) break;
|
|
7990
|
+
buf4 += dec4.decode(res4.value, { stream: true });
|
|
7991
|
+
var parts4 = buf4.split(String.fromCharCode(10) + String.fromCharCode(10));
|
|
7992
|
+
buf4 = parts4.pop();
|
|
7993
|
+
for (var pi4 = 0; pi4 < parts4.length; pi4++) {
|
|
7994
|
+
var line4 = parts4[pi4].replace(/^data: /, '').trim();
|
|
7995
|
+
if (!line4) continue;
|
|
7996
|
+
try {
|
|
7997
|
+
var ev4 = JSON.parse(line4);
|
|
7998
|
+
if (ev4.type === 'text') { agentMsg.text += ev4.token; renderWebCraft(document.getElementById('content')); wcScrollChatToBottom(); }
|
|
7999
|
+
else if (ev4.type === 'tool') { agentMsg.tools.push({ op: ev4.op, path: ev4.path, result: ev4.result }); renderWebCraft(document.getElementById('content')); }
|
|
8000
|
+
else if (ev4.type === 'done') {
|
|
8001
|
+
wcChatRunning = false;
|
|
8002
|
+
if (ev4.changed) {
|
|
8003
|
+
// Files changed — syntax check then offer to restart
|
|
8004
|
+
wcChat.push({ role: 'system', text: '✅ Fix applicato. Clicca ▶ Avvia Sandbox per ritentare.' });
|
|
8005
|
+
}
|
|
8006
|
+
renderWebCraft(document.getElementById('content'));
|
|
8007
|
+
wcScrollChatToBottom();
|
|
8008
|
+
} else if (ev4.type === 'restart_sandbox') {
|
|
8009
|
+
wcState.sandbox = { running: false, port: null, dir: null, logs: [], error: null };
|
|
8010
|
+
setTimeout(function(){ wcStartSandbox(); }, 800);
|
|
8011
|
+
}
|
|
8012
|
+
} catch(_) {}
|
|
8013
|
+
}
|
|
8014
|
+
}
|
|
8015
|
+
} catch(e2) {
|
|
8016
|
+
wcChatRunning = false;
|
|
8017
|
+
wcChat.push({ role: 'system', text: '❌ Errore chiamata agente: ' + e2.message });
|
|
8018
|
+
renderWebCraft(document.getElementById('content'));
|
|
8019
|
+
}
|
|
8020
|
+
}
|
|
8021
|
+
|
|
7944
8022
|
var _wcLastDownload = 0;
|
|
7945
8023
|
function wcDownloadZip() {
|
|
7946
8024
|
if (!wcState.generatedFiles.length) return;
|