nothumanallowed 14.5.8 → 14.5.9
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "14.5.
|
|
3
|
+
"version": "14.5.9",
|
|
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/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 = '14.5.
|
|
8
|
+
export const VERSION = '14.5.9';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
|
@@ -266,9 +266,15 @@ class SandboxManager {
|
|
|
266
266
|
}
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
-
// Show the actual error from stderr
|
|
270
|
-
const
|
|
271
|
-
|
|
269
|
+
// Show the actual error from stderr — include full trace for debugging
|
|
270
|
+
const stderrLines = stderrBuf.split('\n').filter(l => l.trim());
|
|
271
|
+
const errLine = stderrLines.find((l) => l.includes('Error') || l.includes('error'));
|
|
272
|
+
const stackLines = stderrLines.filter(l => l.includes('at ') || l.includes('Error')).slice(0, 5).join('\n');
|
|
273
|
+
const errDetail = errLine || stderrBuf.slice(0, 500) || 'No error output captured';
|
|
274
|
+
const fullErr = stackLines ? `${errDetail}\n${stackLines}` : errDetail;
|
|
275
|
+
emit({ type: 'error', msg: _attempt >= MAX_RETRIES
|
|
276
|
+
? `Failed after ${MAX_RETRIES} attempts (exit ${exitCode}):\n${fullErr}`
|
|
277
|
+
: `Crash (exit ${exitCode}):\n${fullErr}` });
|
|
272
278
|
}
|
|
273
279
|
}
|
|
274
280
|
|
|
@@ -2495,50 +2501,29 @@ export function register(router) {
|
|
|
2495
2501
|
|
|
2496
2502
|
const files = _listProjectFiles(dir);
|
|
2497
2503
|
const issues = [];
|
|
2498
|
-
const allFileNames = new Set(files);
|
|
2499
2504
|
|
|
2500
2505
|
for (const relPath of files) {
|
|
2501
2506
|
const content = ProjectStore.readFile(projectName, relPath);
|
|
2502
2507
|
if (!content) continue;
|
|
2503
|
-
const ext = relPath.split('.').pop()
|
|
2508
|
+
const ext = (relPath.split('.').pop() || '').toLowerCase();
|
|
2504
2509
|
|
|
2505
|
-
|
|
2506
|
-
if (
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
}
|
|
2510
|
-
}
|
|
2511
|
-
|
|
2512
|
-
// JSON parse check
|
|
2513
|
-
if (ext === 'json') {
|
|
2510
|
+
let diags = [];
|
|
2511
|
+
if (['js', 'mjs', 'jsx', 'cjs'].includes(ext)) {
|
|
2512
|
+
diags = lintJS(content, relPath, projectName);
|
|
2513
|
+
} else if (ext === 'json') {
|
|
2514
2514
|
try { JSON.parse(content); } catch (e) {
|
|
2515
|
-
|
|
2515
|
+
diags.push({ from: { line: 1, col: 0 }, severity: 'error', message: e.message });
|
|
2516
2516
|
}
|
|
2517
|
+
} else if (ext === 'css') {
|
|
2518
|
+
diags = lintCSS(content);
|
|
2519
|
+
} else if (ext === 'html' || ext === 'htm') {
|
|
2520
|
+
diags = lintHTML(content, relPath, projectName);
|
|
2517
2521
|
}
|
|
2518
2522
|
|
|
2519
|
-
//
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
}
|
|
2524
|
-
|
|
2525
|
-
// HTML closing tag + reference check
|
|
2526
|
-
if (ext === 'html' || ext === 'htm') {
|
|
2527
|
-
if (!content.includes('</html>')) {
|
|
2528
|
-
issues.push({ file: relPath, severity: 'warning', message: 'Missing </html>' });
|
|
2529
|
-
}
|
|
2530
|
-
// Check file references
|
|
2531
|
-
const refRegex = /(?:src|href)=["']([^"']*?\.(?:js|css|mjs))["']/gi;
|
|
2532
|
-
let m;
|
|
2533
|
-
while ((m = refRegex.exec(content)) !== null) {
|
|
2534
|
-
const ref = m[1];
|
|
2535
|
-
if (ref.startsWith('http') || ref.startsWith('//') || ref.startsWith('data:')) continue;
|
|
2536
|
-
const htmlDir = path.dirname(relPath);
|
|
2537
|
-
const refPath = ref.startsWith('/') ? ref.slice(1) : path.join(htmlDir, ref).replace(/\\/g, '/');
|
|
2538
|
-
const publicRef = refPath.startsWith('public/') ? refPath : `public/${refPath}`;
|
|
2539
|
-
if (!allFileNames.has(refPath) && !allFileNames.has(publicRef) && !allFileNames.has(ref)) {
|
|
2540
|
-
issues.push({ file: relPath, severity: 'error', message: `Missing file: ${ref}` });
|
|
2541
|
-
}
|
|
2523
|
+
// Convert diagnostics to scan issues (only errors, not warnings — too noisy)
|
|
2524
|
+
for (const d of diags) {
|
|
2525
|
+
if (d.severity === 'error') {
|
|
2526
|
+
issues.push({ file: relPath, severity: d.severity, message: `Line ${d.from.line}: ${d.message}` });
|
|
2542
2527
|
}
|
|
2543
2528
|
}
|
|
2544
2529
|
|
|
@@ -764,7 +764,7 @@ FRONTEND:
|
|
|
764
764
|
- index.html: Job board homepage — (1) Hero: gradient background, large search widget (keyword input + location input + category select + Search button), quick stats bar (12,847 Jobs / 3,420 Companies / 45K Candidates). (2) Featured jobs: horizontal scroll row of 4 "Featured" cards with company logo (colored emoji), job title, company name, location + type badge + salary range + "Easy Apply" button. (3) Main layout: left sidebar filters (Job Type checkboxes, Salary Range slider, Category checkboxes, Location input, Posted Within select, Remote Only toggle) + right: jobs list (job row cards with company logo/title/company/location/type/salary/time-ago posted/Save bookmark/Apply button). (4) "Load More" button + results count "Showing 12 of 247 jobs". (5) Top companies section: 8 company cards with logo/name/industry/openings count. (6) Category browsing: 6 category cards with icon/name/count/link. (7) Job seeker CTA banner. (8) Newsletter.
|
|
765
765
|
- job.html: Job detail page — company header (logo + name + industry + website + size + "Follow" button), job title + badges (Remote, Senior, Urgent), salary + location + posted date, Apply Now button (sticky on scroll), job description (markdown-rendered sections: About/Responsibilities/Requirements/Nice-to-Have/Benefits), company sidebar card (description + stats), similar jobs list (4 cards)
|
|
766
766
|
- apply.html: Application modal/page — job summary header, form (Full Name / Email / Phone / LinkedIn URL / Portfolio URL / Cover Letter textarea with character count / Resume paste textarea), Submit button with loading state, success page with application reference number
|
|
767
|
-
- public/css/main.css: Modern job board design — tag/badge system (Remote=blue, Onsite=green, Urgent=red), salary range display, company logo placeholder styles, filter sidebar collapse on mobile, job card hover effects, application form validation styles`}],BT=[{key:`auth`,label:`Auth (register/login/JWT)`,icon:`🔒`},{key:`cookieBanner`,label:`GDPR Cookie Banner`,icon:`🍪`},{key:`securityMiddleware`,label:`Security Middleware`,icon:`🛡️`},{key:`emailVerification`,label:`Email Verification`,icon:`✉️`}],VT={js:`📄`,ts:`📄`,css:`🎨`,html:`🌐`,json:`📋`,md:`📑`,sql:`🗂`,env:`🔐`,conf:`⚙`,lock:`🔒`};function HT(e){return VT[e.split(`.`).pop()?.toLowerCase()??``]??`📄`}function UT(e){let t=new TextEncoder().encode(e).length;return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:`${(t/(1024*1024)).toFixed(2)} MB`}function WT(e){return e===`memory`?`🧠`:e===`provider`?`🤖`:e===`log`?`📄`:`📋`}function GT(){let e=j(),[t,n]=(0,_.useState)(`new`),[r,i]=(0,_.useState)(`files`),[a,o]=(0,_.useState)(``),[s,c]=(0,_.useState)(``),[l,u]=(0,_.useState)({auth:!0,cookieBanner:!0,securityMiddleware:!0,emailVerification:!0}),[d,f]=(0,_.useState)([{label:`Email`,type:`email`,required:!0},{label:`Password`,type:`password`,required:!0},{label:`Name`,type:`text`,required:!0}]),[p,m]=(0,_.useState)([]),[h,g]=(0,_.useState)(0),[v,y]=(0,_.useState)(null),[b,x]=(0,_.useState)(null),[S,C]=(0,_.useState)(new Set),[w,ee]=(0,_.useState)(!1),[te,T]=(0,_.useState)(``),[ne,re]=(0,_.useState)(``),[ie,O]=(0,_.useState)(!1),[ae,A]=(0,_.useState)(null),[oe,se]=(0,_.useState)(!1),[ce,le]=(0,_.useState)([]),[ue,de]=(0,_.useState)([]),M=(0,_.useRef)(null),fe=(0,_.useRef)(null),pe=(0,_.useRef)(!0),me=(0,_.useRef)(null),he=(0,_.useRef)(null),ge=(0,_.useRef)(null),_e=(0,_.useRef)(null),[ve,ye]=(0,_.useState)(null),[be,xe]=(0,_.useState)(!1),[Se,N]=(0,_.useState)(!1),[Ce,we]=(0,_.useState)(0),[Te,Ee]=(0,_.useState)(0),[P,De]=(0,_.useState)(``),[Oe,ke]=(0,_.useState)({fi:0,total:0,name:``}),[F,I]=(0,_.useState)({tokIn:0,tokOut:0}),[Ae,je]=(0,_.useState)(null),[Me,Ne]=(0,_.useState)([]),[Pe,Fe]=(0,_.useState)(``),[Ie,Le]=(0,_.useState)(!1),[Re,ze]=(0,_.useState)([]),[L,Be]=(0,_.useState)(null),[Ve,He]=(0,_.useState)([]),[Ue,We]=(0,_.useState)(!1),[Ge,Ke]=(0,_.useState)(null),[qe,Je]=(0,_.useState)([]),[Ye,Xe]=(0,_.useState)(!1),[Ze,Qe]=(0,_.useState)(``),[$e,et]=(0,_.useState)([]),[tt,nt]=(0,_.useState)([]),[rt,it]=(0,_.useState)([]),[at,ot]=(0,_.useState)(null),[st,ct]=(0,_.useState)(!1),[lt,ut]=(0,_.useState)(null),[dt,ft]=(0,_.useState)(`0s`),[R,pt]=(0,_.useState)(`0s`),mt=(0,_.useRef)(0),ht=(0,_.useRef)(0),gt=(0,_.useRef)(null),_t=(0,_.useRef)(null),vt=(0,_.useRef)(null),yt=(0,_.useRef)(null),z=(0,_.useRef)(null),bt=(0,_.useRef)(!1),xt=(0,_.useRef)(null);function St(e){D(`/api/studio/webcraft/scan`,{projectName:e}).then(e=>{e?.issues
|
|
767
|
+
- public/css/main.css: Modern job board design — tag/badge system (Remote=blue, Onsite=green, Urgent=red), salary range display, company logo placeholder styles, filter sidebar collapse on mobile, job card hover effects, application form validation styles`}],BT=[{key:`auth`,label:`Auth (register/login/JWT)`,icon:`🔒`},{key:`cookieBanner`,label:`GDPR Cookie Banner`,icon:`🍪`},{key:`securityMiddleware`,label:`Security Middleware`,icon:`🛡️`},{key:`emailVerification`,label:`Email Verification`,icon:`✉️`}],VT={js:`📄`,ts:`📄`,css:`🎨`,html:`🌐`,json:`📋`,md:`📑`,sql:`🗂`,env:`🔐`,conf:`⚙`,lock:`🔒`};function HT(e){return VT[e.split(`.`).pop()?.toLowerCase()??``]??`📄`}function UT(e){let t=new TextEncoder().encode(e).length;return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:`${(t/(1024*1024)).toFixed(2)} MB`}function WT(e){return e===`memory`?`🧠`:e===`provider`?`🤖`:e===`log`?`📄`:`📋`}function GT(){let e=j(),[t,n]=(0,_.useState)(`new`),[r,i]=(0,_.useState)(`files`),[a,o]=(0,_.useState)(``),[s,c]=(0,_.useState)(``),[l,u]=(0,_.useState)({auth:!0,cookieBanner:!0,securityMiddleware:!0,emailVerification:!0}),[d,f]=(0,_.useState)([{label:`Email`,type:`email`,required:!0},{label:`Password`,type:`password`,required:!0},{label:`Name`,type:`text`,required:!0}]),[p,m]=(0,_.useState)([]),[h,g]=(0,_.useState)(0),[v,y]=(0,_.useState)(null),[b,x]=(0,_.useState)(null),[S,C]=(0,_.useState)(new Set),[w,ee]=(0,_.useState)(!1),[te,T]=(0,_.useState)(``),[ne,re]=(0,_.useState)(``),[ie,O]=(0,_.useState)(!1),[ae,A]=(0,_.useState)(null),[oe,se]=(0,_.useState)(!1),[ce,le]=(0,_.useState)([]),[ue,de]=(0,_.useState)([]),M=(0,_.useRef)(null),fe=(0,_.useRef)(null),pe=(0,_.useRef)(!0),me=(0,_.useRef)(null),he=(0,_.useRef)(null),ge=(0,_.useRef)(null),_e=(0,_.useRef)(null),[ve,ye]=(0,_.useState)(null),[be,xe]=(0,_.useState)(!1),[Se,N]=(0,_.useState)(!1),[Ce,we]=(0,_.useState)(0),[Te,Ee]=(0,_.useState)(0),[P,De]=(0,_.useState)(``),[Oe,ke]=(0,_.useState)({fi:0,total:0,name:``}),[F,I]=(0,_.useState)({tokIn:0,tokOut:0}),[Ae,je]=(0,_.useState)(null),[Me,Ne]=(0,_.useState)([]),[Pe,Fe]=(0,_.useState)(``),[Ie,Le]=(0,_.useState)(!1),[Re,ze]=(0,_.useState)([]),[L,Be]=(0,_.useState)(null),[Ve,He]=(0,_.useState)([]),[Ue,We]=(0,_.useState)(!1),[Ge,Ke]=(0,_.useState)(null),[qe,Je]=(0,_.useState)([]),[Ye,Xe]=(0,_.useState)(!1),[Ze,Qe]=(0,_.useState)(``),[$e,et]=(0,_.useState)([]),[tt,nt]=(0,_.useState)([]),[rt,it]=(0,_.useState)([]),[at,ot]=(0,_.useState)(null),[st,ct]=(0,_.useState)(!1),[lt,ut]=(0,_.useState)(null),[dt,ft]=(0,_.useState)(`0s`),[R,pt]=(0,_.useState)(`0s`),mt=(0,_.useRef)(0),ht=(0,_.useRef)(0),gt=(0,_.useRef)(null),_t=(0,_.useRef)(null),vt=(0,_.useRef)(null),yt=(0,_.useRef)(null),z=(0,_.useRef)(null),bt=(0,_.useRef)(!1),xt=(0,_.useRef)(null);function St(e){D(`/api/studio/webcraft/scan`,{projectName:e}).then(e=>{if(e?.issues)if(de(e.issues),e.issues.length>0){let t=new Set(e.issues.filter(e=>e.severity===`error`).map(e=>e.file));m(n=>n.map(n=>{if(t.has(n.name)){let t=e.issues.filter(e=>e.file===n.name);return{...n,_syntaxError:t.map(e=>e.message).join(`; `)}}return{...n,_syntaxError:void 0,_error:!1}}))}else m(e=>e.map(e=>({...e,_syntaxError:void 0,_error:!1})))}).catch(()=>{})}(0,_.useEffect)(()=>{if(!at){le([]);return}let e=setInterval(()=>{E(`/api/studio/webcraft/sandbox/errors`).then(e=>{e?.errors?.length&&le(e.errors)}).catch(()=>{})},5e3);return()=>clearInterval(e)},[at]);let Ct=(0,_.useRef)(at);Ct.current=at,(0,_.useEffect)(()=>{let e=()=>{Ct.current&&(navigator.sendBeacon(`/api/studio/webcraft/sandbox/stop-beacon`,``),fetch(`/api/studio/webcraft/sandbox`,{method:`DELETE`,keepalive:!0}).catch(()=>{}))};return window.addEventListener(`beforeunload`,e),()=>{window.removeEventListener(`beforeunload`,e),e()}},[]),(0,_.useEffect)(()=>{let e=e=>{if((e.metaKey||e.ctrlKey)&&e.key===`f`&&(e.preventDefault(),ee(e=>!e)),(e.metaKey||e.ctrlKey)&&e.key===`s`&&(e.preventDefault(),b!==null&&p[h])){let e=p[h];m(e=>e.map((e,t)=>t===h?{...e,content:b}:e)),D(`/api/studio/webcraft/file/write`,{projectName:a,path:e.name,content:b}),x(null),C(t=>{let n=new Set(t);return n.delete(e.name),n})}};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[b,h,p,a]),(0,_.useEffect)(()=>{let e=()=>{let e=b===null?ge.current:he.current;e&&_e.current&&(_e.current.scrollTop=e.scrollTop)},t=b===null?ge.current:he.current;return t&&t.addEventListener(`scroll`,e),()=>{t&&t.removeEventListener(`scroll`,e)}},[b,h]);function wt(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function B(e){let t=Math.floor((Date.now()-e)/1e3),n=Math.floor(t/60);return(n>0?`${n}m `:``)+`${t%60}s`}(0,_.useEffect)(()=>(be||Se?gt.current=setInterval(()=>{be&&ft(B(mt.current)),Se&&pt(B(ht.current))},1e3):gt.current&&=(clearInterval(gt.current),null),()=>{gt.current&&clearInterval(gt.current)}),[be,Se]);function Tt(){vt.current&&(vt.current.scrollTop=vt.current.scrollHeight)}(0,_.useEffect)(()=>{Tt()},[Me]),(0,_.useEffect)(()=>{a&&!Ue&&(We(!0),E(`/api/studio/webcraft/skills/${encodeURIComponent(a)}`).then(e=>{e?.skills&&He(e.skills)}).catch(()=>{}))},[a,Ue]);async function Et(e,t){if(be||!e||e.length<5)return;xe(!0),m([]),g(0),y(null),ke({fi:0,total:0,name:``}),I({tokIn:0,tokOut:0}),mt.current=Date.now(),ft(`0s`),_t.current=new AbortController;let n=Date.now();try{let r=await fetch(`/api/studio/webcraft/generate`,{method:`POST`,headers:{"Content-Type":`application/json`},signal:_t.current.signal,body:JSON.stringify({projectName:t,description:e,blocks:l,authFields:d})});if(!r.ok||!r.body){xe(!1);return}let i=r.body.getReader(),s=_t.current,c=new TextDecoder,u=``,f=[];for(;;){if(s?.signal?.aborted){try{i.cancel()}catch{}break}let{done:e,value:t}=await i.read();if(e)break;u+=c.decode(t,{stream:!0});let r=u.split(`
|
|
768
768
|
|
|
769
769
|
`);u=r.pop()??``;for(let e of r){let t=e.replace(/^data: /,``).trim();if(t)try{let e=JSON.parse(t);if(e.type===`project_renamed`)o(e.name);else if(e.type===`processing`||e.type===`planning`)ke(t=>({...t,name:e.type===`planning`?`📋 Pianificazione struttura...`:e.msg||`Avvio...`}));else if(e.type===`file_start`)f.push({name:e.name,content:``,_pending:!0}),m([...f]),ke({fi:e.fi,total:e.total,name:e.name}),M.current=f.length-1,fe.current||(g(f.length-1),y(``)),pe.current=!0;else if(e.type===`file_chunk`){let t=f.find(t=>t.name===e.name);t&&(t.content+=e.chunk,t._pending=!1),m([...f]);let n=f.findIndex(t=>t.name===e.name);n>=0&&(M.current=n,y(t?t.content:null))}else if(e.type===`file_done`){let t=f.find(t=>t.name===e.name);t&&(t._pending=!1,e.syntaxError&&(t._syntaxError=e.syntaxError)),m([...f]),ke({fi:e.fi,total:e.total,name:e.name}),(e.cumTokIn||e.cumTokOut)&&I({tokIn:e.cumTokIn||0,tokOut:e.cumTokOut||0})}else if(e.type===`file_error`){let t=f.find(t=>t.name===e.name);t&&(t._error=!0,t._pending=!1),m([...f])}else e.type===`phase`||e.type===`status`&&!e.op?ke(t=>({...t,name:e.msg||e.phase||``})):e.type===`done`&&(je({seconds:Math.round((Date.now()-n)/1e3),tokIn:e.tokIn??0,tokOut:e.tokOut??0,files:f.length}),y(null),xe(!1),M.current=null,fe.current&&=(clearTimeout(fe.current),null),a&&St(a),se(!0),We(!1),He([]),f.some(e=>e._error||e._syntaxError)?setTimeout(()=>z.current?.(),800):setTimeout(()=>xt.current?.(),800))}catch{}}}}catch(e){e.name!==`AbortError`&&Ne(t=>[...t,{role:`system`,text:`Errore generazione: `+e.message}]),xe(!1)}}async function Dt(){let e=Pe.trim();if(!(a&&p.length>0)){if(!e||e.length<5)return;let t=a||`MyProject`;o(t),c(e),Fe(``),await Et(e,t);return}if(!e&&Re.length===0||Ie||be)return;let t=[...Re];if(ze([]),Fe(``),e.toLowerCase().startsWith(`/plan `)||e.toLowerCase().startsWith(`piano: `)){let t=e.replace(/^\/plan[ ]*/i,``).replace(/^piano:[ ]*/i,``);Ne(t=>[...t,{role:`user`,text:e}]),await Ot(`[MODALITA PIANO] Descrivi cosa modificheresti per: "${t}". Elenca i file e cosa faresti. NON applicare modifiche ancora. Rispondi con il piano in bullet list.`,t,[]);return}Ne(n=>[...n,{role:`user`,text:e,attachments:t}]),await Ot(e,null,t)}async function Ot(e,t,n){if(Ie)return;Le(!0),a&&p.length>0&&D(`/api/studio/webcraft/snapshot`,{projectName:a}).catch(()=>{});let r={};p.forEach(e=>{r[e.name]=e.content});try{let i=await fetch(`/api/studio/webcraft/agent`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({projectName:a,message:e,attachments:n.map(e=>({name:e.name,mimeType:e.mimeType,base64:e.base64}))})});if(!i.ok||!i.body){Ne(e=>[...e,{role:`agent`,text:`Errore: ${i.status}`,tools:[]}]),Le(!1);return}let o={role:`agent`,text:``,tools:[]};Ne(e=>[...e,o]);let s=i.body.getReader(),c=new TextDecoder,l=``,u=!1,d=``;for(;;){let{done:e,value:n}=await s.read();if(e)break;l+=c.decode(n,{stream:!0});let i=l.split(`
|
|
770
770
|
|
|
@@ -775,9 +775,9 @@ FRONTEND:
|
|
|
775
775
|
❌ Sandbox error: `+e.msg,Ne(e=>{let t=[...e];return t[t.length-1]={...o},t});else if(e.type===`done`){if(d){let e=d.replace(/<tool>[\s\S]*?<\/tool>/g,``).replace(/<done\s*\/>/g,``);e&&(o.text+=e),d=``}t&&!u&&Be({plan:o.text,originalMessage:t}),Le(!1),e.changed&&await kt((o.tools??[]).filter(e=>e.op===`edit`||e.op===`write`).map(e=>e.path),r)}else e.type===`error`&&(o.text+=`
|
|
776
776
|
Errore: `+e.msg,Le(!1))}catch{}}}}catch(e){Ne(t=>[...t,{role:`agent`,text:`Errore di rete: `+e.message,tools:[]}])}Le(!1)}async function kt(e,t){if(!a)return;let n=await E(`/api/studio/webcraft/projects/load/${encodeURIComponent(a)}`);if(n?.files&&(m(n.files),a&&St(a),e.length>0)){let r=e.map(e=>{let r=n.files.find(t=>t.name===e);return r?{file:e,before:t[e]??``,after:r.content}:null}).filter(Boolean);nt(e=>[...e,...r])}}function At(){_t.current&&=(_t.current.abort(),null),bt.current=!0,xe(!1),Le(!1),N(!1),De(``),y(null),Ne(e=>[...e,{role:`system`,text:`⏹ Generazione interrotta.`}])}async function jt(){return a?(await D(`/api/studio/webcraft/snapshot`,{projectName:a}))?.snapshot??null:null}async function Mt(){let e=await jt();e&&(Ne(t=>[...t,{role:`system`,text:`💾 Snapshot salvato (${e.slice(0,16).replace(`T`,` `)})`}]),Nt())}async function Nt(){if(!a)return;let e=await E(`/api/studio/webcraft/snapshots/${encodeURIComponent(a)}`);e?.snapshots&&Je(e.snapshots)}async function V(e){confirm(`Ripristinare lo snapshot del ${e.replace(`T`,` `).slice(0,16)}? I file attuali verranno sovrascritti.`)&&await D(`/api/studio/webcraft/restore`,{projectName:a,ts:e})!==null&&(Ne(t=>[...t,{role:`agent`,text:`Snapshot ripristinato (${e}). Ricarico i file...`}]),kt([],{}))}async function Pt(){if(!a)return;let e=await D(`/api/studio/webcraft/syntax-check`,{projectName:a});if(e?.results){let t=e.results.filter(e=>!e.ok);t.length>0?Ne(e=>[...e,{role:`system`,text:`⚠ Syntax check: ${t.length} errore/i trovato/i.`,syntaxErrors:t}]):Ne(e=>[...e,{role:`system`,text:`✓ Syntax check: tutti i file JS sono validi.`}])}}async function Ft(){let e=p.filter(e=>e._error||e._syntaxError);if(e.length===0){xt.current?.();return}bt.current=!1,N(!0),we(0),Ee(e.length),ht.current=Date.now(),pt(`0s`);for(let t=0;t<e.length&&!bt.current;t++){let n=e[t];De(n.name),we(t);let r=`FIX ERROR in ${n.name}: ${n._syntaxError??`generazione fallita`}\n\nUse the edit tool to make surgical fixes. Do NOT rewrite the entire file — only change the broken parts. Read the file first, identify the exact lines with errors, and edit only those lines.`;try{await Ot(r,null,[])}catch{if(bt.current)break}}bt.current||(we(e.length),setTimeout(()=>xt.current?.(),500)),De(``),N(!1)}async function It(e){if(!st){ct(!0),ut(null),ot(null),i(`preview`);try{let t=await fetch(`/api/studio/webcraft/sandbox/start`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({projectName:e})});if(!t.ok||!t.body){ut(t.ok?`No response body`:`HTTP ${t.status}`),ct(!1);return}let n=t.body.getReader(),r=new TextDecoder,i=``;for(;;){let{done:e,value:t}=await n.read();if(e)break;i+=r.decode(t,{stream:!0});let a=i.split(`
|
|
777
777
|
|
|
778
|
-
`);i=a.pop()??``;for(let e of a){let t=e.replace(/^data: /,``).trim();if(t)try{let e=JSON.parse(t);e.type===`phase`||(e.type===`ready`&&e.port?(ot(e.port),ct(!1)):e.type===`status`||e.type===`log`||e.type===`warn`||(e.type===`error`?ut(e.msg):e.type))}catch{}}}}catch(e){ut(e.message||`Connection failed`)}ct(!1)}}async function Lt(){a&&await It(a)}(0,_.useEffect)(()=>{z.current=Ft,xt.current=Lt});async function Rt(){if(!Ze||!a)return;let e=await D(`/api/studio/webcraft/grep`,{projectName:a,query:Ze});e?.matches&&et(e.matches)}function zt(e){let t=p.findIndex(t=>t.name===e);t>=0&&(g(t),i(`files`))}function Bt(){window.open(`/api/studio/webcraft/download/${encodeURIComponent(a)}`,`_blank`)}async function H(e,t,n,r){t.endsWith(`.md`)||(t+=`.md`);let i={name:t,content:n,type:r},s;s=e.mode===`edit`&&e.idx!==null?Ve.map((t,n)=>n===e.idx?i:t):[...Ve,i],He(s),Ke(null);let c=a||`MyProject`;a||o(c),await D(`/api/studio/webcraft/skills/${encodeURIComponent(c)}`,{skills:s})}async function Vt(e){let t=Ve[e];!t||!confirm(`Eliminare "${t.name}"?`)||(await D(`/api/studio/webcraft/skills/${encodeURIComponent(a)}/delete`,{name:t.name}),He(Ve.filter((t,n)=>n!==e)))}async function Ht(e){let t=Ve[e];if(!t||!confirm(`Svuotare "${t.name}"? Il file rimane ma il contenuto viene cancellato.`))return;let n=Ve.map((t,n)=>n===e?{...t,content:``}:t);He(n),await D(`/api/studio/webcraft/skills/${encodeURIComponent(a)}`,{skills:n})}async function Ut(){let e=await E(`/api/studio/webcraft/projects`);e?.projects&&it(e.projects)}async function Wt(e){let t=await E(`/api/studio/webcraft/projects/load/${encodeURIComponent(e.name)}`);if(!t)return;
|
|
778
|
+
`);i=a.pop()??``;for(let e of a){let t=e.replace(/^data: /,``).trim();if(t)try{let e=JSON.parse(t);e.type===`phase`||(e.type===`ready`&&e.port?(ot(e.port),ct(!1)):e.type===`status`||e.type===`log`||e.type===`warn`||(e.type===`error`?ut(e.msg):e.type))}catch{}}}}catch(e){ut(e.message||`Connection failed`)}ct(!1)}}async function Lt(){a&&await It(a)}(0,_.useEffect)(()=>{z.current=Ft,xt.current=Lt});async function Rt(){if(!Ze||!a)return;let e=await D(`/api/studio/webcraft/grep`,{projectName:a,query:Ze});e?.matches&&et(e.matches)}function zt(e){let t=p.findIndex(t=>t.name===e);t>=0&&(g(t),i(`files`))}function Bt(){window.open(`/api/studio/webcraft/download/${encodeURIComponent(a)}`,`_blank`)}async function H(e,t,n,r){t.endsWith(`.md`)||(t+=`.md`);let i={name:t,content:n,type:r},s;s=e.mode===`edit`&&e.idx!==null?Ve.map((t,n)=>n===e.idx?i:t):[...Ve,i],He(s),Ke(null);let c=a||`MyProject`;a||o(c),await D(`/api/studio/webcraft/skills/${encodeURIComponent(c)}`,{skills:s})}async function Vt(e){let t=Ve[e];!t||!confirm(`Eliminare "${t.name}"?`)||(await D(`/api/studio/webcraft/skills/${encodeURIComponent(a)}/delete`,{name:t.name}),He(Ve.filter((t,n)=>n!==e)))}async function Ht(e){let t=Ve[e];if(!t||!confirm(`Svuotare "${t.name}"? Il file rimane ma il contenuto viene cancellato.`))return;let n=Ve.map((t,n)=>n===e?{...t,content:``}:t);He(n),await D(`/api/studio/webcraft/skills/${encodeURIComponent(a)}`,{skills:n})}async function Ut(){let e=await E(`/api/studio/webcraft/projects`);e?.projects&&it(e.projects)}async function Wt(e){let t=await E(`/api/studio/webcraft/projects/load/${encodeURIComponent(e.name)}`);if(!t)return;let r=t.projectName??e.name;o(r),c(t.description??``),m(t.files??[]),g(0),n(`new`),i(`files`),Ne([]),He([]),We(!1),de([]),St(r);let a=await E(`/api/studio/webcraft/projects/chat/load/${encodeURIComponent(r)}`);a?.chat&&Ne(a.chat);let s=await E(`/api/studio/webcraft/skills/${encodeURIComponent(r)}`);s?.skills&&(He(s.skills),We(!0))}async function Gt(e){confirm(`Eliminare: ${e.name} - ${e.dir}?`)&&(await D(`/api/studio/webcraft/projects/${encodeURIComponent(e.name)}`,{},`DELETE`),it(rt.filter(t=>t.name!==e.name)),a===e.name&&(o(``),m([]),Ne([]),c(``)))}async function U(){if(!L)return;let e=L.originalMessage;Be(null),await Ot(e+`
|
|
779
779
|
[Piano approvato — procedi con le modifiche]`,null,[])}function Kt(e){e&&Array.from(e).forEach(e=>{let t=new FileReader;t.onload=t=>{let n=(t.target?.result).split(`,`)[1];ze(t=>[...t,{name:e.name,mimeType:e.type,base64:n,size:e.size}])},t.readAsDataURL(e)})}let qt=a&&p.length>0,Jt=p[h],Yt=Ie||be;return(0,k.jsxs)(`div`,{className:$.root,children:[(0,k.jsxs)(`div`,{className:$.header,children:[(0,k.jsxs)(`div`,{children:[(0,k.jsx)(`div`,{className:$.title,children:`⚙ WebCraft`}),(0,k.jsx)(`div`,{className:$.subtitle,children:`Genera progetti web completi con agenti AI`})]}),(0,k.jsxs)(`div`,{className:$.headerTabs,children:[(0,k.jsx)(`button`,{className:`${$.tabBtn} ${t===`new`?$.tabActive:``}`,onClick:async()=>{if(!(S.size>0&&!confirm(`${S.size} unsaved file(s). Discard changes and create new project?`))){if(at){try{await fetch(`/api/studio/webcraft/sandbox`,{method:`DELETE`})}catch{}ot(null)}m([]),g(0),y(null),x(null),C(new Set),Ne([]),o(``),c(``),Fe(``),He([]),We(!1),je(null),xe(!1),Le(!1),O(!1),A(null),n(`new`)}},children:`+ Nuovo`}),(0,k.jsx)(`button`,{className:`${$.tabBtn} ${t===`projects`?$.tabActive:``}`,onClick:()=>{n(`projects`),Ut()},children:`📁 Progetti`})]})]}),(0,k.jsx)(`div`,{className:$.body,children:t===`projects`?(0,k.jsx)(`div`,{className:$.projectsList,children:rt.length===0?(0,k.jsxs)(`div`,{className:$.emptyProjects,children:[(0,k.jsx)(`span`,{className:$.emptyIcon,children:`📁`}),(0,k.jsx)(`span`,{children:e(`webcraft.noProjects`)}),(0,k.jsx)(`span`,{className:$.emptyHint,children:`Crea un progetto nella tab Nuovo`})]}):rt.map(e=>(0,k.jsxs)(`div`,{className:$.projectCard,children:[(0,k.jsxs)(`div`,{className:$.projectInfo,children:[(0,k.jsx)(`div`,{className:$.projectName,children:e.name}),(0,k.jsx)(`div`,{className:$.projectDesc,children:e.description}),(0,k.jsxs)(`div`,{className:$.projectMeta,children:[(0,k.jsxs)(`span`,{children:[`📄 `,e.fileCount,` file`]}),(0,k.jsxs)(`span`,{children:[`📅 `,e.createdAt?new Date(e.createdAt).toLocaleString():``]})]})]}),(0,k.jsx)(`button`,{className:$.openBtn,onClick:()=>Wt(e),children:`↗ Apri`}),(0,k.jsx)(`button`,{className:$.deleteBtn,onClick:()=>Gt(e),children:`🗑`})]},e.name))}):(0,k.jsxs)(`div`,{className:$.editor,children:[(0,k.jsxs)(`div`,{className:$.examples,children:[(0,k.jsx)(`div`,{className:$.sectionLabel,children:`Esempi`}),(0,k.jsx)(`div`,{className:$.examplePills,children:zT.map(e=>(0,k.jsx)(`button`,{className:$.examplePill,onClick:()=>{o(e.name),c(e.desc),Fe(e.desc)},children:e.name},e.name))})]}),(0,k.jsxs)(`div`,{className:$.editorCols,children:[(0,k.jsxs)(`div`,{className:$.leftSidebar,children:[(0,k.jsxs)(`div`,{className:$.panel,children:[(0,k.jsx)(`div`,{className:$.panelTitle,children:`Blocchi`}),BT.map(e=>(0,k.jsxs)(`label`,{className:$.blockLabel,children:[(0,k.jsx)(`input`,{type:`checkbox`,checked:l[e.key],onChange:t=>u(n=>({...n,[e.key]:t.target.checked})),className:$.blockCheck}),(0,k.jsx)(`span`,{children:e.icon}),(0,k.jsx)(`span`,{children:e.label})]},e.key))]}),l.auth&&(0,k.jsxs)(`div`,{className:$.panel,children:[(0,k.jsxs)(`div`,{className:$.panelHeader,children:[(0,k.jsx)(`div`,{className:$.panelTitle,children:`Campi Auth`}),(0,k.jsx)(`button`,{className:$.addBtn,onClick:()=>f(e=>[...e,{label:`New field`,type:`text`,required:!1}]),children:`+ Campo`})]}),d.map((e,t)=>(0,k.jsxs)(`div`,{className:$.authField,children:[(0,k.jsx)(`input`,{value:e.label,onChange:e=>f(n=>n.map((n,r)=>r===t?{...n,label:e.target.value}:n)),className:$.authFieldInput}),(0,k.jsx)(`select`,{value:e.type,onChange:e=>f(n=>n.map((n,r)=>r===t?{...n,type:e.target.value}:n)),className:$.authFieldSelect,children:[`text`,`email`,`password`,`tel`,`date`,`number`].map(e=>(0,k.jsx)(`option`,{value:e,children:e},e))}),(0,k.jsx)(`input`,{type:`checkbox`,checked:e.required,onChange:e=>f(n=>n.map((n,r)=>r===t?{...n,required:e.target.checked}:n)),title:`Required`,className:$.authFieldReq}),(0,k.jsx)(`button`,{onClick:()=>f(e=>e.filter((e,n)=>n!==t)),className:$.removeFieldBtn,children:`×`})]},t))]}),(0,k.jsxs)(`div`,{className:$.panel,children:[(0,k.jsxs)(`div`,{className:$.panelHeader,children:[(0,k.jsx)(`div`,{className:$.panelTitle,children:`🗂 Contesto AI`}),(0,k.jsx)(`button`,{className:$.addBtn,onClick:()=>Ke({mode:`new`,idx:null,name:``,content:``,type:`skill`,generating:!1}),children:`+ Skill`})]}),Ve.length>0?(0,k.jsx)(`div`,{className:$.skillsList,children:Ve.map((e,t)=>(0,k.jsxs)(`div`,{className:$.skillRow,children:[(0,k.jsx)(`span`,{className:$.skillIcon,children:WT(e.type)}),(0,k.jsx)(`span`,{className:$.skillName,title:e.name,children:e.name}),(0,k.jsx)(`span`,{className:`${$.skillBadge} ${$[`skillBadge_`+e.type]}`,children:e.type}),!e.content&&e.type!==`log`&&(0,k.jsx)(`span`,{className:$.skillEmpty,children:`⚠`}),(0,k.jsx)(`button`,{className:$.skillBtn,onClick:()=>Ke({mode:e.type===`log`?`view`:`edit`,idx:t,name:e.name,content:e.content,type:e.type,generating:!1}),children:e.type===`log`?`👁`:`✏`}),e.type!==`memory`&&e.type!==`provider`&&e.type!==`log`&&(0,k.jsx)(`button`,{className:$.skillBtn,onClick:()=>Ht(t),children:`🗑`}),e.type===`log`&&(0,k.jsx)(`button`,{className:$.skillBtn,onClick:()=>Vt(t),children:`🗑`})]},t))}):(0,k.jsx)(`div`,{className:$.skillsEmpty,children:Ue?`Nessun file di contesto. Clicca "+ Skill" per aggiungerne uno.`:`Crea o carica un progetto per i file di contesto.`})]}),qe.length>0&&(0,k.jsxs)(`div`,{className:$.panel,children:[(0,k.jsx)(`div`,{className:$.panelTitle,children:`💾 Snapshot`}),qe.slice(0,5).map(e=>{let t=e.ts.replace(`T`,` `).slice(0,16);return(0,k.jsxs)(`div`,{className:$.snapshotRow,children:[(0,k.jsx)(`span`,{className:$.snapshotTs,children:t}),(0,k.jsxs)(`span`,{className:$.snapshotCount,children:[e.fileCount,`f`]}),(0,k.jsx)(`button`,{className:$.snapshotBtn,onClick:()=>V(e.ts),children:`↺`})]},e.ts)})]}),be&&(0,k.jsx)(`div`,{className:$.genStatus,children:`⏳ Generazione...`}),Se&&(0,k.jsxs)(`div`,{className:$.repairStatus,children:[(0,k.jsx)(`div`,{className:$.repairStatusTitle,children:`🔧 Correzione automatica...`}),(0,k.jsxs)(`div`,{className:$.repairStatusProg,children:[Ce,` / `,Te,` file`]}),(0,k.jsx)(`div`,{className:$.repairStatusFile,children:P})]}),p.length>0&&!be&&(0,k.jsxs)(k.Fragment,{children:[(0,k.jsxs)(`div`,{className:$.actionRow,children:[(0,k.jsx)(`button`,{className:$.actionBtn,onClick:Bt,children:`⬇ ZIP`}),(0,k.jsx)(`button`,{className:$.actionBtnIcon,title:`Syntax check`,onClick:Pt,children:`✅`}),(0,k.jsx)(`button`,{className:`${$.actionBtnIcon} ${Ye?$.actionBtnActive:``}`,title:`Grep`,onClick:()=>Xe(!Ye),children:`🔍`}),(0,k.jsx)(`button`,{className:$.actionBtnIcon,title:`Snapshot`,onClick:Mt,children:`💾`})]}),p.some(e=>e._error||e._syntaxError)&&!Se&&(0,k.jsx)(`button`,{className:$.repairBtn,onClick:Ft,children:`🔧 Correggi tutti i file rossi`}),(0,k.jsx)(`button`,{className:$.sandboxBtn,onClick:()=>{a?It(a):i(`preview`)},children:st?`⏳ Starting...`:at?`🌐 Sandbox Live`:`▶ Sandbox`}),Ae&&(0,k.jsxs)(`div`,{className:$.statsBar,children:[(0,k.jsxs)(`span`,{children:[`⏱ `,Ae.seconds>=60?`${Math.floor(Ae.seconds/60)}m ${Ae.seconds%60}s`:`${Ae.seconds}s`]}),(0,k.jsxs)(`span`,{children:[`↑ `,Ae.tokIn.toLocaleString(),` tok`]}),(0,k.jsxs)(`span`,{children:[`↓ `,Ae.tokOut.toLocaleString(),` tok`]}),(0,k.jsxs)(`span`,{children:[`📄 `,Ae.files,` file`]})]})]})]}),(0,k.jsxs)(`div`,{className:$.rightPanel,children:[(0,k.jsxs)(`div`,{className:$.rightTabBar,children:[(0,k.jsx)(`button`,{className:`${$.rightTab} ${r===`preview`?``:$.rightTabActive}`,onClick:()=>i(`files`),children:`📄 File`}),(0,k.jsx)(`button`,{className:`${$.rightTab} ${r===`preview`?$.rightTabActive:``}`,onClick:()=>i(`preview`),children:`🌐 Sandbox`})]}),Se&&(0,k.jsxs)(`div`,{className:$.repairBar,children:[(0,k.jsxs)(`div`,{className:$.repairBarRow,children:[(0,k.jsx)(`span`,{className:$.repairBarIcon,children:`🔧`}),(0,k.jsx)(`span`,{className:$.repairBarLabel,children:`Auto-fix`}),(0,k.jsx)(`span`,{className:$.repairBarFile,children:P}),(0,k.jsxs)(`span`,{className:$.repairBarCounter,children:[Ce,` / `,Te]}),(0,k.jsx)(`span`,{className:$.repairBarTime,children:R}),(0,k.jsx)(`button`,{className:$.stopBtn,onClick:At,children:`⏹ Stop`})]}),(0,k.jsx)(`div`,{className:$.progressTrack,children:(0,k.jsx)(`div`,{className:$.repairProgress,style:{width:Te>0?`${Math.round(Ce/Te*100)}%`:`0%`}})})]}),be&&(0,k.jsxs)(`div`,{className:$.genBar,children:[(0,k.jsxs)(`div`,{className:$.genBarRow,children:[(0,k.jsx)(`span`,{className:$.genBarRobot,children:`🤖`}),(0,k.jsx)(`span`,{className:$.genBarLabel,children:Oe.total===0?`Pianificazione...`:`Generazione`}),(0,k.jsx)(`span`,{className:$.genBarFile,children:Oe.name.split(`,`)[0].trim()}),(0,k.jsx)(`span`,{className:$.genBarCounter,children:Oe.total>0?`${Oe.fi} / ${Oe.total}`:``}),(0,k.jsx)(`span`,{className:$.genBarCounter,children:F.tokIn+F.tokOut>0?`↑${wt(F.tokIn)} ↓${wt(F.tokOut)}`:``}),(0,k.jsx)(`span`,{className:$.genBarTime,children:dt}),(0,k.jsxs)(`span`,{className:$.genDots,children:[(0,k.jsx)(`span`,{className:`${$.dot} ${$.dot1}`}),(0,k.jsx)(`span`,{className:`${$.dot} ${$.dot2}`}),(0,k.jsx)(`span`,{className:`${$.dot} ${$.dot3}`})]})]}),(0,k.jsx)(`div`,{className:$.progressTrack,children:(0,k.jsx)(`div`,{className:$.genProgress,style:{width:Oe.total>0?`${Math.round(Oe.fi/Oe.total*100)}%`:`0%`}})})]}),r===`preview`?(0,k.jsxs)(`div`,{className:$.sandboxWrap,children:[(0,k.jsxs)(`div`,{className:$.sandboxStatusBar,children:[(0,k.jsx)(`span`,{className:$.sandboxStatusDot,style:{background:at?`#4ade80`:st?`#facc15`:`#64748b`}}),(0,k.jsx)(`span`,{className:$.sandboxStatusText,children:at?`Live :${at}`:st?`Starting...`:`Stopped`}),at&&(0,k.jsx)(`button`,{className:$.sandboxReloadBtn,onClick:()=>{let e=document.querySelector(`iframe[title="WebCraft Sandbox"]`);e&&(e.src=e.src)},children:`↻`}),at&&(0,k.jsx)(`button`,{className:$.sandboxStopBtn,onClick:async()=>{ot(null),le([]);try{await fetch(`/api/studio/webcraft/sandbox`,{method:`DELETE`})}catch{}},children:`⏹`}),!at&&!st&&(0,k.jsx)(`button`,{className:$.sandboxStartBtnSmall,onClick:()=>{a&&It(a)},children:`▶ Start`})]}),ce.length>0&&(0,k.jsxs)(`div`,{className:$.runtimeErrors,children:[(0,k.jsxs)(`div`,{className:$.runtimeErrorsHeader,children:[(0,k.jsxs)(`span`,{children:[`❌ `,ce.length,` runtime error`,ce.length>1?`s`:``]}),(0,k.jsx)(`button`,{className:$.runtimeErrorsFix,onClick:()=>{Fe(`Fix these runtime errors:\n${ce.map(e=>`${e.message} (${e.source||``}:${e.line||0})`).join(`
|
|
780
|
-
`)}`),fetch(`/api/studio/webcraft/sandbox/errors`,{method:`DELETE`}),le([]),i(`files`)},children:`🔧 Auto-fix`}),(0,k.jsx)(`button`,{className:$.runtimeErrorsDismiss,onClick:()=>{fetch(`/api/studio/webcraft/sandbox/errors`,{method:`DELETE`}),le([])},children:`✕`})]}),ce.slice(0,3).map((e,t)=>(0,k.jsxs)(`div`,{className:$.runtimeErrorLine,children:[e.message,e.source?` — ${e.source.split(`/`).pop()}:${e.line}`:``]},t))]}),at?(0,k.jsx)(`iframe`,{src:`http://127.0.0.1:${at}`,className:$.sandboxFrame,title:`WebCraft Sandbox`,sandbox:`allow-scripts allow-same-origin allow-forms allow-popups`}):(0,k.jsxs)(`div`,{className:$.sandboxEmpty,children:[(0,k.jsx)(`span`,{style:{fontSize:48},children:st?`⏳`:lt?`❌`:`🌐`}),(0,k.jsx)(`span`,{style:{fontWeight:700,fontSize:16},children:st?`Starting sandbox...`:lt?`Sandbox Error`:`Preview`}),lt&&(0,k.jsx)(`
|
|
780
|
+
`)}`),fetch(`/api/studio/webcraft/sandbox/errors`,{method:`DELETE`}),le([]),i(`files`)},children:`🔧 Auto-fix`}),(0,k.jsx)(`button`,{className:$.runtimeErrorsDismiss,onClick:()=>{fetch(`/api/studio/webcraft/sandbox/errors`,{method:`DELETE`}),le([])},children:`✕`})]}),ce.slice(0,3).map((e,t)=>(0,k.jsxs)(`div`,{className:$.runtimeErrorLine,children:[e.message,e.source?` — ${e.source.split(`/`).pop()}:${e.line}`:``]},t))]}),at?(0,k.jsx)(`iframe`,{src:`http://127.0.0.1:${at}`,className:$.sandboxFrame,title:`WebCraft Sandbox`,sandbox:`allow-scripts allow-same-origin allow-forms allow-popups`}):(0,k.jsxs)(`div`,{className:$.sandboxEmpty,children:[(0,k.jsx)(`span`,{style:{fontSize:48},children:st?`⏳`:lt?`❌`:`🌐`}),(0,k.jsx)(`span`,{style:{fontWeight:700,fontSize:16},children:st?`Starting sandbox...`:lt?`Sandbox Error`:`Preview`}),lt&&(0,k.jsx)(`pre`,{style:{fontSize:11,maxWidth:600,textAlign:`left`,color:`#f87171`,background:`rgba(248,113,113,0.08)`,border:`1px solid rgba(248,113,113,0.2)`,borderRadius:6,padding:`8px 12px`,whiteSpace:`pre-wrap`,wordBreak:`break-word`,margin:`8px 0`,lineHeight:1.5,maxHeight:200,overflow:`auto`},children:lt}),!st&&(0,k.jsxs)(`button`,{className:$.sandboxStartBtn,onClick:()=>{a&&It(a)},children:[`▶ `,lt?`Retry`:`Start Sandbox`]})]})]}):(0,k.jsx)(`div`,{className:$.codeArea,children:p.length===0&&be?(0,k.jsx)(`div`,{className:$.noFiles,children:(0,k.jsxs)(`div`,{className:$.noFilesHero,children:[(0,k.jsx)(`span`,{className:$.noFilesIcon,children:`⏳`}),(0,k.jsx)(`span`,{className:$.noFilesTitle,children:`Pianificazione...`}),(0,k.jsx)(`span`,{className:$.noFilesTagline,children:Oe.name||`Analisi della struttura del progetto in corso`})]})}):p.length===0?(0,k.jsxs)(`div`,{className:$.noFiles,children:[(0,k.jsxs)(`div`,{className:$.noFilesHero,children:[(0,k.jsx)(`span`,{className:$.noFilesIcon,children:`🔨`}),(0,k.jsx)(`span`,{className:$.noFilesTitle,children:`WebCraft`}),(0,k.jsx)(`span`,{className:$.noFilesTagline,children:`Genera progetti web completi con AI`})]}),(0,k.jsxs)(`div`,{className:$.noFilesSteps,children:[(0,k.jsxs)(`div`,{className:$.noFilesStep,children:[(0,k.jsx)(`span`,{className:$.noFilesStepNum,children:`1`}),(0,k.jsx)(`span`,{children:`Scegli un esempio o scrivi una descrizione nel box in basso`})]}),(0,k.jsxs)(`div`,{className:$.noFilesStep,children:[(0,k.jsx)(`span`,{className:$.noFilesStepNum,children:`2`}),(0,k.jsxs)(`span`,{children:[`Premi `,(0,k.jsx)(`strong`,{children:`▶ Genera`}),` — l'AI crea tutti i file del progetto`]})]}),(0,k.jsxs)(`div`,{className:$.noFilesStep,children:[(0,k.jsx)(`span`,{className:$.noFilesStepNum,children:`3`}),(0,k.jsx)(`span`,{children:`Chiedi modifiche in chat, scarica lo ZIP o avvia il Sandbox`})]})]}),(0,k.jsxs)(`div`,{className:$.noFilesExamplesHint,children:[`💡 Prova: `,(0,k.jsx)(`button`,{className:$.noFilesExampleBtn,onClick:()=>{let e=zT[0];o(e.name),c(e.desc),Fe(e.desc)},children:`MySaaS`}),(0,k.jsx)(`button`,{className:$.noFilesExampleBtn,onClick:()=>{let e=zT[1];o(e.name),c(e.desc),Fe(e.desc)},children:`MyShop`}),(0,k.jsx)(`button`,{className:$.noFilesExampleBtn,onClick:()=>{let e=zT[3];o(e.name),c(e.desc),Fe(e.desc)},children:`MyPortfolio`})]})]}):(0,k.jsxs)(`div`,{className:$.codeLayout,children:[(0,k.jsx)(`div`,{className:$.ideTabBar,children:p.map((e,t)=>{let n=e._error||!!e._syntaxError,r=t===h;return(0,k.jsxs)(`button`,{className:`${$.ideTab} ${r?$.ideTabActive:``} ${n?$.ideTabError:``} ${e._pending?$.ideTabPending:``}`,onClick:()=>{g(t),x(null),y(null),be&&M.current!==null&&t!==M.current&&(fe.current&&clearTimeout(fe.current),fe.current=setTimeout(()=>{M.current!==null&&(g(M.current),y(null))},1e4))},title:e.name,children:[(0,k.jsx)(`span`,{className:$.ideTabIcon,children:e._pending?`⌛`:n?`⚠`:HT(e.name)}),(0,k.jsx)(`span`,{className:$.ideTabName,children:e.name.split(`/`).pop()}),S.has(e.name)&&(0,k.jsx)(`span`,{className:$.ideTabUnsaved,children:`●`}),n&&(0,k.jsx)(`span`,{className:$.ideTabDot})]},t)})}),ve&&(0,k.jsxs)(`div`,{className:$.diffOverlay,children:[(0,k.jsxs)(`div`,{className:$.diffOverlayHeader,children:[(0,k.jsxs)(`span`,{children:[`✏ Modifica proposta — `,(0,k.jsx)(`strong`,{children:ve.file})]}),(0,k.jsxs)(`div`,{className:$.diffOverlayActions,children:[(0,k.jsx)(`button`,{className:$.diffAcceptBtn,onClick:()=>{m(e=>e.map(e=>e.name===ve.file?{...e,content:ve.after}:e)),ye(null)},children:`✓ Accetta`}),(0,k.jsx)(`button`,{className:$.diffRejectBtn,onClick:()=>ye(null),children:`✕ Rifiuta`})]})]}),(0,k.jsx)(`div`,{className:$.diffOverlayBody,children:(0,k.jsx)(YT,{before:ve.before,after:ve.after})})]}),(0,k.jsxs)(`div`,{className:$.codeRow,children:[(0,k.jsxs)(`div`,{className:$.fileTreeWrap,children:[ue.length>0&&(0,k.jsxs)(`div`,{className:$.scanBanner,children:[(0,k.jsx)(`span`,{className:$.scanBannerIcon,children:`⚠`}),(0,k.jsxs)(`span`,{className:$.scanBannerText,children:[ue.length,` issue`,ue.length>1?`s`:``]}),(0,k.jsx)(`button`,{className:$.scanBannerFix,onClick:()=>{Fe(`Fix all these issues:\n${ue.map(e=>`[${e.severity}] ${e.file}: ${e.message}`).join(`
|
|
781
781
|
`)}`),i(`files`)},children:`Fix`})]}),(0,k.jsx)(jT,{files:p,activeIndex:h,unsavedFiles:S,onSelect:e=>{g(e),x(null),y(null),be&&M.current!==null&&e!==M.current&&(fe.current&&clearTimeout(fe.current),fe.current=setTimeout(()=>{M.current!==null&&(g(M.current),y(null))},1e4))}})]}),(0,k.jsx)(`div`,{className:$.codeEditorWrap,children:Jt&&(0,k.jsxs)(k.Fragment,{children:[(0,k.jsxs)(`div`,{className:$.codeHeader,children:[(0,k.jsx)(`span`,{className:$.codeFileIcon,children:HT(Jt.name)}),(0,k.jsx)(`span`,{className:$.codeFileName,children:Jt.name}),Jt.content&&!Jt._error&&(0,k.jsxs)(`span`,{className:$.codeFileMeta,children:[Jt.content.split(`
|
|
782
782
|
`).length,` righe · `,UT(Jt.content)]}),!Jt._pending&&!Jt._error&&Jt.content&&(0,k.jsx)(`button`,{className:`${$.editToggleBtn} ${b===null?``:$.editToggleBtnActive}`,onClick:()=>{b===null?x(Jt.content):(m(e=>e.map((e,t)=>t===h?{...e,content:b}:e)),D(`/api/studio/webcraft/file/write`,{projectName:a,path:Jt.name,content:b}),x(null))},children:b===null?`✏ Modifica`:`💾 Salva`}),(0,k.jsx)(`button`,{className:$.headerIconBtn,title:`Split view`,onClick:()=>A(ae===null?+(h===0&&p.length>1):null),children:`⫼`}),(0,k.jsx)(`button`,{className:`${$.headerIconBtn} ${ie?$.headerIconBtnActive:``}`,title:`Terminal`,onClick:()=>O(!ie),children:`⌨`}),(0,k.jsx)(`button`,{className:$.headerIconBtn,title:`Development Guide`,onClick:()=>se(!0),children:`📖`})]}),w&&(0,k.jsxs)(`div`,{className:$.findBar,children:[(0,k.jsx)(`input`,{className:$.findInput,value:te,onChange:e=>T(e.target.value),placeholder:`Find...`,autoFocus:!0}),(0,k.jsx)(`input`,{className:$.findInput,value:ne,onChange:e=>re(e.target.value),placeholder:`Replace...`}),(0,k.jsx)(`span`,{className:$.findCount,children:te?((Jt.content||``).match(new RegExp(te.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),`gi`))?.length||0)+` found`:``}),(0,k.jsx)(`button`,{className:$.findBtn,onClick:()=>{!te||b===null||x(b.replace(new RegExp(te.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),`i`),ne))},children:`Replace`}),(0,k.jsx)(`button`,{className:$.findBtn,onClick:()=>{!te||b===null||x(b.replace(new RegExp(te.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),`gi`),ne))},children:`All`}),(0,k.jsx)(`button`,{className:$.findClose,onClick:()=>ee(!1),children:`×`})]}),Jt._error&&(0,k.jsx)(`div`,{className:$.fileError,children:`⚠ Generazione fallita — chiedi al modello di rigenerare questo file`}),Jt._syntaxError&&!Jt._error&&(0,k.jsxs)(`div`,{className:$.fileSyntaxError,children:[`⚠ Syntax error: `,Jt._syntaxError]}),be&&v!==null?(0,k.jsx)(`pre`,{className:$.streamingPre,ref:e=>{e&&pe.current&&(e.scrollTop=e.scrollHeight)},onScroll:e=>{let t=e.currentTarget;t.scrollHeight-t.scrollTop-t.clientHeight<50?pe.current=!0:(pe.current=!1,me.current&&clearTimeout(me.current),me.current=setTimeout(()=>{pe.current=!0},15e3))},dangerouslySetInnerHTML:{__html:LT(v||``,(Jt.name.split(`.`).pop()||`js`).toLowerCase())+`<span class="`+$.streamingCursor+`">▋</span>`}}):(0,k.jsx)(TT,{value:b===null?Jt.content||``:b,filename:Jt.name,readOnly:b===null,projectName:a,onChange:e=>{x(e),Jt&&C(e=>new Set(e).add(Jt.name))},onSave:e=>{m(t=>t.map((t,n)=>n===h?{...t,content:e}:t)),D(`/api/studio/webcraft/file/write`,{projectName:a,path:Jt.name,content:e}),x(null),C(e=>{let t=new Set(e);return t.delete(Jt.name),t})}})]})}),ae!==null&&p[ae]&&(0,k.jsxs)(`div`,{className:$.codeEditorWrap,children:[(0,k.jsxs)(`div`,{className:$.codeHeader,children:[(0,k.jsx)(`span`,{className:$.codeFileIcon,children:HT(p[ae].name)}),(0,k.jsx)(`span`,{className:$.codeFileName,children:p[ae].name}),(0,k.jsx)(`button`,{className:$.headerIconBtn,onClick:()=>A(null),children:`✕`})]}),(0,k.jsx)(TT,{value:p[ae].content||``,filename:p[ae].name,readOnly:!0})]})]}),ie&&(0,k.jsxs)(`div`,{className:$.terminalPanel,children:[(0,k.jsxs)(`div`,{className:$.terminalHeader,children:[(0,k.jsx)(`span`,{className:$.terminalTitle,children:`Terminal`}),(0,k.jsx)(`button`,{className:$.terminalClose,onClick:()=>O(!1),children:`✕`})]}),(0,k.jsx)(IT,{projectDir:a||void 0})]})]})})]})]})]})}),L&&t!==`projects`&&(0,k.jsxs)(`div`,{className:$.planBanner,children:[(0,k.jsx)(`div`,{className:$.planTitle,children:`📌 Piano proposto — approva per eseguire`}),(0,k.jsx)(`pre`,{className:$.planText,children:L.plan}),(0,k.jsxs)(`div`,{className:$.planActions,children:[(0,k.jsx)(`button`,{className:$.planApprove,onClick:U,children:`✓ Esegui`}),(0,k.jsx)(`button`,{className:$.planReject,onClick:()=>Be(null),children:`✕ Annulla`})]})]}),Ye&&t!==`projects`&&(0,k.jsxs)(`div`,{className:$.grepPanel,children:[(0,k.jsxs)(`div`,{className:$.grepRow,children:[(0,k.jsx)(`input`,{className:$.grepInput,value:Ze,onChange:e=>Qe(e.target.value),onKeyDown:e=>e.key===`Enter`&&Rt(),placeholder:`Cerca nel codice...`}),(0,k.jsx)(`button`,{className:$.grepBtn,onClick:Rt,children:`🔍`}),(0,k.jsx)(`button`,{className:$.grepClose,onClick:()=>Xe(!1),children:`×`})]}),$e.length>0&&(0,k.jsxs)(`div`,{className:$.grepCount,children:[$e.length,` risultati`]}),(0,k.jsx)(`div`,{className:$.grepResults,children:$e.length===0?(0,k.jsx)(`div`,{className:$.grepEmpty,children:`Nessun risultato.`}):$e.map((e,t)=>(0,k.jsxs)(`div`,{className:$.grepMatch,onClick:()=>zt(e.file),children:[(0,k.jsxs)(`span`,{className:$.grepMatchFile,children:[e.file,`:`,e.lineNum]}),(0,k.jsx)(`pre`,{className:$.grepMatchLine,children:e.line})]},t))})]}),tt.length>0&&t!==`projects`&&(0,k.jsxs)(`div`,{className:$.diffPanel,children:[(0,k.jsxs)(`div`,{className:$.diffHeader,children:[(0,k.jsxs)(`span`,{children:[`🔌 Diff — `,tt.length,` file modificati`]}),(0,k.jsx)(`button`,{className:$.diffClose,onClick:()=>nt([]),children:`✕ Chiudi`})]}),tt.map((e,t)=>{let n=e.after.split(`
|
|
783
783
|
`).length-e.before.split(`
|
package/src/ui-dist/index.html
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
|
9
9
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
10
10
|
<title>NHA — NotHumanAllowed</title>
|
|
11
|
-
<script type="module" crossorigin src="/assets/index-
|
|
11
|
+
<script type="module" crossorigin src="/assets/index-wcl8Kj42.js"></script>
|
|
12
12
|
<link rel="stylesheet" crossorigin href="/assets/index-CIozt-VX.css">
|
|
13
13
|
</head>
|
|
14
14
|
<body>
|