nothumanallowed 13.5.83 → 13.5.85
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 +98 -22
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "13.5.
|
|
3
|
+
"version": "13.5.85",
|
|
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
|
@@ -6527,7 +6527,8 @@ var wcState = {
|
|
|
6527
6527
|
dir: null,
|
|
6528
6528
|
logs: [],
|
|
6529
6529
|
error: null
|
|
6530
|
-
}
|
|
6530
|
+
},
|
|
6531
|
+
lastGenStats: null
|
|
6531
6532
|
};
|
|
6532
6533
|
var wcRightTab = 'files';
|
|
6533
6534
|
var wcMainTab = 'new'; // 'new' | 'projects'
|
|
@@ -6569,9 +6570,11 @@ function renderWebCraft(el) {
|
|
|
6569
6570
|
wcState.generatedFiles.map(function(f,i){
|
|
6570
6571
|
var active = i === wcState.activeFile;
|
|
6571
6572
|
var hasErr = !!f._error || !!f._syntaxError;
|
|
6572
|
-
var
|
|
6573
|
+
var isPending = !!f._pending;
|
|
6574
|
+
var tabColor = hasErr ? (active ? '#f87171' : '#7f4040') : isPending ? (active ? '#9ca3af' : '#4b5563') : (active ? 'var(--green)' : 'var(--dim)');
|
|
6573
6575
|
var tabBorder = hasErr ? (active ? '#f87171' : 'transparent') : (active ? 'var(--green3)' : 'transparent');
|
|
6574
|
-
|
|
6576
|
+
var tabPrefix = hasErr ? '⚠ ' : isPending ? '⌛ ' : '';
|
|
6577
|
+
return '<button id="wcTab'+i+'" onclick="wcSetFile('+i+')" style="padding:6px 14px;font-size:11px;font-family:var(--mono);font-weight:'+(active?'700':'400')+';background:'+(active?'var(--bg3)':'transparent')+';border:none;border-bottom:2px solid '+tabBorder+';color:'+tabColor+';cursor:pointer;white-space:nowrap;flex-shrink:0">'+tabPrefix+wcEsc(f.name)+'</button>';
|
|
6575
6578
|
}).join('') +
|
|
6576
6579
|
'</div>'
|
|
6577
6580
|
: '';
|
|
@@ -6661,7 +6664,13 @@ function renderWebCraft(el) {
|
|
|
6661
6664
|
'<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>' +
|
|
6662
6665
|
'<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>' +
|
|
6663
6666
|
'</div>' +
|
|
6664
|
-
'<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>'
|
|
6667
|
+
'<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>' +
|
|
6668
|
+
(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">' +
|
|
6669
|
+
'<span>⏱ '+(wcState.lastGenStats.seconds >= 60 ? Math.floor(wcState.lastGenStats.seconds/60)+'m '+(wcState.lastGenStats.seconds%60)+'s' : wcState.lastGenStats.seconds+'s')+'</span>' +
|
|
6670
|
+
'<span>⇧ '+wcState.lastGenStats.tokIn.toLocaleString()+' tok in</span>' +
|
|
6671
|
+
'<span>⇩ '+wcState.lastGenStats.tokOut.toLocaleString()+' tok out</span>' +
|
|
6672
|
+
'<span>📄 '+wcState.lastGenStats.files+' file</span>' +
|
|
6673
|
+
'</div>' : '')
|
|
6665
6674
|
: '') +
|
|
6666
6675
|
'</div>' +
|
|
6667
6676
|
'<div data-wc-files style="position:relative;flex:1;min-width:0;background:var(--bg2);border:1px solid var(--border);border-radius:10px;display:flex;flex-direction:column;height:100%;overflow:hidden">' +
|
|
@@ -7870,11 +7879,35 @@ async function wcGenerate() {
|
|
|
7870
7879
|
var _nl = String.fromCharCode(10);
|
|
7871
7880
|
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.';
|
|
7872
7881
|
|
|
7882
|
+
var _wcGenStartTime = Date.now();
|
|
7883
|
+
var _wcTokIn = 0, _wcTokOut = 0;
|
|
7884
|
+
var _wcTimerInterval = null;
|
|
7885
|
+
|
|
7886
|
+
function wcGenElapsed() {
|
|
7887
|
+
var s = Math.floor((Date.now() - _wcGenStartTime) / 1000);
|
|
7888
|
+
var m = Math.floor(s / 60); s = s % 60;
|
|
7889
|
+
return (m > 0 ? m + 'm ' : '') + s + 's';
|
|
7890
|
+
}
|
|
7891
|
+
|
|
7892
|
+
function wcStartGenTimer() {
|
|
7893
|
+
if (_wcTimerInterval) clearInterval(_wcTimerInterval);
|
|
7894
|
+
_wcTimerInterval = setInterval(function() {
|
|
7895
|
+
if (!wcState.running) { clearInterval(_wcTimerInterval); _wcTimerInterval = null; return; }
|
|
7896
|
+
wcUpdateGenOverlay(_wcGenOverlayState.fi, _wcGenOverlayState.total, _wcGenOverlayState.name);
|
|
7897
|
+
}, 1000);
|
|
7898
|
+
}
|
|
7899
|
+
|
|
7900
|
+
var _wcGenOverlayState = { fi: 0, total: 0, name: '' };
|
|
7901
|
+
|
|
7873
7902
|
function wcUpdateGenOverlay(fi2, total, name) {
|
|
7874
|
-
|
|
7903
|
+
_wcGenOverlayState = { fi: fi2, total: total, name: name };
|
|
7904
|
+
if (_wcOverlayMinimized) return;
|
|
7875
7905
|
var ov = document.getElementById('wcGenOverlay');
|
|
7876
7906
|
if (!ov) return;
|
|
7877
7907
|
var pct = Math.round((fi2 / total) * 100);
|
|
7908
|
+
var tokLabel = (_wcTokIn + _wcTokOut) > 0
|
|
7909
|
+
? '<div style="font-size:10px;color:var(--dim);margin-top:4px;font-family:var(--mono)">⇧' + _wcTokIn.toLocaleString() + ' ⇩' + _wcTokOut.toLocaleString() + ' tok</div>'
|
|
7910
|
+
: '';
|
|
7878
7911
|
ov.innerHTML =
|
|
7879
7912
|
'<div style="font-size:38px;animation:wcRobotBob 1s ease-in-out infinite">🤖</div>' +
|
|
7880
7913
|
'<div style="font-size:13px;font-weight:700;color:var(--green);margin-top:12px">Generazione in corso...</div>' +
|
|
@@ -7883,11 +7916,12 @@ async function wcGenerate() {
|
|
|
7883
7916
|
'<div style="width:220px;height:4px;background:rgba(255,255,255,0.1);border-radius:2px;overflow:hidden;margin-top:12px">' +
|
|
7884
7917
|
'<div style="height:100%;width:'+pct+'%;background:var(--green);border-radius:2px;transition:width .4s ease;animation:wcBarPulse 1.5s ease-in-out infinite"></div>' +
|
|
7885
7918
|
'</div>' +
|
|
7886
|
-
'<div style="font-size:10px;color:var(--dim);margin-top:6px">'+fi2+' / '+total+' file</div>' +
|
|
7919
|
+
'<div style="font-size:10px;color:var(--dim);margin-top:6px">'+fi2+' / '+total+' file · '+wcGenElapsed()+'</div>' +
|
|
7920
|
+
tokLabel +
|
|
7887
7921
|
'<div style="display:flex;gap:4px;margin-top:10px">'+[0,1,2,3,4].map(function(_,idx){ return '<div style="width:6px;height:6px;border-radius:50%;background:var(--green);animation:wcDot 1.1s ease-in-out infinite '+(idx*0.14)+'s"></div>'; }).join('')+'</div>';
|
|
7888
7922
|
}
|
|
7889
7923
|
|
|
7890
|
-
// Helper: generate one file
|
|
7924
|
+
// Helper: generate one file
|
|
7891
7925
|
async function wcGenOneFile(fp, signal) {
|
|
7892
7926
|
var _nl2 = String.fromCharCode(10);
|
|
7893
7927
|
var content = await wcCallLLM(sysPreamble, fp.prompt + _nl2 + _nl2 + 'File to generate: ' + fp.name, signal, fp.lang);
|
|
@@ -7898,21 +7932,49 @@ async function wcGenerate() {
|
|
|
7898
7932
|
return wcLines.join(_nl2).trim();
|
|
7899
7933
|
}
|
|
7900
7934
|
|
|
7901
|
-
|
|
7902
|
-
|
|
7903
|
-
|
|
7935
|
+
wcStartGenTimer();
|
|
7936
|
+
|
|
7937
|
+
// Pre-populate generatedFiles in order so tabs appear immediately
|
|
7938
|
+
filePlan.forEach(function(fp) {
|
|
7939
|
+
wcState.generatedFiles.push({ name: fp.name, content: '', lang: fp.lang, _pending: true });
|
|
7940
|
+
});
|
|
7941
|
+
wcState.activeFile = 0;
|
|
7942
|
+
renderWebCraft(document.getElementById('content'));
|
|
7943
|
+
|
|
7944
|
+
// Generate in parallel batches of 4 — each call is independent/fresh to Liara
|
|
7945
|
+
var BATCH = 4;
|
|
7946
|
+
var doneCount = 0;
|
|
7947
|
+
for (var bi = 0; bi < filePlan.length; bi += BATCH) {
|
|
7904
7948
|
if (_wcGenAbortCtrl && _wcGenAbortCtrl.signal.aborted) break;
|
|
7905
|
-
|
|
7906
|
-
|
|
7907
|
-
|
|
7908
|
-
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
if (
|
|
7912
|
-
|
|
7913
|
-
|
|
7914
|
-
|
|
7915
|
-
|
|
7949
|
+
var batch = filePlan.slice(bi, bi + BATCH);
|
|
7950
|
+
wcUpdateGenOverlay(doneCount, filePlan.length, batch.map(function(f){ return f.name; }).join(', '));
|
|
7951
|
+
var results = await Promise.allSettled(batch.map(function(fp) {
|
|
7952
|
+
return wcGenOneFile(fp, _wcGenAbortCtrl ? _wcGenAbortCtrl.signal : null).then(function(c){ return { fp: fp, content: c }; });
|
|
7953
|
+
}));
|
|
7954
|
+
results.forEach(function(r) {
|
|
7955
|
+
if (r.status === 'fulfilled') {
|
|
7956
|
+
var fp = r.value.fp;
|
|
7957
|
+
for (var gi = 0; gi < wcState.generatedFiles.length; gi++) {
|
|
7958
|
+
if (wcState.generatedFiles[gi].name === fp.name) {
|
|
7959
|
+
wcState.generatedFiles[gi] = { name: fp.name, content: r.value.content, lang: fp.lang };
|
|
7960
|
+
break;
|
|
7961
|
+
}
|
|
7962
|
+
}
|
|
7963
|
+
} else if (r.reason && r.reason.name !== 'AbortError') {
|
|
7964
|
+
var fpName = batch[results.indexOf(r)] ? batch[results.indexOf(r)].name : '?';
|
|
7965
|
+
// find by matching position
|
|
7966
|
+
var batchIdx = results.indexOf(r);
|
|
7967
|
+
if (batch[batchIdx]) fpName = batch[batchIdx].name;
|
|
7968
|
+
for (var gi2 = 0; gi2 < wcState.generatedFiles.length; gi2++) {
|
|
7969
|
+
if (wcState.generatedFiles[gi2].name === fpName) {
|
|
7970
|
+
wcState.generatedFiles[gi2] = { name: fpName, content: '// Error generating this file: ' + (r.reason.message || 'unknown error'), lang: (batch[batchIdx] || {}).lang || '', _error: true };
|
|
7971
|
+
break;
|
|
7972
|
+
}
|
|
7973
|
+
}
|
|
7974
|
+
}
|
|
7975
|
+
doneCount++;
|
|
7976
|
+
});
|
|
7977
|
+
renderWebCraft(document.getElementById('content'));
|
|
7916
7978
|
}
|
|
7917
7979
|
|
|
7918
7980
|
// ── Retry pass: regenerate files that failed ──────────────────────────────
|
|
@@ -7998,9 +8060,14 @@ async function wcGenerate() {
|
|
|
7998
8060
|
}
|
|
7999
8061
|
}
|
|
8000
8062
|
|
|
8063
|
+
if (_wcTimerInterval) { clearInterval(_wcTimerInterval); _wcTimerInterval = null; }
|
|
8064
|
+
var _wcGenTotalTime = Math.floor((Date.now() - _wcGenStartTime) / 1000);
|
|
8065
|
+
|
|
8001
8066
|
wcState.running = false;
|
|
8002
8067
|
_wcGenAbortCtrl = null;
|
|
8003
8068
|
_wcOverlayMinimized = false;
|
|
8069
|
+
// Store final stats for display after generation
|
|
8070
|
+
wcState.lastGenStats = { tokIn: _wcTokIn, tokOut: _wcTokOut, seconds: _wcGenTotalTime, files: wcState.generatedFiles.length };
|
|
8004
8071
|
|
|
8005
8072
|
// Auto-save project to ~/.nha/webcraft/<projectName>/
|
|
8006
8073
|
try {
|
|
@@ -8092,6 +8159,15 @@ async function wcCallLLMRaw(sys, user, signal) {
|
|
|
8092
8159
|
var r = await fetch(API + '/api/studio/webcraft', fetchOpts);
|
|
8093
8160
|
if (r.ok) {
|
|
8094
8161
|
var d = await r.json();
|
|
8162
|
+
// Accumulate token counts if the server returns usage data
|
|
8163
|
+
if (d && d.usage) {
|
|
8164
|
+
if (typeof _wcTokIn !== 'undefined') _wcTokIn += (d.usage.prompt_tokens || d.usage.input_tokens || 0);
|
|
8165
|
+
if (typeof _wcTokOut !== 'undefined') _wcTokOut += (d.usage.completion_tokens || d.usage.output_tokens || 0);
|
|
8166
|
+
} else if (d && d.text) {
|
|
8167
|
+
// Estimate from char count (4 chars ≈ 1 token)
|
|
8168
|
+
if (typeof _wcTokIn !== 'undefined') _wcTokIn += Math.round((sys.length + user.length) / 4);
|
|
8169
|
+
if (typeof _wcTokOut !== 'undefined') _wcTokOut += Math.round((d.text || '').length / 4);
|
|
8170
|
+
}
|
|
8095
8171
|
return (d && (d.text || d.content || d.result)) || '';
|
|
8096
8172
|
}
|
|
8097
8173
|
if (r.status < 500 || attempt === 2) {
|
|
@@ -8267,7 +8343,7 @@ async function wcStartSandbox() {
|
|
|
8267
8343
|
headers: {'Content-Type':'application/json'},
|
|
8268
8344
|
body: JSON.stringify({
|
|
8269
8345
|
projectName: wcState.projectName || 'webcraft-sandbox',
|
|
8270
|
-
files: wcState.generatedFiles.filter(function(f){ return !f._error; })
|
|
8346
|
+
files: wcState.generatedFiles.filter(function(f){ return !f._error && !f._pending; })
|
|
8271
8347
|
})
|
|
8272
8348
|
});
|
|
8273
8349
|
if (!r.ok || !r.body) throw new Error('Sandbox error ' + r.status);
|