nothumanallowed 13.5.87 → 13.5.89
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/services/web-ui.mjs +130 -92
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "13.5.
|
|
3
|
+
"version": "13.5.89",
|
|
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/services/web-ui.mjs
CHANGED
|
@@ -6528,7 +6528,11 @@ var wcState = {
|
|
|
6528
6528
|
logs: [],
|
|
6529
6529
|
error: null
|
|
6530
6530
|
},
|
|
6531
|
-
lastGenStats: null
|
|
6531
|
+
lastGenStats: null,
|
|
6532
|
+
repairing: false,
|
|
6533
|
+
repairTotal: 0,
|
|
6534
|
+
repairDone: 0,
|
|
6535
|
+
repairCurrent: ''
|
|
6532
6536
|
};
|
|
6533
6537
|
var wcRightTab = 'files';
|
|
6534
6538
|
var wcMainTab = 'new'; // 'new' | 'projects'
|
|
@@ -6550,6 +6554,10 @@ var _wcOverlayTimer = null; // inactivity timer to restore overlay
|
|
|
6550
6554
|
var _wcGenAbortCtrl = null; // AbortController for generation stop
|
|
6551
6555
|
var _wcSyntaxResults = []; // [{file, ok, error}]
|
|
6552
6556
|
var _wcSnapshots = []; // [{ts, fileCount}]
|
|
6557
|
+
var _wcLastFilePlan = []; // saved for manual repair trigger
|
|
6558
|
+
var _wcLastSysPreamble = '';
|
|
6559
|
+
var _wcTokIn = 0; // global token counters (accumulate across generation + repair)
|
|
6560
|
+
var _wcTokOut = 0;
|
|
6553
6561
|
// Skills state
|
|
6554
6562
|
var wcSkills = []; // [{name, content, type}] type: 'skill'|'memory'|'provider'
|
|
6555
6563
|
var wcSkillModal = null; // null | {mode:'edit'|'new', idx:number|null, name, content, type, generating}
|
|
@@ -6694,6 +6702,13 @@ function renderWebCraft(el) {
|
|
|
6694
6702
|
(wcState.running ?
|
|
6695
6703
|
'<div style="width:100%;padding:11px;background:var(--bg3);border:1px solid var(--border);border-radius:8px;color:var(--dim);font-size:12px;text-align:center">⏳ '+t('wc_generating')+'...</div>'
|
|
6696
6704
|
: '') +
|
|
6705
|
+
(wcState.repairing ?
|
|
6706
|
+
'<div style="width:100%;padding:10px 12px;background:rgba(234,179,8,0.08);border:1px solid rgba(234,179,8,0.4);border-radius:8px;display:flex;flex-direction:column;gap:4px">' +
|
|
6707
|
+
'<div style="display:flex;align-items:center;gap:6px;font-size:11px;color:#facc15;font-weight:600">🔧 Correzione automatica in corso...</div>' +
|
|
6708
|
+
'<div style="font-size:10px;color:var(--dim)">'+wcState.repairDone+' / '+wcState.repairTotal+' file</div>' +
|
|
6709
|
+
(wcState.repairCurrent ? '<div style="font-size:10px;color:#fde68a;font-family:var(--mono);overflow:hidden;text-overflow:ellipsis;white-space:nowrap">'+wcEsc(wcState.repairCurrent)+'</div>' : '') +
|
|
6710
|
+
'</div>'
|
|
6711
|
+
: '') +
|
|
6697
6712
|
(wcState.generatedFiles.length > 0 && !wcState.running ?
|
|
6698
6713
|
'<div style="display:flex;gap:6px;flex-wrap:wrap">' +
|
|
6699
6714
|
'<button onclick="wcDownloadZip()" style="flex:1;padding:9px;background:var(--bg3);border:1px solid var(--border2);border-radius:8px;color:var(--text);font-size:11px;font-weight:600;cursor:pointer">⇩ ZIP</button>' +
|
|
@@ -6701,6 +6716,9 @@ function renderWebCraft(el) {
|
|
|
6701
6716
|
'<button onclick="wcToggleGrep()" title="Cerca nel codice" style="padding:9px 10px;background:'+(_wcGrepOpen?'var(--greendim)':'var(--bg3)')+';border:1px solid '+(_wcGrepOpen?'var(--green3)':'var(--border2)')+';border-radius:8px;color:'+(_wcGrepOpen?'var(--green)':'var(--dim)')+';font-size:11px;cursor:pointer">🔍</button>' +
|
|
6702
6717
|
'<button onclick="wcManualSnapshot()" title="Salva snapshot" style="padding:9px 10px;background:var(--bg3);border:1px solid var(--border2);border-radius:8px;color:var(--dim);font-size:11px;cursor:pointer">💾</button>' +
|
|
6703
6718
|
'</div>' +
|
|
6719
|
+
(wcState.generatedFiles.some(function(f){ return f._error || f._syntaxError; }) && !wcState.repairing ?
|
|
6720
|
+
'<button onclick="wcTriggerRepair()" style="width:100%;padding:9px;background:rgba(234,179,8,0.08);border:1px solid rgba(234,179,8,0.5);border-radius:8px;color:#facc15;font-size:11px;font-weight:600;cursor:pointer">🔧 Correggi tutti i file rossi</button>'
|
|
6721
|
+
: '') +
|
|
6704
6722
|
'<button onclick="wcStartSandbox()" id="wcSandboxBtn" style="width:100%;padding:10px;background:var(--bg3);border:1px solid var(--green3);border-radius:8px;color:var(--green);font-size:12px;font-weight:600;cursor:pointer">▶ '+t('wc_sandbox_start')+'</button>' +
|
|
6705
6723
|
(wcState.lastGenStats ? '<div style="padding:6px 8px;background:var(--bg3);border:1px solid var(--border);border-radius:6px;font-size:10px;color:var(--dim);font-family:var(--mono);display:flex;flex-wrap:wrap;gap:6px">' +
|
|
6706
6724
|
'<span>⏱ '+(wcState.lastGenStats.seconds >= 60 ? Math.floor(wcState.lastGenStats.seconds/60)+'m '+(wcState.lastGenStats.seconds%60)+'s' : wcState.lastGenStats.seconds+'s')+'</span>' +
|
|
@@ -7916,9 +7934,11 @@ async function wcGenerate() {
|
|
|
7916
7934
|
|
|
7917
7935
|
var _nl = String.fromCharCode(10);
|
|
7918
7936
|
var sysPreamble = 'You are an expert full-stack engineer generating production-quality code.' + _nl + _nl + 'SECURITY RULES (non-negotiable):' + _nl + SECURITY_RULES + _nl + _nl + 'Project: ' + projName + _nl + 'Description: ' + desc + _nl + 'Enabled blocks: ' + blocksEnabled + _nl + _nl + 'Generate ONLY the file content requested. No explanations, no markdown code fences, no comments like "here is the file". Output raw file content only.';
|
|
7937
|
+
_wcLastFilePlan = filePlan;
|
|
7938
|
+
_wcLastSysPreamble = sysPreamble;
|
|
7919
7939
|
|
|
7920
7940
|
var _wcGenStartTime = Date.now();
|
|
7921
|
-
|
|
7941
|
+
_wcTokIn = 0; _wcTokOut = 0; // reset global counters for this generation run
|
|
7922
7942
|
var _wcTimerInterval = null;
|
|
7923
7943
|
|
|
7924
7944
|
function wcGenElapsed() {
|
|
@@ -8023,103 +8043,114 @@ async function wcGenerate() {
|
|
|
8023
8043
|
renderWebCraft(document.getElementById('content'));
|
|
8024
8044
|
}
|
|
8025
8045
|
|
|
8026
|
-
|
|
8027
|
-
|
|
8028
|
-
|
|
8029
|
-
|
|
8030
|
-
|
|
8031
|
-
|
|
8032
|
-
|
|
8033
|
-
|
|
8034
|
-
|
|
8035
|
-
|
|
8036
|
-
|
|
8037
|
-
|
|
8038
|
-
|
|
8039
|
-
for (var gi = 0; gi < wcState.generatedFiles.length; gi++) {
|
|
8040
|
-
if (wcState.generatedFiles[gi].name === rfp.name) {
|
|
8041
|
-
wcState.generatedFiles[gi] = { name: rfp.name, content: retryContent, lang: rfp.lang };
|
|
8042
|
-
break;
|
|
8043
|
-
}
|
|
8044
|
-
}
|
|
8045
|
-
renderWebCraft(document.getElementById('content'));
|
|
8046
|
-
} catch(re) {
|
|
8047
|
-
if (re && re.name === 'AbortError') break;
|
|
8048
|
-
// Keep as error — already in generatedFiles
|
|
8049
|
-
}
|
|
8050
|
-
}
|
|
8051
|
-
}
|
|
8046
|
+
if (_wcTimerInterval) { clearInterval(_wcTimerInterval); _wcTimerInterval = null; }
|
|
8047
|
+
|
|
8048
|
+
wcState.running = false;
|
|
8049
|
+
_wcGenAbortCtrl = null;
|
|
8050
|
+
_wcOverlayMinimized = false;
|
|
8051
|
+
|
|
8052
|
+
// Auto-save
|
|
8053
|
+
try {
|
|
8054
|
+
await fetch(API + '/api/studio/webcraft/projects/save', {
|
|
8055
|
+
method: 'POST', headers: {'Content-Type':'application/json'},
|
|
8056
|
+
body: JSON.stringify({ projectName: wcState.projectName, description: wcState.description, files: wcState.generatedFiles })
|
|
8057
|
+
});
|
|
8058
|
+
} catch(_) {}
|
|
8052
8059
|
|
|
8053
|
-
//
|
|
8054
|
-
// Zero LLM calls — pure structural check on every generated file
|
|
8055
|
-
// Files with syntax errors get _syntaxError set and are re-queued for retry
|
|
8056
|
-
var syntaxFailedNames = [];
|
|
8060
|
+
// Post-generation syntax scan — mark truncated/broken files before repair
|
|
8057
8061
|
wcState.generatedFiles.forEach(function(f) {
|
|
8058
|
-
if (f._error
|
|
8059
|
-
var
|
|
8060
|
-
|
|
8061
|
-
if (!check.ok) {
|
|
8062
|
-
f._syntaxError = check.reason;
|
|
8063
|
-
syntaxFailedNames.push(f.name);
|
|
8064
|
-
} else {
|
|
8065
|
-
delete f._syntaxError;
|
|
8066
|
-
}
|
|
8062
|
+
if (f._error || f._pending || !f.content) return;
|
|
8063
|
+
var chk = wcSyntaxCheck(f.content, f.lang || '');
|
|
8064
|
+
if (!chk.ok) f._syntaxError = chk.reason;
|
|
8067
8065
|
});
|
|
8068
8066
|
|
|
8069
|
-
|
|
8070
|
-
|
|
8071
|
-
|
|
8072
|
-
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
|
|
8076
|
-
|
|
8077
|
-
|
|
8078
|
-
|
|
8079
|
-
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
|
|
8084
|
-
|
|
8085
|
-
|
|
8086
|
-
|
|
8087
|
-
|
|
8088
|
-
|
|
8089
|
-
|
|
8090
|
-
|
|
8091
|
-
|
|
8092
|
-
|
|
8093
|
-
|
|
8094
|
-
|
|
8095
|
-
|
|
8096
|
-
|
|
8097
|
-
|
|
8098
|
-
|
|
8099
|
-
|
|
8100
|
-
|
|
8067
|
+
renderWebCraft(document.getElementById('content'));
|
|
8068
|
+
|
|
8069
|
+
// Auto-repair: run immediately after generation completes
|
|
8070
|
+
await wcAutoRepair(filePlan, sysPreamble);
|
|
8071
|
+
|
|
8072
|
+
// Update stats AFTER repair so token counts include repair calls
|
|
8073
|
+
wcState.lastGenStats = { tokIn: _wcTokIn, tokOut: _wcTokOut, seconds: Math.floor((Date.now() - _wcGenStartTime) / 1000), files: wcState.generatedFiles.length };
|
|
8074
|
+
renderWebCraft(document.getElementById('content'));
|
|
8075
|
+
}
|
|
8076
|
+
|
|
8077
|
+
// ── Auto-repair pass — fixes _error and _syntaxError files ────────────────
|
|
8078
|
+
// Called automatically after generation and available as manual button
|
|
8079
|
+
var _wcRepairRunning = false;
|
|
8080
|
+
async function wcAutoRepair(filePlan, sysPreamble) {
|
|
8081
|
+
if (_wcRepairRunning) return;
|
|
8082
|
+
// Collect broken files: LLM errors + syntax errors
|
|
8083
|
+
var toFix = wcState.generatedFiles.filter(function(f){ return f._error || f._syntaxError; });
|
|
8084
|
+
if (toFix.length === 0) return;
|
|
8085
|
+
|
|
8086
|
+
_wcRepairRunning = true;
|
|
8087
|
+
wcState.repairing = true;
|
|
8088
|
+
wcState.repairTotal = toFix.length;
|
|
8089
|
+
wcState.repairDone = 0;
|
|
8090
|
+
renderWebCraft(document.getElementById('content'));
|
|
8091
|
+
|
|
8092
|
+
// Build a map name→plan for prompt lookup
|
|
8093
|
+
var planMap = {};
|
|
8094
|
+
if (filePlan) filePlan.forEach(function(fp){ planMap[fp.name] = fp; });
|
|
8095
|
+
|
|
8096
|
+
var _nl3 = String.fromCharCode(10);
|
|
8097
|
+
var sysBase = sysPreamble || ('You are an expert full-stack engineer. Output ONLY the complete corrected file content. No explanations, no markdown fences.');
|
|
8098
|
+
|
|
8099
|
+
for (var ri = 0; ri < toFix.length; ri++) {
|
|
8100
|
+
var broken = toFix[ri];
|
|
8101
|
+
var plan = planMap[broken.name];
|
|
8102
|
+
wcState.repairDone = ri;
|
|
8103
|
+
wcState.repairCurrent = broken.name;
|
|
8104
|
+
renderWebCraft(document.getElementById('content'));
|
|
8105
|
+
|
|
8106
|
+
await new Promise(function(resolve){ setTimeout(resolve, 2000); });
|
|
8107
|
+
try {
|
|
8108
|
+
var fixSys = sysBase + _nl3 + 'You are fixing a broken or truncated file. Output ONLY the complete corrected file. No fences, no explanations.';
|
|
8109
|
+
var fixUser;
|
|
8110
|
+
if (broken._error) {
|
|
8111
|
+
// LLM failed entirely — regenerate from original prompt
|
|
8112
|
+
fixUser = plan
|
|
8113
|
+
? plan.prompt + _nl3 + _nl3 + 'File to generate: ' + broken.name
|
|
8114
|
+
: 'Regenerate the file: ' + broken.name;
|
|
8115
|
+
} else {
|
|
8116
|
+
// Syntax error — pass existing content + error for targeted fix
|
|
8117
|
+
fixUser = 'File: ' + broken.name + _nl3 +
|
|
8118
|
+
'Error: ' + (broken._syntaxError || 'truncated/incomplete') + _nl3 + _nl3 +
|
|
8119
|
+
'Current broken content (last 800 chars shown if long):' + _nl3 +
|
|
8120
|
+
(broken.content.length > 800 ? broken.content.slice(0, 400) + _nl3 + '...' + _nl3 + broken.content.slice(-400) : broken.content) + _nl3 + _nl3 +
|
|
8121
|
+
'Output the COMPLETE corrected file from the beginning.';
|
|
8122
|
+
}
|
|
8123
|
+
var fixed = await wcCallLLM(fixSys, fixUser, null, broken.lang || plan && plan.lang);
|
|
8124
|
+
var _fence3 = String.fromCharCode(96,96,96);
|
|
8125
|
+
var fixLines = fixed.split(_nl3);
|
|
8126
|
+
if (fixLines.length > 0 && fixLines[0].indexOf(_fence3) === 0) fixLines.shift();
|
|
8127
|
+
if (fixLines.length > 0 && fixLines[fixLines.length-1].trim() === _fence3) fixLines.pop();
|
|
8128
|
+
fixed = fixLines.join(_nl3).trim();
|
|
8129
|
+
var lang2 = broken.lang || (plan && plan.lang) || 'text';
|
|
8130
|
+
var check2 = wcSyntaxCheck(fixed, lang2);
|
|
8131
|
+
for (var gi3 = 0; gi3 < wcState.generatedFiles.length; gi3++) {
|
|
8132
|
+
if (wcState.generatedFiles[gi3].name === broken.name) {
|
|
8133
|
+
wcState.generatedFiles[gi3] = { name: broken.name, content: fixed, lang: lang2 };
|
|
8134
|
+
if (!check2.ok) wcState.generatedFiles[gi3]._syntaxError = check2.reason;
|
|
8135
|
+
break;
|
|
8101
8136
|
}
|
|
8102
|
-
renderWebCraft(document.getElementById('content'));
|
|
8103
|
-
} catch(se) {
|
|
8104
|
-
if (se && se.name === 'AbortError') break;
|
|
8105
8137
|
}
|
|
8106
|
-
}
|
|
8138
|
+
} catch(e) { /* keep as broken */ }
|
|
8139
|
+
|
|
8140
|
+
wcState.repairDone = ri + 1;
|
|
8141
|
+
renderWebCraft(document.getElementById('content'));
|
|
8107
8142
|
}
|
|
8108
8143
|
|
|
8109
|
-
|
|
8110
|
-
|
|
8144
|
+
_wcRepairRunning = false;
|
|
8145
|
+
wcState.repairing = false;
|
|
8146
|
+
wcState.repairTotal = 0;
|
|
8147
|
+
wcState.repairDone = 0;
|
|
8148
|
+
wcState.repairCurrent = '';
|
|
8111
8149
|
|
|
8112
|
-
|
|
8113
|
-
_wcGenAbortCtrl = null;
|
|
8114
|
-
_wcOverlayMinimized = false;
|
|
8115
|
-
// Store final stats for display after generation
|
|
8116
|
-
wcState.lastGenStats = { tokIn: _wcTokIn, tokOut: _wcTokOut, seconds: _wcGenTotalTime, files: wcState.generatedFiles.length };
|
|
8117
|
-
|
|
8118
|
-
// Auto-save project to ~/.nha/webcraft/<projectName>/
|
|
8150
|
+
// Save after repair
|
|
8119
8151
|
try {
|
|
8120
8152
|
await fetch(API + '/api/studio/webcraft/projects/save', {
|
|
8121
|
-
method: 'POST',
|
|
8122
|
-
headers: {'Content-Type':'application/json'},
|
|
8153
|
+
method: 'POST', headers: {'Content-Type':'application/json'},
|
|
8123
8154
|
body: JSON.stringify({ projectName: wcState.projectName, description: wcState.description, files: wcState.generatedFiles })
|
|
8124
8155
|
});
|
|
8125
8156
|
} catch(_) {}
|
|
@@ -8127,6 +8158,12 @@ async function wcGenerate() {
|
|
|
8127
8158
|
renderWebCraft(document.getElementById('content'));
|
|
8128
8159
|
}
|
|
8129
8160
|
|
|
8161
|
+
// Manual trigger for repair — called from "Correggi tutti" button
|
|
8162
|
+
function wcTriggerRepair() {
|
|
8163
|
+
if (_wcRepairRunning) return;
|
|
8164
|
+
wcAutoRepair(_wcLastFilePlan, _wcLastSysPreamble);
|
|
8165
|
+
}
|
|
8166
|
+
|
|
8130
8167
|
// Quick structural check — returns {ok, reason} without calling the LLM
|
|
8131
8168
|
// Reads only structure (braces, tags) — does NOT add content to any context
|
|
8132
8169
|
function wcSyntaxCheck(content, lang) {
|
|
@@ -8207,12 +8244,12 @@ async function wcCallLLMRaw(sys, user, signal) {
|
|
|
8207
8244
|
var d = await r.json();
|
|
8208
8245
|
// Accumulate token counts if the server returns usage data
|
|
8209
8246
|
if (d && d.usage) {
|
|
8210
|
-
|
|
8211
|
-
|
|
8247
|
+
_wcTokIn += (d.usage.prompt_tokens || d.usage.input_tokens || 0);
|
|
8248
|
+
_wcTokOut += (d.usage.completion_tokens || d.usage.output_tokens || 0);
|
|
8212
8249
|
} else if (d && d.text) {
|
|
8213
8250
|
// Estimate from char count (4 chars ≈ 1 token)
|
|
8214
|
-
|
|
8215
|
-
|
|
8251
|
+
_wcTokIn += Math.round((sys.length + user.length) / 4);
|
|
8252
|
+
_wcTokOut += Math.round((d.text || '').length / 4);
|
|
8216
8253
|
}
|
|
8217
8254
|
return (d && (d.text || d.content || d.result)) || '';
|
|
8218
8255
|
}
|
|
@@ -8381,6 +8418,7 @@ async function wcStartSandbox() {
|
|
|
8381
8418
|
wcState.sandbox = { running: true, port: null, dir: null, logs: [], error: null };
|
|
8382
8419
|
wcState.rightTab = 'preview';
|
|
8383
8420
|
wcRightTab = 'preview';
|
|
8421
|
+
_wcSkillsLoaded = false; // force skill panel reload after sandbox completes
|
|
8384
8422
|
renderWebCraft(document.getElementById('content'));
|
|
8385
8423
|
|
|
8386
8424
|
try {
|