nothumanallowed 14.1.19 → 14.1.20

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.1.19",
3
+ "version": "14.1.20",
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.1.19';
8
+ export const VERSION = '14.1.20';
9
9
  export const BASE_URL = 'https://nothumanallowed.com/cli';
10
10
  export const API_BASE = 'https://nothumanallowed.com/api/v1';
11
11
 
@@ -527,7 +527,95 @@ ${u}
527
527
 
528
528
  `),r=`The user asked: "${e}"\n\nHere are the responses from ${t.length} specialist agents:\n\n${n}\n\nSynthesize these responses into a unified analysis.`,i=``;try{await ie(`/api/chat/stream`,{message:r,systemPrompt:`You are the Conductor — a meta-agent that synthesizes the outputs of multiple specialist AI agents.
529
529
  Your job: examine all agent responses to a user's question, identify agreements, disagreements, complementary insights, and deliver a unified, high-quality synthesis.
530
- Be concise. Highlight what each agent contributed uniquely. Give your own synthesis verdict at the end.`},e=>{i+=e,g(i)})}catch{}finally{y(!1)}},pe=e=>{let t=window.SpeechRecognition??window.webkitSpeechRecognition;if(!t){alert(`Speech recognition not supported.`);return}let n=T.current.get(e);if(l.find(t=>t.agent.id===e)?.voiceActive&&n){n.stop(),F(e,{voiceActive:!1});return}let r=new t;T.current.set(e,r),r.lang=`it-IT`,r.continuous=!1,r.interimResults=!1,r.onresult=t=>{let n=t.results[0][0].transcript;F(e,{input:(l.find(t=>t.agent.id===e)?.input??``)+(l.find(t=>t.agent.id===e)?.input?` `:``)+n})},r.onend=()=>F(e,{voiceActive:!1}),r.onerror=()=>F(e,{voiceActive:!1}),r.start(),F(e,{voiceActive:!0})},me=(e,t)=>{if(!t)return;let n=t.name.toLowerCase().endsWith(`.pdf`)||t.type===`application/pdf`,r=new FileReader;n?(r.onload=n=>{let r=(n.target?.result).split(`,`)[1];F(e,{attachedFile:{name:t.name,size:t.size,base64:r,mimeType:`application/pdf`,isPDF:!0},attachedImage:null})},r.readAsDataURL(t)):(r.onload=n=>{F(e,{attachedFile:{name:t.name,size:t.size,content:n.target?.result},attachedImage:null})},r.readAsText(t))},he=(e,t)=>{if(!t)return;let n=new FileReader;n.onload=n=>{let r=(n.target?.result).split(`,`)[1];F(e,{attachedImage:{name:t.name,size:t.size,base64:r,mimeType:t.type||`image/jpeg`},attachedFile:null})},n.readAsDataURL(t)},ge=()=>{x({name:``,tagline:``,systemPrompt:``}),C(`create`),ee(``)},L=async e=>{let t=await E(`/api/agents/${e.id}`).catch(()=>null);x({name:e.id,tagline:t?.tagline??e.description,systemPrompt:t?.systemPrompt??``}),C(`edit`),ee(``)},_e=async()=>{if(b){if(!b.tagline.trim()||!b.systemPrompt.trim()){ee(`Tagline and system prompt are required.`);return}ne(!0),ee(``);try{if(S===`create`){let e=b.name.toLowerCase().replace(/[^a-z0-9_-]/g,``);if(!e){ee(`Agent name required (lowercase, no spaces).`),ne(!1);return}let t=await D(`/api/agents`,{name:e,tagline:b.tagline,systemPrompt:b.systemPrompt});if(t?.error){ee(`Error: `+t.error),ne(!1);return}}else await D(`/api/agents/${b.name}`,{tagline:b.tagline,systemPrompt:b.systemPrompt,category:`custom`},`PUT`);x(null),oe()}catch(e){ee(`Error: `+e.message)}finally{ne(!1)}}},ve=e=>{confirm(`Delete agent "${e.label}"?`)&&D(`/api/agents/${e.id}`,{},`DELETE`).then(()=>oe())};return r?(0,k.jsx)(`div`,{className:q.root,children:(0,k.jsx)(`div`,{className:q.loading,children:(0,k.jsx)(`div`,{className:`spinner`})})}):(0,k.jsxs)(`div`,{className:q.root,children:[(0,k.jsxs)(`div`,{className:q.gridSection,children:[(0,k.jsxs)(`div`,{className:q.gridHeader,children:[(0,k.jsxs)(`div`,{className:q.headerRow,children:[(0,k.jsx)(`input`,{className:q.search,value:a,onChange:e=>o(e.target.value),placeholder:`Search agents…`}),(0,k.jsx)(`button`,{className:q.createBtn,onClick:ge,children:`+ Create`})]}),(0,k.jsx)(`div`,{className:q.catTabs,children:se.map(e=>(0,k.jsxs)(`button`,{className:`${q.catTab} ${s===e?q.catActive:``}`,onClick:()=>c(e),children:[e,` (`,e===`All`?t.length:t.filter(t=>t.category===e).length,`)`]},e))})]}),(0,k.jsx)(`div`,{className:q.grid,children:M.map(e=>{let t=l.some(t=>t.agent.id===e.id);return(0,k.jsxs)(`div`,{className:`${q.agentCard} ${t?q.agentActive:``}`,onClick:()=>ce(e),children:[(0,k.jsxs)(`div`,{className:q.agentCardTop,children:[(0,k.jsx)(`div`,{className:q.agentIcon,children:e.icon}),e.isCustom&&(0,k.jsxs)(`div`,{className:q.agentActions,children:[(0,k.jsx)(`button`,{className:q.agentEditBtn,onClick:t=>{t.stopPropagation(),L(e)},children:`✏️`}),(0,k.jsx)(`button`,{className:q.agentDelBtn,onClick:t=>{t.stopPropagation(),ve(e)},children:`🗑`})]})]}),(0,k.jsx)(`div`,{className:q.agentLabel,children:e.label}),(0,k.jsx)(`div`,{className:q.agentDesc,children:e.description}),(0,k.jsx)(`div`,{className:q.agentCat,children:e.category})]},e.id)})})]}),(0,k.jsx)(`div`,{className:q.chatArea,children:l.length===0?(0,k.jsxs)(`div`,{className:q.emptyChat,children:[(0,k.jsx)(`span`,{children:`Click an agent above to open a chat`}),(0,k.jsx)(`span`,{className:q.emptyChatHint,children:`Open multiple agents to run them in parallel`})]}):l.map(e=>{let{agent:t}=e,n=e.attachedFile?`📎 ${e.attachedFile.name}`:e.attachedImage?`🖼 ${e.attachedImage.name}`:null;return(0,k.jsxs)(`div`,{className:q.chatPanel,children:[(0,k.jsxs)(`div`,{className:q.chatHeader,children:[(0,k.jsx)(`span`,{className:q.chatIcon,children:t.icon}),(0,k.jsxs)(`div`,{className:q.chatHeaderInfo,children:[(0,k.jsx)(`div`,{className:q.chatAgentName,children:t.label}),(0,k.jsx)(`div`,{className:q.chatAgentDesc,children:t.description})]}),(0,k.jsx)(`button`,{className:q.closeChat,onClick:()=>N(t.id),children:`✕`})]}),(0,k.jsxs)(`div`,{className:q.chatMessages,ref:e=>{O.current.set(t.id,e)},children:[e.history.length===0&&(0,k.jsxs)(`div`,{className:q.chatEmpty,children:[`Ask `,t.label,` anything…`]}),e.history.map((e,t)=>(0,k.jsx)(`div`,{className:`${q.chatMsg} ${e.role===`user`?q.msgUser:q.msgAgent}`,children:e.role===`assistant`?(0,k.jsx)(`div`,{dangerouslySetInnerHTML:{__html:fe(e.content||`…`)}}):(0,k.jsx)(`span`,{children:e.content})},t)),e.streaming&&e.history[e.history.length-1]?.role===`assistant`&&e.history[e.history.length-1]?.content===``&&(0,k.jsxs)(`div`,{className:q.thinking,children:[(0,k.jsx)(`span`,{className:q.dot}),(0,k.jsx)(`span`,{className:q.dot}),(0,k.jsx)(`span`,{className:q.dot})]})]}),n&&(0,k.jsxs)(`div`,{className:q.attachBar,children:[(0,k.jsx)(`span`,{children:n}),(0,k.jsx)(`button`,{className:q.attachClear,onClick:()=>F(t.id,{attachedFile:null,attachedImage:null}),children:`×`})]}),(0,k.jsxs)(`div`,{className:q.chatInput,children:[(0,k.jsxs)(`div`,{className:q.chatTools,children:[(0,k.jsx)(`button`,{className:`${q.toolBtn} ${e.voiceActive?q.toolBtnActive:``}`,onClick:()=>pe(t.id),title:`Voice`,children:`🎤`}),(0,k.jsx)(`button`,{className:q.toolBtn,onClick:()=>ae.current.get(t.id)?.click(),title:`Attach file`,children:`📎`}),(0,k.jsx)(`button`,{className:q.toolBtn,onClick:()=>A.current.get(t.id)?.click(),title:`Attach image`,children:`🖼`}),(0,k.jsx)(`input`,{type:`file`,style:{display:`none`},ref:e=>{ae.current.set(t.id,e)},onChange:e=>me(t.id,e.target.files?.[0])}),(0,k.jsx)(`input`,{type:`file`,accept:`image/*`,style:{display:`none`},ref:e=>{A.current.set(t.id,e)},onChange:e=>he(t.id,e.target.files?.[0])})]}),(0,k.jsxs)(`div`,{className:q.chatInputRow,children:[(0,k.jsx)(`textarea`,{className:q.chatTextarea,value:e.input,onChange:e=>F(t.id,{input:e.target.value}),placeholder:`Message ${t.label}…`,rows:2,onKeyDown:t=>{t.key===`Enter`&&!t.shiftKey&&(t.preventDefault(),de(e,e.input,e.attachedFile,e.attachedImage))}}),(0,k.jsx)(`button`,{className:q.sendBtn,onClick:()=>de(e,e.input,e.attachedFile,e.attachedImage),disabled:e.streaming||!e.input.trim()&&!e.attachedFile&&!e.attachedImage,children:e.streaming?`…`:`→`})]})]})]},t.id)})}),l.length>=2&&(0,k.jsxs)(`div`,{className:q.orchBar,children:[(0,k.jsxs)(`div`,{className:q.orchLabel,children:[`🎼 Conductor · `,l.map(e=>`${e.agent.icon} ${e.agent.label}`).join(` · `)]}),(0,k.jsxs)(`div`,{className:q.orchRow,children:[(0,k.jsx)(`textarea`,{ref:j,className:q.orchInput,value:d,onChange:e=>f(e.target.value),placeholder:`Ask all agents — Conductor will synthesize a unified response…`,rows:1,onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),I())}}),(0,k.jsx)(`button`,{className:q.orchBtn,onClick:I,disabled:p||v||!d.trim(),children:p?`⏳`:v?`🔄`:`🎼 Run`})]}),(v||h)&&(0,k.jsxs)(`div`,{className:q.orchSynthesis,children:[(0,k.jsxs)(`div`,{className:q.orchSynthHeader,children:[(0,k.jsx)(`span`,{children:`🎼 Conductor Synthesis`}),v&&(0,k.jsx)(`span`,{className:q.orchSynthSpinner,children:`synthesizing…`})]}),(0,k.jsx)(`div`,{className:q.orchSynthBody,dangerouslySetInnerHTML:{__html:fe(h||`…`)}})]})]}),b&&(0,k.jsx)(`div`,{className:q.modalOverlay,onClick:e=>{e.target===e.currentTarget&&x(null)},children:(0,k.jsxs)(`div`,{className:q.modal,children:[(0,k.jsx)(`div`,{className:q.modalTitle,children:S===`create`?`+ New Agent`:`✏️ Edit Agent`}),S===`create`&&(0,k.jsxs)(`div`,{className:q.formField,children:[(0,k.jsx)(`label`,{className:q.formLabel,children:`Agent name (lowercase, no spaces)`}),(0,k.jsx)(`input`,{className:q.formInput,placeholder:`my-agent`,value:b.name,onChange:e=>x(t=>t&&{...t,name:e.target.value})})]}),(0,k.jsxs)(`div`,{className:q.formField,children:[(0,k.jsx)(`label`,{className:q.formLabel,children:`Tagline`}),(0,k.jsx)(`input`,{className:q.formInput,placeholder:`Short description`,value:b.tagline,onChange:e=>x(t=>t&&{...t,tagline:e.target.value})})]}),(0,k.jsxs)(`div`,{className:q.formField,children:[(0,k.jsx)(`label`,{className:q.formLabel,children:`System Prompt`}),(0,k.jsx)(`textarea`,{className:q.formTextarea,placeholder:`You are an expert in…`,value:b.systemPrompt,onChange:e=>x(t=>t&&{...t,systemPrompt:e.target.value})})]}),w&&(0,k.jsx)(`div`,{className:q.formError,children:w}),(0,k.jsxs)(`div`,{className:q.modalBtns,children:[(0,k.jsx)(`button`,{className:q.cancelBtn,onClick:()=>x(null),children:e(`common.cancel`)}),(0,k.jsx)(`button`,{className:q.modalSaveBtn,onClick:_e,disabled:te,children:te?`…`:S===`create`?`Create Agent`:`Save`})]})]})})]})}var J={root:`_root_1mam6_1`,error:`_error_1mam6_10`,errorHint:`_errorHint_1mam6_16`,quotaBar:`_quotaBar_1mam6_29`,quotaText:`_quotaText_1mam6_37`,quotaUsed:`_quotaUsed_1mam6_43`,quotaPct:`_quotaPct_1mam6_44`,quotaTrack:`_quotaTrack_1mam6_46`,quotaFill:`_quotaFill_1mam6_53`,actionBar:`_actionBar_1mam6_59`,filterBtn:`_filterBtn_1mam6_67`,filterActive:`_filterActive_1mam6_79`,spacer:`_spacer_1mam6_85`,newBtn:`_newBtn_1mam6_87`,uploadBtn:`_uploadBtn_1mam6_98`,searchRow:`_searchRow_1mam6_108`,searchInput:`_searchInput_1mam6_114`,searchBtn:`_searchBtn_1mam6_126`,loading:`_loading_1mam6_136`,empty:`_empty_1mam6_141`,fileList:`_fileList_1mam6_151`,fileRow:`_fileRow_1mam6_159`,fileIcon:`_fileIcon_1mam6_172`,fileInfo:`_fileInfo_1mam6_174`,fileName:`_fileName_1mam6_176`,fileMeta:`_fileMeta_1mam6_184`,fileBtns:`_fileBtns_1mam6_190`,editBtn:`_editBtn_1mam6_196`,viewBtn:`_viewBtn_1mam6_197`,pdfBtn:`_pdfBtn_1mam6_198`,openBtn:`_openBtn_1mam6_199`,delBtn:`_delBtn_1mam6_200`,editorRoot:`_editorRoot_1mam6_204`,editorToolbar:`_editorToolbar_1mam6_211`,backBtn:`_backBtn_1mam6_221`,editorName:`_editorName_1mam6_231`,saveBtn:`_saveBtn_1mam6_238`,editorArea:`_editorArea_1mam6_251`,editorMeta:`_editorMeta_1mam6_266`,viewerRoot:`_viewerRoot_1mam6_276`,imgContainer:`_imgContainer_1mam6_283`,imgView:`_imgView_1mam6_292`,pdfFrame:`_pdfFrame_1mam6_298`};function Wt(e,t){return e===`folder`?`📁`:e===`image`?`🖼`:e===`pdf`||t.includes(`pdf`)?`📕`:e===`video`?`🎬`:e===`audio`?`🎵`:t.includes(`spreadsheet`)||t.includes(`excel`)?`📊`:t.includes(`presentation`)||t.includes(`powerpoint`)?`📽`:t.includes(`document`)||t.includes(`word`)?`📄`:t.includes(`zip`)||t.includes(`archive`)?`📦`:`📄`}function Gt(e){let t=e.mimeType;return e.type===`text`||e.type===`doc`||t.includes(`text`)||t.includes(`json`)||t.includes(`javascript`)||t.includes(`xml`)||t.includes(`csv`)||t.includes(`yaml`)||t.includes(`markdown`)||t.includes(`html`)||t.includes(`css`)||t.includes(`python`)||t.includes(`vnd.google-apps.document`)}function Kt(){let e=P(),[t,n]=(0,_.useState)(null),[r,i]=(0,_.useState)(!0),[a,o]=(0,_.useState)(``),[s,c]=(0,_.useState)(``),[l,u]=(0,_.useState)(``),[d,f]=(0,_.useState)(``),[p,m]=(0,_.useState)(`list`),[h,g]=(0,_.useState)(null),[v,y]=(0,_.useState)(``),[b,x]=(0,_.useState)(null),[S,C]=(0,_.useState)(!1),w=(0,_.useRef)(null),ee=(e=s,t=l)=>{i(!0);let r=`/api/drive`;e&&(r+=`?filter=${e}`),t&&(r+=`${e?`&`:`?`}search=${encodeURIComponent(t)}`),E(r).then(e=>{n(e??{files:[]}),i(!1)}).catch(e=>{o(e.message??`Error`),i(!1)})};(0,_.useEffect)(()=>{ee()},[]);let te=e=>{c(e),ee(e,l)},ne=()=>{u(d),ee(s,d)},T=(e,t)=>{i(!0),E(`/api/drive/read/${e}`).then(n=>{g({id:e,name:t,content:n?.content??``}),y(n?.content??``),m(`editor`),i(!1)}).catch(()=>i(!1))},re=async()=>{if(h&&confirm(`Save changes to "${h.name}" on Drive?`)){C(!0);try{await D(`/api/drive/update/${h.id}`,{content:v}),g(e=>e&&{...e,content:v}),alert(`Saved!`)}catch(e){alert(`Save failed: `+e.message)}finally{C(!1)}}},ie=(e,t)=>{i(!0),E(`/api/drive/download/${e}`).then(n=>{x({id:e,name:t,src:`data:${n?.mimeType??`image/jpeg`};base64,${n?.base64}`,mode:`image`}),m(`image`),i(!1)}).catch(()=>i(!1))},O=(e,t)=>{i(!0),E(`/api/drive/download/${e}`).then(n=>{x({id:e,name:t,src:`data:application/pdf;base64,${n?.base64}`,mode:`pdf`}),m(`pdf`),i(!1)}).catch(()=>i(!1))},ae=(e,t)=>{confirm(`Delete "${t}" from Drive? (moved to trash)`)&&D(`/api/drive/delete/${e}`,{}).then(()=>{n(null),ee()})},A=()=>{let e=prompt(`File name (e.g. notes.txt, script.py):`);e&&D(`/api/drive/upload`,{name:e,content:``,mimeType:`text/plain`}).then(t=>{t?.id?T(t.id,e):ee()}).catch(e=>alert(`Error: `+e.message))},j=()=>{w.current?.click()},oe=e=>{if(!e)return;let t=new FileReader;t.onload=t=>{let r=(t.target?.result).split(`,`)[1]??``;D(`/api/drive/upload`,{name:e.name,content:r,mimeType:e.type||`application/octet-stream`,encoding:`base64`}).then(()=>{n(null),ee()}).catch(e=>alert(`Upload error: `+e.message))},t.readAsDataURL(e)};if(a)return(0,k.jsxs)(`div`,{className:J.error,children:[(0,k.jsx)(`div`,{children:a}),(0,k.jsxs)(`div`,{className:J.errorHint,children:[`Run: `,(0,k.jsx)(`code`,{children:`nha google revoke`}),` then `,(0,k.jsx)(`code`,{children:`nha google auth`})]})]});if(p===`editor`&&h)return(0,k.jsxs)(`div`,{className:J.editorRoot,children:[(0,k.jsxs)(`div`,{className:J.editorToolbar,children:[(0,k.jsx)(`button`,{className:J.backBtn,onClick:()=>m(`list`),children:`← Back`}),(0,k.jsx)(`span`,{className:J.editorName,children:h.name}),(0,k.jsx)(`button`,{className:J.saveBtn,onClick:re,disabled:S,children:S?`Saving…`:`Save to Drive`})]}),(0,k.jsx)(`textarea`,{className:J.editorArea,value:v,onChange:e=>y(e.target.value),spellCheck:!1,onKeyDown:e=>{if(e.key===`Tab`){e.preventDefault();let t=e.currentTarget.selectionStart,n=e.currentTarget.selectionEnd,r=e.currentTarget.value;e.currentTarget.value=r.slice(0,t)+` `+r.slice(n),e.currentTarget.selectionStart=e.currentTarget.selectionEnd=t+2}}}),(0,k.jsxs)(`div`,{className:J.editorMeta,children:[`File ID: `,h.id,` · Tab = 2 spaces · Not auto-saved`]})]});if(p===`image`&&b)return(0,k.jsxs)(`div`,{className:J.viewerRoot,children:[(0,k.jsxs)(`div`,{className:J.editorToolbar,children:[(0,k.jsx)(`button`,{className:J.backBtn,onClick:()=>m(`list`),children:`← Back`}),(0,k.jsx)(`span`,{className:J.editorName,children:b.name})]}),(0,k.jsx)(`div`,{className:J.imgContainer,children:(0,k.jsx)(`img`,{src:b.src,alt:b.name,className:J.imgView})})]});if(p===`pdf`&&b)return(0,k.jsxs)(`div`,{className:J.viewerRoot,children:[(0,k.jsxs)(`div`,{className:J.editorToolbar,children:[(0,k.jsx)(`button`,{className:J.backBtn,onClick:()=>m(`list`),children:`← Back`}),(0,k.jsx)(`span`,{className:J.editorName,children:b.name})]}),(0,k.jsx)(`iframe`,{className:J.pdfFrame,src:b.src,title:b.name})]});let se=t?.files??[],M=t?.quota;return(0,k.jsxs)(`div`,{className:J.root,children:[M&&(0,k.jsxs)(`div`,{className:J.quotaBar,children:[(0,k.jsxs)(`div`,{className:J.quotaText,children:[(0,k.jsxs)(`span`,{className:J.quotaUsed,children:[M.usage,` of `,M.limit,` used`]}),(0,k.jsxs)(`span`,{className:J.quotaPct,children:[M.percentUsed,`%`]})]}),(0,k.jsx)(`div`,{className:J.quotaTrack,children:(0,k.jsx)(`div`,{className:J.quotaFill,style:{width:`${Math.min(M.percentUsed,100)}%`,background:M.percentUsed>90?`var(--red)`:M.percentUsed>70?`var(--amber)`:`var(--green)`}})})]}),(0,k.jsxs)(`div`,{className:J.actionBar,children:[[``,`recent`,`starred`,`shared`].map(e=>(0,k.jsx)(`button`,{className:`${J.filterBtn} ${s===e?J.filterActive:``}`,onClick:()=>te(e),children:e?e.charAt(0).toUpperCase()+e.slice(1):`All Files`},e)),(0,k.jsx)(`div`,{className:J.spacer}),(0,k.jsx)(`button`,{className:J.newBtn,onClick:A,children:`+ New File`}),(0,k.jsx)(`button`,{className:J.uploadBtn,onClick:j,children:e(`drive.upload`)}),(0,k.jsx)(`input`,{ref:w,type:`file`,style:{display:`none`},onChange:e=>oe(e.target.files?.[0])})]}),(0,k.jsxs)(`div`,{className:J.searchRow,children:[(0,k.jsx)(`input`,{className:J.searchInput,value:d,onChange:e=>f(e.target.value),placeholder:`Search files…`,onKeyDown:e=>e.key===`Enter`&&ne()}),(0,k.jsx)(`button`,{className:J.searchBtn,onClick:ne,children:`Search`})]}),r&&(0,k.jsx)(`div`,{className:J.loading,children:(0,k.jsx)(`div`,{className:`spinner`})}),!r&&se.length===0&&(0,k.jsxs)(`div`,{className:J.empty,children:[e(`drive.noFiles`),` found`]}),(0,k.jsx)(`div`,{className:J.fileList,children:se.map(e=>{let t=Gt(e),n=e.type===`image`,r=e.type===`pdf`||e.mimeType.includes(`pdf`);return(0,k.jsxs)(`div`,{className:J.fileRow,onClick:()=>{t?T(e.id,e.name):n?ie(e.id,e.name):r?O(e.id,e.name):e.webViewLink&&window.open(e.webViewLink,`_blank`)},style:{cursor:t||n||r||e.webViewLink?`pointer`:`default`},children:[(0,k.jsx)(`span`,{className:J.fileIcon,children:Wt(e.type,e.mimeType)}),(0,k.jsxs)(`div`,{className:J.fileInfo,children:[(0,k.jsx)(`div`,{className:J.fileName,children:e.name}),(0,k.jsxs)(`div`,{className:J.fileMeta,children:[e.modifiedTime?new Date(e.modifiedTime).toLocaleDateString():``,e.size?` · ${e.size}`:``,e.shared?` · Shared`:``,e.starred?` ★`:``]})]}),(0,k.jsxs)(`div`,{className:J.fileBtns,children:[t&&(0,k.jsx)(`button`,{className:J.editBtn,onClick:t=>{t.stopPropagation(),T(e.id,e.name)},children:`Edit`}),n&&(0,k.jsx)(`button`,{className:J.viewBtn,onClick:t=>{t.stopPropagation(),ie(e.id,e.name)},children:`View`}),r&&(0,k.jsx)(`button`,{className:J.pdfBtn,onClick:t=>{t.stopPropagation(),O(e.id,e.name)},children:`PDF`}),e.webViewLink&&(0,k.jsx)(`a`,{className:J.openBtn,href:e.webViewLink,target:`_blank`,rel:`noreferrer`,onClick:e=>e.stopPropagation(),children:`Open ↗`}),(0,k.jsx)(`button`,{className:J.delBtn,onClick:t=>{t.stopPropagation(),ae(e.id,e.name)},children:`Del`})]})]},e.id)})})]})}var Y={root:`_root_a0x57_1`,loading:`_loading_a0x57_10`,errorBox:`_errorBox_a0x57_12`,errorHint:`_errorHint_a0x57_13`,userRow:`_userRow_a0x57_16`,avatar:`_avatar_a0x57_27`,userLogin:`_userLogin_a0x57_29`,userName:`_userName_a0x57_30`,disconnectBtn:`_disconnectBtn_a0x57_32`,repoBar:`_repoBar_a0x57_43`,repoInput:`_repoInput_a0x57_49`,issuesBtn:`_issuesBtn_a0x57_61`,prsBtn:`_prsBtn_a0x57_72`,repoPills:`_repoPills_a0x57_83`,repoPill:`_repoPill_a0x57_83`,issueCount:`_issueCount_a0x57_106`,tabs:`_tabs_a0x57_112`,tab:`_tab_a0x57_112`,tabActive:`_tabActive_a0x57_131`,markRead:`_markRead_a0x57_137`,content:`_content_a0x57_148`,empty:`_empty_a0x57_150`,notifRow:`_notifRow_a0x57_152`,issueRow:`_issueRow_a0x57_152`,prRow:`_prRow_a0x57_152`,notifRepo:`_notifRepo_a0x57_166`,notifType:`_notifType_a0x57_167`,notifTitle:`_notifTitle_a0x57_168`,notifMeta:`_notifMeta_a0x57_169`,issueNum:`_issueNum_a0x57_171`,issueTitle:`_issueTitle_a0x57_172`,issueMeta:`_issueMeta_a0x57_173`,issueLabel:`_issueLabel_a0x57_174`,prNum:`_prNum_a0x57_176`,prTitle:`_prTitle_a0x57_177`,prAuthor:`_prAuthor_a0x57_178`,prDraft:`_prDraft_a0x57_179`,prMeta:`_prMeta_a0x57_180`};function qt(){let e=P(),[t,n]=(0,_.useState)(null),[r,i]=(0,_.useState)(!0),[a,o]=(0,_.useState)(``),[s,c]=(0,_.useState)(``),[l,u]=(0,_.useState)(`notifs`),d=(e=``)=>{i(!0),E(e?`/api/github?repo=${encodeURIComponent(e)}`:`/api/github`).then(e=>{n(e??{}),i(!1)}).catch(()=>i(!1))};(0,_.useEffect)(()=>{d()},[]);let f=()=>{let e=s.trim();o(e),d(e),u(`issues`)},p=()=>{let e=s.trim();o(e),d(e),u(`prs`)},m=()=>D(`/api/github/mark-read`,{}).then(()=>d(a)),h=()=>{confirm(`Remove GitHub connection? You can reconnect anytime.`)&&D(`/api/config`,{key:`github-token`,value:``}).then(()=>{n(null),i(!1)})};if(r)return(0,k.jsx)(`div`,{className:Y.loading,children:(0,k.jsx)(`div`,{className:`spinner`})});if(t?.error)return(0,k.jsxs)(`div`,{className:Y.errorBox,children:[(0,k.jsx)(`div`,{children:t.error}),(0,k.jsxs)(`div`,{className:Y.errorHint,children:[`Run: `,(0,k.jsx)(`code`,{children:`nha config set github-token YOUR_PAT`})]})]});let g=t?.user,v=t?.notifications??[],y=t?.issues??[],b=t?.prs??[];return(0,k.jsxs)(`div`,{className:Y.root,children:[g?.login&&(0,k.jsxs)(`div`,{className:Y.userRow,children:[g.avatar&&(0,k.jsx)(`img`,{src:g.avatar,className:Y.avatar,alt:g.login}),(0,k.jsxs)(`div`,{style:{flex:1},children:[(0,k.jsxs)(`div`,{className:Y.userLogin,children:[`@`,g.login]}),g.name&&(0,k.jsx)(`div`,{className:Y.userName,children:g.name})]}),(0,k.jsx)(`button`,{className:Y.disconnectBtn,onClick:h,children:`Disconnect`})]}),(0,k.jsxs)(`div`,{className:Y.repoBar,children:[(0,k.jsx)(`input`,{className:Y.repoInput,value:s,onChange:e=>c(e.target.value),placeholder:`owner/repo`,onKeyDown:e=>e.key===`Enter`&&f()}),(0,k.jsx)(`button`,{className:Y.issuesBtn,onClick:f,children:`Issues`}),(0,k.jsx)(`button`,{className:Y.prsBtn,onClick:p,children:`PRs`})]}),g?.repos&&g.repos.length>0&&(0,k.jsx)(`div`,{className:Y.repoPills,children:g.repos.slice(0,12).map(e=>(0,k.jsxs)(`button`,{className:Y.repoPill,onClick:()=>{c(e.full_name),o(e.full_name),d(e.full_name),u(`issues`)},title:e.description??``,children:[e.private?`🔒 `:``,e.full_name,e.open_issues?(0,k.jsx)(`span`,{className:Y.issueCount,children:e.open_issues}):null]},e.full_name))}),(0,k.jsxs)(`div`,{className:Y.tabs,children:[(0,k.jsxs)(`button`,{className:`${Y.tab} ${l===`notifs`?Y.tabActive:``}`,onClick:()=>u(`notifs`),children:[`Notifications `,v.length>0?`(${v.length})`:``]}),y.length>0&&(0,k.jsxs)(`button`,{className:`${Y.tab} ${l===`issues`?Y.tabActive:``}`,onClick:()=>u(`issues`),children:[`Issues (`,y.length,`)`]}),b.length>0&&(0,k.jsxs)(`button`,{className:`${Y.tab} ${l===`prs`?Y.tabActive:``}`,onClick:()=>u(`prs`),children:[`PRs (`,b.length,`)`]}),l===`notifs`&&v.length>0&&(0,k.jsx)(`button`,{className:Y.markRead,onClick:m,children:`Mark all read`})]}),(0,k.jsxs)(`div`,{className:Y.content,children:[l===`notifs`&&(v.length===0?(0,k.jsx)(`div`,{className:Y.empty,children:`No notifications`}):v.map((e,t)=>(0,k.jsxs)(`a`,{className:Y.notifRow,href:e.url,target:`_blank`,rel:`noreferrer`,children:[(0,k.jsx)(`span`,{className:Y.notifRepo,children:e.repo}),(0,k.jsxs)(`span`,{className:Y.notifType,children:[`[`,e.type,`]`]}),(0,k.jsx)(`div`,{className:Y.notifTitle,children:e.title}),(0,k.jsxs)(`div`,{className:Y.notifMeta,children:[e.reason,` · `,e.updated]})]},t))),l===`issues`&&(y.length===0?(0,k.jsxs)(`div`,{className:Y.empty,children:[e(`github.noIssues`),` for `,a]}):y.map((e,t)=>(0,k.jsxs)(`a`,{className:Y.issueRow,href:e.url,target:`_blank`,rel:`noreferrer`,children:[(0,k.jsxs)(`span`,{className:Y.issueNum,children:[`#`,e.number]}),(0,k.jsx)(`span`,{className:Y.issueTitle,children:e.title}),e.assignee&&(0,k.jsxs)(`span`,{className:Y.issueMeta,children:[`→ `,e.assignee]}),e.labels&&(0,k.jsxs)(`span`,{className:Y.issueLabel,children:[`[`,e.labels,`]`]}),(0,k.jsx)(`div`,{className:Y.issueMeta,children:e.updated})]},t))),l===`prs`&&(b.length===0?(0,k.jsxs)(`div`,{className:Y.empty,children:[`No PRs for `,a]}):b.map((e,t)=>(0,k.jsxs)(`a`,{className:Y.prRow,href:e.url,target:`_blank`,rel:`noreferrer`,children:[(0,k.jsxs)(`span`,{className:Y.prNum,children:[`#`,e.number]}),(0,k.jsx)(`span`,{className:Y.prTitle,children:e.title}),(0,k.jsxs)(`span`,{className:Y.prAuthor,children:[`by `,e.author]}),e.draft&&(0,k.jsx)(`span`,{className:Y.prDraft,children:`DRAFT`}),(0,k.jsx)(`div`,{className:Y.prMeta,children:e.updated})]},t)))]})]})}var Jt={loading:`_loading_1h5ss_1`,errorBox:`_errorBox_1h5ss_3`,errorHint:`_errorHint_1h5ss_4`,twoPane:`_twoPane_1h5ss_7`,sidebar:`_sidebar_1h5ss_13`,sidebarTitle:`_sidebarTitle_1h5ss_24`,workspace:`_workspace_1h5ss_36`,searchRow:`_searchRow_1h5ss_42`,searchInput:`_searchInput_1h5ss_50`,searchBtn:`_searchBtn_1h5ss_63`,channelItem:`_channelItem_1h5ss_73`,channelActive:`_channelActive_1h5ss_83`,pageTitle:`_pageTitle_1h5ss_89`,pageMeta:`_pageMeta_1h5ss_97`,disconnectBtn:`_disconnectBtn_1h5ss_99`,empty:`_empty_1h5ss_110`,messagePane:`_messagePane_1h5ss_112`,channelHeader:`_channelHeader_1h5ss_120`,emptyPane:`_emptyPane_1h5ss_129`,message:`_message_1h5ss_112`,msgUser:`_msgUser_1h5ss_146`,msgText:`_msgText_1h5ss_147`,msgTs:`_msgTs_1h5ss_148`,openLink:`_openLink_1h5ss_150`,pageBody:`_pageBody_1h5ss_160`};function Yt(){let e=P(),[t,n]=(0,_.useState)(null),[r,i]=(0,_.useState)(!0),[a,o]=(0,_.useState)(null),[s,c]=(0,_.useState)([]),l=()=>{i(!0),E(`/api/slack/channels`).then(e=>{n(e??{}),i(!1)}).catch(()=>i(!1))},u=e=>{o(e),E(`/api/slack/messages?channel=${e.id}`).then(e=>c(e?.messages??[]))};if((0,_.useEffect)(()=>{l()},[]),r)return(0,k.jsxs)(`div`,{className:Jt.loading,children:[(0,k.jsx)(`div`,{className:`spinner`}),e(`common.loading`)]});if(t?.error)return(0,k.jsxs)(`div`,{className:Jt.errorBox,children:[(0,k.jsx)(`div`,{children:t.error}),(0,k.jsxs)(`div`,{className:Jt.errorHint,children:[`Run: `,(0,k.jsx)(`code`,{children:`nha config set slack-token xoxb-YOUR-TOKEN`})]})]});let d=t?.channels??[];return(0,k.jsxs)(`div`,{className:Jt.twoPane,children:[(0,k.jsxs)(`div`,{className:Jt.sidebar,children:[(0,k.jsxs)(`div`,{className:Jt.sidebarTitle,children:[(0,k.jsx)(`span`,{children:`💬 Slack`}),t?.workspace&&(0,k.jsx)(`span`,{className:Jt.workspace,children:t.workspace})]}),d.length===0&&(0,k.jsx)(`div`,{className:Jt.empty,children:`No channels`}),d.map(e=>(0,k.jsxs)(`div`,{className:`${Jt.channelItem} ${a?.id===e.id?Jt.channelActive:``}`,onClick:()=>u(e),children:[`# `,e.name]},e.id)),(0,k.jsx)(`button`,{className:Jt.disconnectBtn,onClick:()=>D(`/api/config`,{key:`slack-token`,value:``}).then(l),children:`Disconnect`})]}),(0,k.jsx)(`div`,{className:Jt.messagePane,children:a?(0,k.jsxs)(k.Fragment,{children:[(0,k.jsxs)(`div`,{className:Jt.channelHeader,children:[`#`,a.name]}),s.length===0&&(0,k.jsx)(`div`,{className:Jt.empty,children:`No messages`}),s.map((e,t)=>(0,k.jsxs)(`div`,{className:Jt.message,children:[(0,k.jsx)(`span`,{className:Jt.msgUser,children:e.username||e.user||`Unknown`}),(0,k.jsx)(`span`,{className:Jt.msgText,children:e.text}),(0,k.jsx)(`span`,{className:Jt.msgTs,children:new Date(parseFloat(e.ts)*1e3).toLocaleTimeString()})]},t))]}):(0,k.jsx)(`div`,{className:Jt.emptyPane,children:`Select a channel`})})]})}function Xt(){let e=P(),[t,n]=(0,_.useState)(null),[r,i]=(0,_.useState)(!0),[a,o]=(0,_.useState)(null),[s,c]=(0,_.useState)(``),[l,u]=(0,_.useState)(``),d=(e=``)=>{i(!0),E(e?`/api/notion/search?q=${encodeURIComponent(e)}`:`/api/notion`).then(e=>{n(e??{}),i(!1)}).catch(()=>i(!1))},f=e=>{o(e),E(`/api/notion/page?id=${encodeURIComponent(e.id)}`).then(e=>c(e?.content??``))};(0,_.useEffect)(()=>{d()},[]);let p=()=>d(l);if(r)return(0,k.jsxs)(`div`,{className:Jt.loading,children:[(0,k.jsx)(`div`,{className:`spinner`}),e(`common.loading`)]});if(t?.error)return(0,k.jsxs)(`div`,{className:Jt.errorBox,children:[(0,k.jsx)(`div`,{children:t.error}),(0,k.jsxs)(`div`,{className:Jt.errorHint,children:[`Run: `,(0,k.jsx)(`code`,{children:`nha config set notion-token secret_YOUR_TOKEN`})]})]});let m=t?.pages??[];return(0,k.jsxs)(`div`,{className:Jt.twoPane,children:[(0,k.jsxs)(`div`,{className:Jt.sidebar,children:[(0,k.jsx)(`div`,{className:Jt.sidebarTitle,children:`📋 Notion`}),(0,k.jsxs)(`div`,{className:Jt.searchRow,children:[(0,k.jsx)(`input`,{className:Jt.searchInput,value:l,onChange:e=>u(e.target.value),placeholder:`Search pages…`,onKeyDown:e=>e.key===`Enter`&&p()}),(0,k.jsx)(`button`,{className:Jt.searchBtn,onClick:p,children:`Go`})]}),m.length===0&&(0,k.jsx)(`div`,{className:Jt.empty,children:`No pages found`}),m.map(e=>(0,k.jsxs)(`div`,{className:`${Jt.channelItem} ${a?.id===e.id?Jt.channelActive:``}`,onClick:()=>f(e),children:[(0,k.jsx)(`div`,{className:Jt.pageTitle,children:e.title||`Untitled`}),e.last_edited&&(0,k.jsx)(`div`,{className:Jt.pageMeta,children:e.last_edited.slice(0,10)})]},e.id)),(0,k.jsx)(`button`,{className:Jt.disconnectBtn,onClick:()=>D(`/api/config`,{key:`notion-token`,value:``}).then(()=>d()),children:`Disconnect`})]}),(0,k.jsx)(`div`,{className:Jt.messagePane,children:a?(0,k.jsxs)(k.Fragment,{children:[(0,k.jsx)(`div`,{className:Jt.channelHeader,children:a.title}),a.url&&(0,k.jsx)(`a`,{className:Jt.openLink,href:a.url,target:`_blank`,rel:`noreferrer`,children:`Open in Notion ↗`}),(0,k.jsx)(`div`,{className:Jt.pageBody,dangerouslySetInnerHTML:{__html:fe(s||`Loading…`)}})]}):(0,k.jsx)(`div`,{className:Jt.emptyPane,children:`Select a page`})})]})}var X={root:`_root_1l3ll_1`,sidebar:`_sidebar_1l3ll_8`,sidebarHeader:`_sidebarHeader_1l3ll_18`,sidebarTitle:`_sidebarTitle_1l3ll_19`,sidebarBtns:`_sidebarBtns_1l3ll_21`,createBtn:`_createBtn_1l3ll_22`,joinBtn:`_joinBtn_1l3ll_23`,noChannels:`_noChannels_1l3ll_25`,channelItem:`_channelItem_1l3ll_27`,channelActive:`_channelActive_1l3ll_29`,channelName:`_channelName_1l3ll_30`,channelMeta:`_channelMeta_1l3ll_31`,channelCode:`_channelCode_1l3ll_32`,channelDel:`_channelDel_1l3ll_34`,main:`_main_1l3ll_38`,chatHeader:`_chatHeader_1l3ll_41`,chatChannelName:`_chatChannelName_1l3ll_50`,chatChannelId:`_chatChannelId_1l3ll_51`,statusDot:`_statusDot_1l3ll_52`,connected:`_connected_1l3ll_53`,disconnected:`_disconnected_1l3ll_54`,statusText:`_statusText_1l3ll_55`,messages:`_messages_1l3ll_58`,emptyMsgs:`_emptyMsgs_1l3ll_66`,msg:`_msg_1l3ll_68`,msgSelf:`_msgSelf_1l3ll_69`,msgOther:`_msgOther_1l3ll_70`,msgSender:`_msgSender_1l3ll_71`,msgContent:`_msgContent_1l3ll_72`,msgTime:`_msgTime_1l3ll_82`,inputRow:`_inputRow_1l3ll_85`,textInput:`_textInput_1l3ll_86`,sendBtn:`_sendBtn_1l3ll_88`,welcome:`_welcome_1l3ll_92`,welcomeIcon:`_welcomeIcon_1l3ll_103`,welcomeTitle:`_welcomeTitle_1l3ll_104`,welcomeSub:`_welcomeSub_1l3ll_105`,welcomeBox:`_welcomeBox_1l3ll_106`,welcomeBoxTitle:`_welcomeBoxTitle_1l3ll_107`,welcomeStep:`_welcomeStep_1l3ll_108`,welcomeHint:`_welcomeHint_1l3ll_109`,cliCmd:`_cliCmd_1l3ll_110`};function Zt(e){return e.content||e.plaintext||e.message||``}function Qt(e){return e.senderName||e.senderFingerprint?.slice(0,8)||e.sender||`unknown`}function $t(){let e=P(),[t,n]=(0,_.useState)([]),[r,i]=(0,_.useState)(null),[a,o]=(0,_.useState)([]),[s,c]=(0,_.useState)(``),[l,u]=(0,_.useState)(!1),[d]=(0,_.useState)(()=>`nha-ui-${Math.random().toString(36).slice(2,8)}`),f=(0,_.useRef)(null),p=(0,_.useRef)(null);(0,_.useEffect)(()=>{E(`/api/collab/channels`).then(e=>{n(e?.channels??[])}).catch(()=>{})},[]),(0,_.useEffect)(()=>{if(r)return m(r),h(r),()=>{f.current?.close(),u(!1)}},[r]);let m=e=>{E(`/api/collab/messages?channelId=${e}`).then(e=>{e?.messages&&(o(e.messages),setTimeout(()=>{p.current&&(p.current.scrollTop=p.current.scrollHeight)},50))}).catch(()=>{})},h=e=>{f.current?.close();let t=window.location.protocol===`https:`?`wss:`:`ws:`,n=window.location.port===`3030`||window.location.port===`3031`?`3020`:window.location.port||`3020`,r=`${t}//${window.location.hostname}:${n}/ws/alexandria?channel=${e}&agentId=${encodeURIComponent(d)}`,i=new WebSocket(r);f.current=i,i.onopen=()=>u(!0),i.onclose=()=>u(!1),i.onmessage=e=>{try{let t=JSON.parse(e.data);if(!t)return;o(e=>[...e,{...t,id:t.id||Date.now().toString(),type:`message`}]),p.current&&(p.current.scrollTop=p.current.scrollHeight)}catch{}}},g=async()=>{let e=prompt(`Channel name:`);if(!e)return;let t=await D(`/api/collab/create`,{name:e}).catch(()=>null);if(!t||t.error){alert(t?.error||`Error creating channel`);return}let r=t.id;await D(`/api/collab/channels`,{id:r,name:e,role:`creator`}).catch(()=>{});let a={id:r,name:e,role:`creator`};n(e=>[...e,a]),i(r),prompt(`Share this invite code with collaborators:`,r)},v=async()=>{let e=prompt(`Invite code:`);if(!e)return;let t=await D(`/api/collab/join`,{channelId:e}).catch(()=>null);if(!t||t.error){alert(t?.error||`Error joining channel`);return}let r=t.name||e.slice(0,8);await D(`/api/collab/channels`,{id:e,name:r,role:`member`}).catch(()=>{}),n(t=>[...t,{id:e,name:r,role:`member`}]),i(e)},y=async e=>{confirm(`Delete this channel? Messages will be lost.`)&&(D(`/api/collab/delete`,{channelId:e}).catch(()=>{}),n(t=>t.filter(t=>t.id!==e)),r===e&&(i(null),o([]),f.current?.close(),u(!1)))},b=async()=>{let e=s.trim();if(!e||!r)return;c(``);let t=await D(`/api/collab/send`,{channelId:r,message:e}).catch(()=>null);t?.error&&alert(t.error),l||m(r)},x=e=>{navigator.clipboard.writeText(e).catch(()=>{})};return(0,k.jsxs)(`div`,{className:X.root,children:[(0,k.jsxs)(`div`,{className:X.sidebar,children:[(0,k.jsx)(`div`,{className:X.sidebarHeader,children:(0,k.jsx)(`div`,{className:X.sidebarTitle,children:`Alexandria`})}),(0,k.jsxs)(`div`,{className:X.sidebarBtns,children:[(0,k.jsx)(`button`,{className:X.createBtn,onClick:g,children:`+ Create`}),(0,k.jsx)(`button`,{className:X.joinBtn,onClick:v,children:`Join`})]}),t.length===0?(0,k.jsxs)(`div`,{className:X.noChannels,children:[e(`collab.noChannels`),` yet`]}):t.map(e=>(0,k.jsxs)(`div`,{className:`${X.channelItem} ${r===e.id?X.channelActive:``}`,onClick:()=>i(e.id),children:[(0,k.jsx)(`div`,{className:X.channelName,children:e.name}),(0,k.jsxs)(`div`,{className:X.channelMeta,children:[(0,k.jsxs)(`span`,{className:X.channelCode,onClick:t=>{t.stopPropagation(),x(e.id)},title:`Click to copy invite code`,children:[e.id.slice(0,8),`…`]}),(0,k.jsx)(`button`,{className:X.channelDel,onClick:t=>{t.stopPropagation(),y(e.id)},children:`del`})]})]},e.id))]}),(0,k.jsx)(`div`,{className:X.main,children:r?(0,k.jsxs)(k.Fragment,{children:[(0,k.jsxs)(`div`,{className:X.chatHeader,children:[(0,k.jsx)(`div`,{className:X.chatChannelName,children:t.find(e=>e.id===r)?.name??r.slice(0,12)}),(0,k.jsx)(`div`,{className:X.chatChannelId,children:r}),(0,k.jsx)(`div`,{className:`${X.statusDot} ${l?X.connected:X.disconnected}`}),(0,k.jsx)(`span`,{className:X.statusText,children:l?`Live`:`HTTP`})]}),(0,k.jsxs)(`div`,{className:X.messages,ref:p,children:[a.length===0&&(0,k.jsx)(`div`,{className:X.emptyMsgs,children:`No messages yet`}),a.map((e,t)=>{let n=Qt(e),r=Zt(e),i=n===d;return(0,k.jsxs)(`div`,{className:`${X.msg} ${i?X.msgSelf:X.msgOther}`,children:[!i&&(0,k.jsx)(`div`,{className:X.msgSender,children:n}),(0,k.jsx)(`div`,{className:X.msgContent,children:r}),(0,k.jsx)(`div`,{className:X.msgTime,children:new Date(e.timestamp).toLocaleTimeString()})]},e.id||t)})]}),(0,k.jsxs)(`div`,{className:X.inputRow,children:[(0,k.jsx)(`input`,{className:X.textInput,value:s,onChange:e=>c(e.target.value),placeholder:`Send an encrypted message…`,onKeyDown:e=>e.key===`Enter`&&!e.shiftKey&&b()}),(0,k.jsx)(`button`,{className:X.sendBtn,onClick:b,disabled:!s.trim(),children:e(`collab.send`)})]})]}):(0,k.jsxs)(`div`,{className:X.welcome,children:[(0,k.jsx)(`div`,{className:X.welcomeIcon,children:`🔐`}),(0,k.jsx)(`div`,{className:X.welcomeTitle,children:`Alexandria`}),(0,k.jsx)(`div`,{className:X.welcomeSub,children:`E2E encrypted messaging for AI agents and teams`}),(0,k.jsxs)(`div`,{className:X.welcomeBox,children:[(0,k.jsx)(`div`,{className:X.welcomeBoxTitle,children:`HOW TO USE`}),(0,k.jsxs)(`div`,{className:X.welcomeStep,children:[(0,k.jsx)(`strong`,{children:`1. Create a channel`}),` — Click [+ Create] in the sidebar. Give it a name.`]}),(0,k.jsx)(`div`,{className:X.welcomeHint,children:`You get an invite code. Share it with your team or another AI session.`}),(0,k.jsxs)(`div`,{className:X.welcomeStep,children:[(0,k.jsx)(`strong`,{children:`2. Others join`}),` — They click [Join] and paste the invite code.`]}),(0,k.jsx)(`div`,{className:X.welcomeHint,children:`Works from this web UI, the Android app, or the CLI.`}),(0,k.jsxs)(`div`,{className:X.welcomeStep,children:[(0,k.jsx)(`strong`,{children:`3. Chat encrypted`}),` — All messages are E2E encrypted. The server sees only ciphertext.`]})]}),(0,k.jsxs)(`div`,{className:X.welcomeBox,children:[(0,k.jsx)(`div`,{className:X.welcomeBoxTitle,children:`FROM CLI (same channels)`}),(0,k.jsx)(`div`,{className:X.cliCmd,children:`nha collab create "Project X"`}),(0,k.jsx)(`div`,{className:X.cliCmd,children:`nha collab join <invite-code>`}),(0,k.jsx)(`div`,{className:X.cliCmd,children:`nha collab send "Hello from CLI"`}),(0,k.jsx)(`div`,{className:X.cliCmd,children:`nha collab read`})]})]})})]})}var Z={root:`_root_85zy7_2`,header:`_header_85zy7_10`,title:`_title_85zy7_21`,subtitle:`_subtitle_85zy7_28`,headerTabs:`_headerTabs_85zy7_34`,tabBtn:`_tabBtn_85zy7_40`,tabActive:`_tabActive_85zy7_51`,body:`_body_85zy7_58`,editor:`_editor_85zy7_67`,examples:`_examples_85zy7_75`,sectionLabel:`_sectionLabel_85zy7_81`,examplePills:`_examplePills_85zy7_89`,examplePill:`_examplePill_85zy7_89`,editorCols:`_editorCols_85zy7_109`,leftSidebar:`_leftSidebar_85zy7_119`,panel:`_panel_85zy7_128`,panelHeader:`_panelHeader_85zy7_135`,panelTitle:`_panelTitle_85zy7_142`,addBtn:`_addBtn_85zy7_149`,blockLabel:`_blockLabel_85zy7_160`,blockCheck:`_blockCheck_85zy7_170`,authField:`_authField_85zy7_173`,authFieldInput:`_authFieldInput_85zy7_183`,authFieldSelect:`_authFieldSelect_85zy7_193`,authFieldReq:`_authFieldReq_85zy7_204`,removeFieldBtn:`_removeFieldBtn_85zy7_205`,skillsList:`_skillsList_85zy7_208`,skillRow:`_skillRow_85zy7_210`,skillIcon:`_skillIcon_85zy7_218`,skillName:`_skillName_85zy7_220`,skillBadge:`_skillBadge_85zy7_229`,skillBadge_skill:`_skillBadge_skill_85zy7_237`,skillBadge_memory:`_skillBadge_memory_85zy7_238`,skillBadge_provider:`_skillBadge_provider_85zy7_239`,skillBadge_log:`_skillBadge_log_85zy7_240`,skillEmpty:`_skillEmpty_85zy7_242`,skillBtn:`_skillBtn_85zy7_244`,skillsEmpty:`_skillsEmpty_85zy7_246`,snapshotRow:`_snapshotRow_85zy7_249`,snapshotTs:`_snapshotTs_85zy7_258`,snapshotCount:`_snapshotCount_85zy7_259`,snapshotBtn:`_snapshotBtn_85zy7_260`,genStatus:`_genStatus_85zy7_263`,repairStatus:`_repairStatus_85zy7_265`,repairStatusTitle:`_repairStatusTitle_85zy7_266`,repairStatusProg:`_repairStatusProg_85zy7_267`,repairStatusFile:`_repairStatusFile_85zy7_268`,actionRow:`_actionRow_85zy7_271`,actionBtn:`_actionBtn_85zy7_273`,actionBtnIcon:`_actionBtnIcon_85zy7_275`,actionBtnActive:`_actionBtnActive_85zy7_276`,repairBtn:`_repairBtn_85zy7_278`,sandboxBtn:`_sandboxBtn_85zy7_280`,statsBar:`_statsBar_85zy7_282`,rightPanel:`_rightPanel_85zy7_285`,rightTabBar:`_rightTabBar_85zy7_296`,rightTab:`_rightTab_85zy7_296`,rightTabActive:`_rightTabActive_85zy7_313`,repairBar:`_repairBar_85zy7_316`,repairBarRow:`_repairBarRow_85zy7_326`,repairBarIcon:`_repairBarIcon_85zy7_327`,repairBarLabel:`_repairBarLabel_85zy7_328`,repairBarFile:`_repairBarFile_85zy7_329`,repairBarCounter:`_repairBarCounter_85zy7_330`,repairBarTime:`_repairBarTime_85zy7_331`,genBar:`_genBar_85zy7_333`,genBarRow:`_genBarRow_85zy7_343`,genBarRobot:`_genBarRobot_85zy7_344`,robotBob:`_robotBob_85zy7_1`,genBarLabel:`_genBarLabel_85zy7_345`,genBarFile:`_genBarFile_85zy7_346`,genBarCounter:`_genBarCounter_85zy7_347`,genBarTime:`_genBarTime_85zy7_348`,progressTrack:`_progressTrack_85zy7_350`,repairProgress:`_repairProgress_85zy7_351`,genProgress:`_genProgress_85zy7_352`,genDots:`_genDots_85zy7_355`,dot:`_dot_85zy7_356`,dot1:`_dot1_85zy7_357`,dotBounce:`_dotBounce_85zy7_1`,dot2:`_dot2_85zy7_358`,dot3:`_dot3_85zy7_359`,stopBtn:`_stopBtn_85zy7_362`,codeArea:`_codeArea_85zy7_365`,sandboxWrap:`_sandboxWrap_85zy7_366`,sandboxFrame:`_sandboxFrame_85zy7_367`,sandboxEmpty:`_sandboxEmpty_85zy7_368`,sandboxStartBtn:`_sandboxStartBtn_85zy7_369`,codeLayout:`_codeLayout_85zy7_372`,codeRow:`_codeRow_85zy7_381`,ideTabBar:`_ideTabBar_85zy7_389`,ideTab:`_ideTab_85zy7_389`,ideTabActive:`_ideTabActive_85zy7_421`,ideTabError:`_ideTabError_85zy7_426`,ideTabPending:`_ideTabPending_85zy7_427`,ideTabIcon:`_ideTabIcon_85zy7_428`,ideTabName:`_ideTabName_85zy7_429`,ideTabDot:`_ideTabDot_85zy7_430`,codeEditorWrap:`_codeEditorWrap_85zy7_438`,editToggleBtn:`_editToggleBtn_85zy7_449`,editToggleBtnActive:`_editToggleBtnActive_85zy7_460`,codeEditor:`_codeEditor_85zy7_438`,genCursor:`_genCursor_85zy7_482`,cursorBlink:`_cursorBlink_85zy7_1`,diffOverlay:`_diffOverlay_85zy7_491`,diffOverlayHeader:`_diffOverlayHeader_85zy7_500`,diffOverlayActions:`_diffOverlayActions_85zy7_511`,diffAcceptBtn:`_diffAcceptBtn_85zy7_512`,diffRejectBtn:`_diffRejectBtn_85zy7_513`,diffOverlayBody:`_diffOverlayBody_85zy7_514`,diffSame:`_diffSame_85zy7_515`,diffRem:`_diffRem_85zy7_516`,diffAdd:`_diffAdd_85zy7_517`,noFiles:`_noFiles_85zy7_519`,noFilesHero:`_noFilesHero_85zy7_529`,noFilesIcon:`_noFilesIcon_85zy7_536`,noFilesTitle:`_noFilesTitle_85zy7_538`,noFilesTagline:`_noFilesTagline_85zy7_545`,noFilesSteps:`_noFilesSteps_85zy7_550`,noFilesStep:`_noFilesStep_85zy7_550`,noFilesStepNum:`_noFilesStepNum_85zy7_567`,noFilesExamplesHint:`_noFilesExamplesHint_85zy7_581`,noFilesExampleBtn:`_noFilesExampleBtn_85zy7_591`,codeViewer:`_codeViewer_85zy7_605`,codeHeader:`_codeHeader_85zy7_613`,codeFileIcon:`_codeFileIcon_85zy7_626`,codeFileName:`_codeFileName_85zy7_627`,codeFileMeta:`_codeFileMeta_85zy7_628`,fileError:`_fileError_85zy7_630`,fileSyntaxError:`_fileSyntaxError_85zy7_631`,filePending:`_filePending_85zy7_632`,code:`_code_85zy7_365`,codeError:`_codeError_85zy7_647`,codeSyntaxError:`_codeSyntaxError_85zy7_648`,fileSidebar:`_fileSidebar_85zy7_651`,fileSidebarHeader:`_fileSidebarHeader_85zy7_660`,fileTab:`_fileTab_85zy7_670`,fileTabActive:`_fileTabActive_85zy7_686`,fileTabError:`_fileTabError_85zy7_687`,fileTabRow:`_fileTabRow_85zy7_689`,fileTabIcon:`_fileTabIcon_85zy7_690`,fileTabName:`_fileTabName_85zy7_691`,fileTabDir:`_fileTabDir_85zy7_692`,fileTabMeta:`_fileTabMeta_85zy7_693`,projectsList:`_projectsList_85zy7_696`,emptyProjects:`_emptyProjects_85zy7_698`,emptyIcon:`_emptyIcon_85zy7_699`,emptyHint:`_emptyHint_85zy7_700`,projectCard:`_projectCard_85zy7_702`,projectInfo:`_projectInfo_85zy7_703`,projectName:`_projectName_85zy7_704`,projectDesc:`_projectDesc_85zy7_705`,projectMeta:`_projectMeta_85zy7_706`,openBtn:`_openBtn_85zy7_707`,deleteBtn:`_deleteBtn_85zy7_708`,planBanner:`_planBanner_85zy7_711`,planTitle:`_planTitle_85zy7_720`,planText:`_planText_85zy7_721`,planActions:`_planActions_85zy7_722`,planApprove:`_planApprove_85zy7_723`,planReject:`_planReject_85zy7_724`,grepPanel:`_grepPanel_85zy7_727`,grepRow:`_grepRow_85zy7_736`,grepInput:`_grepInput_85zy7_737`,grepBtn:`_grepBtn_85zy7_739`,grepClose:`_grepClose_85zy7_740`,grepCount:`_grepCount_85zy7_741`,grepResults:`_grepResults_85zy7_742`,grepEmpty:`_grepEmpty_85zy7_743`,grepMatch:`_grepMatch_85zy7_744`,grepMatchFile:`_grepMatchFile_85zy7_746`,grepMatchLine:`_grepMatchLine_85zy7_747`,diffPanel:`_diffPanel_85zy7_750`,diffHeader:`_diffHeader_85zy7_759`,diffClose:`_diffClose_85zy7_760`,diffFile:`_diffFile_85zy7_761`,diffSummary:`_diffSummary_85zy7_762`,diffArrow:`_diffArrow_85zy7_763`,diffFileName:`_diffFileName_85zy7_764`,diffAdded:`_diffAdded_85zy7_765`,diffRemoved:`_diffRemoved_85zy7_766`,diffContent:`_diffContent_85zy7_767`,diffInline:`_diffInline_85zy7_770`,diffInlineHeader:`_diffInlineHeader_85zy7_771`,diffRemLine:`_diffRemLine_85zy7_772`,diffAddLine:`_diffAddLine_85zy7_773`,chatPanel:`_chatPanel_85zy7_776`,chatMessages:`_chatMessages_85zy7_785`,chatWelcome:`_chatWelcome_85zy7_787`,chatUser:`_chatUser_85zy7_789`,chatUserBubble:`_chatUserBubble_85zy7_790`,chatAttachPreviews:`_chatAttachPreviews_85zy7_791`,chatAttachBadge:`_chatAttachBadge_85zy7_792`,chatSystem:`_chatSystem_85zy7_794`,chatSystemBubble:`_chatSystemBubble_85zy7_795`,chatSyntaxErr:`_chatSyntaxErr_85zy7_796`,chatAgent:`_chatAgent_85zy7_798`,chatAgentCard:`_chatAgentCard_85zy7_799`,chatAgentHeader:`_chatAgentHeader_85zy7_800`,chatAgentRobot:`_chatAgentRobot_85zy7_801`,chatAgentRobotAnim:`_chatAgentRobotAnim_85zy7_802`,chatAgentLabel:`_chatAgentLabel_85zy7_803`,chatRunningDots:`_chatRunningDots_85zy7_804`,chatAgentText:`_chatAgentText_85zy7_805`,chatToolBadges:`_chatToolBadges_85zy7_806`,toolBadge:`_toolBadge_85zy7_807`,toolBadgeOk:`_toolBadgeOk_85zy7_808`,toolBadgeErr:`_toolBadgeErr_85zy7_809`,cursor:`_cursor_85zy7_811`,blink:`_blink_85zy7_1`,attachPreviews:`_attachPreviews_85zy7_814`,attachBadge:`_attachBadge_85zy7_815`,removeAttachBtn:`_removeAttachBtn_85zy7_816`,projNameRow:`_projNameRow_85zy7_819`,projNameLabel:`_projNameLabel_85zy7_820`,projNameInput:`_projNameInput_85zy7_821`,projActiveRow:`_projActiveRow_85zy7_822`,projActiveName:`_projActiveName_85zy7_823`,chatInputRow:`_chatInputRow_85zy7_826`,attachLabel:`_attachLabel_85zy7_827`,chatTextarea:`_chatTextarea_85zy7_828`,chatSendCol:`_chatSendCol_85zy7_831`,chatSendBtn:`_chatSendBtn_85zy7_832`,chatStopBtn:`_chatStopBtn_85zy7_834`,modalOverlay:`_modalOverlay_85zy7_837`,modal:`_modal_85zy7_837`,modalHeader:`_modalHeader_85zy7_859`,modalTitle:`_modalTitle_85zy7_860`,modalClose:`_modalClose_85zy7_861`,modalBody:`_modalBody_85zy7_863`,modalRow:`_modalRow_85zy7_865`,modalField:`_modalField_85zy7_866`,modalLabel:`_modalLabel_85zy7_867`,modalLabelRow:`_modalLabelRow_85zy7_868`,modalSelect:`_modalSelect_85zy7_870`,modalInput:`_modalInput_85zy7_871`,modalHint:`_modalHint_85zy7_874`,modalAiBox:`_modalAiBox_85zy7_876`,modalAiRow:`_modalAiRow_85zy7_877`,modalAiDesc:`_modalAiDesc_85zy7_878`,modalAiBtn:`_modalAiBtn_85zy7_879`,modalContentArea:`_modalContentArea_85zy7_882`,logView:`_logView_85zy7_885`,modalFooter:`_modalFooter_85zy7_887`,modalCancelBtn:`_modalCancelBtn_85zy7_888`,modalSaveBtn:`_modalSaveBtn_85zy7_889`},en=[{name:`MySaaS`,desc:`SaaS product landing page. Hero: large headline, subheadline, two CTA buttons (Start free trial / Watch demo), animated gradient background. Features section: 3-column grid with icon, title, description for 6 features. Pricing section: 3 cards (Free / Pro $29/mo / Enterprise). Testimonials: 3 customer quotes. FAQ accordion: 5 questions. Footer with links and social icons. Sticky nav.`},{name:`MyShop`,desc:`E-commerce storefront homepage. Nav with logo, search bar, cart badge, hamburger mobile menu. Hero banner. Category strip: 6 cards. Featured products grid: 8 cards with rating, price, Add to Cart, wishlist. Promo banner. Newsletter signup. Responsive.`},{name:`MyBlog`,desc:`Blog platform homepage. Nav with category links. Hero: featured article card. Article grid: 6 cards. Sidebar: recent posts, tags cloud, newsletter widget. Pagination. Author bio section. Minimal footer.`},{name:`MyPortfolio`,desc:`Developer portfolio. Nav with scroll hide/show. Hero: typewriter role subtitle, CTA buttons. Work section: 6 project cards. Skills grouped by category with bars. About: timeline of milestones. Contact form. Scroll entrance animations via Intersection Observer.`},{name:`MyRestaurant`,desc:`Restaurant website. Nav: logo center, transparent→solid on scroll. Hero: full-viewport with overlay. Menu preview: tabbed (Starters/Mains/Desserts/Drinks). Reservation form. Gallery 3x3 mosaic. Chef section. Testimonials horizontal scroll.`},{name:`MyJobBoard`,desc:`Job board homepage. Hero search widget. Stats strip. Featured jobs list: 8 cards with company, location badge, salary, Quick Apply. Filter sidebar. Top companies section. Category cards. Newsletter.`}],tn=[{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:`✉️`}],nn={js:`📄`,ts:`📄`,css:`🎨`,html:`🌐`,json:`{`,md:`📑`,sql:`🗂`,env:`🔐`,conf:`⚙`,lock:`🔒`};function rn(e){return nn[e.split(`.`).pop()?.toLowerCase()??``]??`📄`}function an(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 on(e){return e===`memory`?`🧠`:e===`provider`?`🤖`:e===`log`?`📄`:`📋`}function sn(){let e=P(),[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)(!1),[w,ee]=(0,_.useState)(!1),[te,ne]=(0,_.useState)(0),[T,re]=(0,_.useState)(0),[ie,O]=(0,_.useState)(``),[ae,A]=(0,_.useState)({fi:0,total:0,name:``}),[j,oe]=(0,_.useState)(null),[se,M]=(0,_.useState)([]),[ce,N]=(0,_.useState)(``),[F,le]=(0,_.useState)(!1),[ue,de]=(0,_.useState)([]),[fe,I]=(0,_.useState)(null),[pe,me]=(0,_.useState)([]),[he,ge]=(0,_.useState)(!1),[L,_e]=(0,_.useState)(null),[ve,ye]=(0,_.useState)([]),[R,z]=(0,_.useState)(!1),[be,xe]=(0,_.useState)(``),[Se,Ce]=(0,_.useState)([]),[we,Te]=(0,_.useState)([]),[Ee,De]=(0,_.useState)([]),[Oe,ke]=(0,_.useState)(null),[B,Ae]=(0,_.useState)(`0s`),[je,Me]=(0,_.useState)(`0s`),Ne=(0,_.useRef)(0),Pe=(0,_.useRef)(0),Fe=(0,_.useRef)(null),Ie=(0,_.useRef)(null),Le=(0,_.useRef)(null),Re=(0,_.useRef)(null),ze=(0,_.useRef)(null),Be=(0,_.useRef)(null);function Ve(e){let t=Math.floor((Date.now()-e)/1e3),n=Math.floor(t/60);return(n>0?`${n}m `:``)+`${t%60}s`}(0,_.useEffect)(()=>(S||w?Fe.current=setInterval(()=>{S&&Ae(Ve(Ne.current)),w&&Me(Ve(Pe.current))},1e3):Fe.current&&=(clearInterval(Fe.current),null),()=>{Fe.current&&clearInterval(Fe.current)}),[S,w]);function He(){Le.current&&(Le.current.scrollTop=Le.current.scrollHeight)}(0,_.useEffect)(()=>{He()},[se]),(0,_.useEffect)(()=>{a&&p.length>0&&!he&&(ge(!0),E(`/api/studio/webcraft/skills/${encodeURIComponent(a)}`).then(e=>{e?.skills&&me(e.skills)}).catch(()=>{}))},[a,p.length,he]);async function Ue(e,t){if(S||!e||e.length<5)return;C(!0),m([]),g(0),A({fi:0,total:0,name:``}),Ne.current=Date.now(),Ae(`0s`),Ie.current=new AbortController;let n=Date.now();try{let r=await fetch(`/api/studio/webcraft/generate`,{method:`POST`,headers:{"Content-Type":`application/json`},signal:Ie.current.signal,body:JSON.stringify({projectName:t,description:e,blocks:l,authFields:d})});if(!r.ok||!r.body){C(!1);return}let i=r.body.getReader(),a=new TextDecoder,o=``,s=[];for(;;){let{done:e,value:t}=await i.read();if(e)break;o+=a.decode(t,{stream:!0});let r=o.split(`
530
+ Be concise. Highlight what each agent contributed uniquely. Give your own synthesis verdict at the end.`},e=>{i+=e,g(i)})}catch{}finally{y(!1)}},pe=e=>{let t=window.SpeechRecognition??window.webkitSpeechRecognition;if(!t){alert(`Speech recognition not supported.`);return}let n=T.current.get(e);if(l.find(t=>t.agent.id===e)?.voiceActive&&n){n.stop(),F(e,{voiceActive:!1});return}let r=new t;T.current.set(e,r),r.lang=`it-IT`,r.continuous=!1,r.interimResults=!1,r.onresult=t=>{let n=t.results[0][0].transcript;F(e,{input:(l.find(t=>t.agent.id===e)?.input??``)+(l.find(t=>t.agent.id===e)?.input?` `:``)+n})},r.onend=()=>F(e,{voiceActive:!1}),r.onerror=()=>F(e,{voiceActive:!1}),r.start(),F(e,{voiceActive:!0})},me=(e,t)=>{if(!t)return;let n=t.name.toLowerCase().endsWith(`.pdf`)||t.type===`application/pdf`,r=new FileReader;n?(r.onload=n=>{let r=(n.target?.result).split(`,`)[1];F(e,{attachedFile:{name:t.name,size:t.size,base64:r,mimeType:`application/pdf`,isPDF:!0},attachedImage:null})},r.readAsDataURL(t)):(r.onload=n=>{F(e,{attachedFile:{name:t.name,size:t.size,content:n.target?.result},attachedImage:null})},r.readAsText(t))},he=(e,t)=>{if(!t)return;let n=new FileReader;n.onload=n=>{let r=(n.target?.result).split(`,`)[1];F(e,{attachedImage:{name:t.name,size:t.size,base64:r,mimeType:t.type||`image/jpeg`},attachedFile:null})},n.readAsDataURL(t)},ge=()=>{x({name:``,tagline:``,systemPrompt:``}),C(`create`),ee(``)},L=async e=>{let t=await E(`/api/agents/${e.id}`).catch(()=>null);x({name:e.id,tagline:t?.tagline??e.description,systemPrompt:t?.systemPrompt??``}),C(`edit`),ee(``)},_e=async()=>{if(b){if(!b.tagline.trim()||!b.systemPrompt.trim()){ee(`Tagline and system prompt are required.`);return}ne(!0),ee(``);try{if(S===`create`){let e=b.name.toLowerCase().replace(/[^a-z0-9_-]/g,``);if(!e){ee(`Agent name required (lowercase, no spaces).`),ne(!1);return}let t=await D(`/api/agents`,{name:e,tagline:b.tagline,systemPrompt:b.systemPrompt});if(t?.error){ee(`Error: `+t.error),ne(!1);return}}else await D(`/api/agents/${b.name}`,{tagline:b.tagline,systemPrompt:b.systemPrompt,category:`custom`},`PUT`);x(null),oe()}catch(e){ee(`Error: `+e.message)}finally{ne(!1)}}},ve=e=>{confirm(`Delete agent "${e.label}"?`)&&D(`/api/agents/${e.id}`,{},`DELETE`).then(()=>oe())};return r?(0,k.jsx)(`div`,{className:q.root,children:(0,k.jsx)(`div`,{className:q.loading,children:(0,k.jsx)(`div`,{className:`spinner`})})}):(0,k.jsxs)(`div`,{className:q.root,children:[(0,k.jsxs)(`div`,{className:q.gridSection,children:[(0,k.jsxs)(`div`,{className:q.gridHeader,children:[(0,k.jsxs)(`div`,{className:q.headerRow,children:[(0,k.jsx)(`input`,{className:q.search,value:a,onChange:e=>o(e.target.value),placeholder:`Search agents…`}),(0,k.jsx)(`button`,{className:q.createBtn,onClick:ge,children:`+ Create`})]}),(0,k.jsx)(`div`,{className:q.catTabs,children:se.map(e=>(0,k.jsxs)(`button`,{className:`${q.catTab} ${s===e?q.catActive:``}`,onClick:()=>c(e),children:[e,` (`,e===`All`?t.length:t.filter(t=>t.category===e).length,`)`]},e))})]}),(0,k.jsx)(`div`,{className:q.grid,children:M.map(e=>{let t=l.some(t=>t.agent.id===e.id);return(0,k.jsxs)(`div`,{className:`${q.agentCard} ${t?q.agentActive:``}`,onClick:()=>ce(e),children:[(0,k.jsxs)(`div`,{className:q.agentCardTop,children:[(0,k.jsx)(`div`,{className:q.agentIcon,children:e.icon}),e.isCustom&&(0,k.jsxs)(`div`,{className:q.agentActions,children:[(0,k.jsx)(`button`,{className:q.agentEditBtn,onClick:t=>{t.stopPropagation(),L(e)},children:`✏️`}),(0,k.jsx)(`button`,{className:q.agentDelBtn,onClick:t=>{t.stopPropagation(),ve(e)},children:`🗑`})]})]}),(0,k.jsx)(`div`,{className:q.agentLabel,children:e.label}),(0,k.jsx)(`div`,{className:q.agentDesc,children:e.description}),(0,k.jsx)(`div`,{className:q.agentCat,children:e.category})]},e.id)})})]}),(0,k.jsx)(`div`,{className:q.chatArea,children:l.length===0?(0,k.jsxs)(`div`,{className:q.emptyChat,children:[(0,k.jsx)(`span`,{children:`Click an agent above to open a chat`}),(0,k.jsx)(`span`,{className:q.emptyChatHint,children:`Open multiple agents to run them in parallel`})]}):l.map(e=>{let{agent:t}=e,n=e.attachedFile?`📎 ${e.attachedFile.name}`:e.attachedImage?`🖼 ${e.attachedImage.name}`:null;return(0,k.jsxs)(`div`,{className:q.chatPanel,children:[(0,k.jsxs)(`div`,{className:q.chatHeader,children:[(0,k.jsx)(`span`,{className:q.chatIcon,children:t.icon}),(0,k.jsxs)(`div`,{className:q.chatHeaderInfo,children:[(0,k.jsx)(`div`,{className:q.chatAgentName,children:t.label}),(0,k.jsx)(`div`,{className:q.chatAgentDesc,children:t.description})]}),(0,k.jsx)(`button`,{className:q.closeChat,onClick:()=>N(t.id),children:`✕`})]}),(0,k.jsxs)(`div`,{className:q.chatMessages,ref:e=>{O.current.set(t.id,e)},children:[e.history.length===0&&(0,k.jsxs)(`div`,{className:q.chatEmpty,children:[`Ask `,t.label,` anything…`]}),e.history.map((e,t)=>(0,k.jsx)(`div`,{className:`${q.chatMsg} ${e.role===`user`?q.msgUser:q.msgAgent}`,children:e.role===`assistant`?(0,k.jsx)(`div`,{dangerouslySetInnerHTML:{__html:fe(e.content||`…`)}}):(0,k.jsx)(`span`,{children:e.content})},t)),e.streaming&&e.history[e.history.length-1]?.role===`assistant`&&e.history[e.history.length-1]?.content===``&&(0,k.jsxs)(`div`,{className:q.thinking,children:[(0,k.jsx)(`span`,{className:q.dot}),(0,k.jsx)(`span`,{className:q.dot}),(0,k.jsx)(`span`,{className:q.dot})]})]}),n&&(0,k.jsxs)(`div`,{className:q.attachBar,children:[(0,k.jsx)(`span`,{children:n}),(0,k.jsx)(`button`,{className:q.attachClear,onClick:()=>F(t.id,{attachedFile:null,attachedImage:null}),children:`×`})]}),(0,k.jsxs)(`div`,{className:q.chatInput,children:[(0,k.jsxs)(`div`,{className:q.chatTools,children:[(0,k.jsx)(`button`,{className:`${q.toolBtn} ${e.voiceActive?q.toolBtnActive:``}`,onClick:()=>pe(t.id),title:`Voice`,children:`🎤`}),(0,k.jsx)(`button`,{className:q.toolBtn,onClick:()=>ae.current.get(t.id)?.click(),title:`Attach file`,children:`📎`}),(0,k.jsx)(`button`,{className:q.toolBtn,onClick:()=>A.current.get(t.id)?.click(),title:`Attach image`,children:`🖼`}),(0,k.jsx)(`input`,{type:`file`,style:{display:`none`},ref:e=>{ae.current.set(t.id,e)},onChange:e=>me(t.id,e.target.files?.[0])}),(0,k.jsx)(`input`,{type:`file`,accept:`image/*`,style:{display:`none`},ref:e=>{A.current.set(t.id,e)},onChange:e=>he(t.id,e.target.files?.[0])})]}),(0,k.jsxs)(`div`,{className:q.chatInputRow,children:[(0,k.jsx)(`textarea`,{className:q.chatTextarea,value:e.input,onChange:e=>F(t.id,{input:e.target.value}),placeholder:`Message ${t.label}…`,rows:2,onKeyDown:t=>{t.key===`Enter`&&!t.shiftKey&&(t.preventDefault(),de(e,e.input,e.attachedFile,e.attachedImage))}}),(0,k.jsx)(`button`,{className:q.sendBtn,onClick:()=>de(e,e.input,e.attachedFile,e.attachedImage),disabled:e.streaming||!e.input.trim()&&!e.attachedFile&&!e.attachedImage,children:e.streaming?`…`:`→`})]})]})]},t.id)})}),l.length>=2&&(0,k.jsxs)(`div`,{className:q.orchBar,children:[(0,k.jsxs)(`div`,{className:q.orchLabel,children:[`🎼 Conductor · `,l.map(e=>`${e.agent.icon} ${e.agent.label}`).join(` · `)]}),(0,k.jsxs)(`div`,{className:q.orchRow,children:[(0,k.jsx)(`textarea`,{ref:j,className:q.orchInput,value:d,onChange:e=>f(e.target.value),placeholder:`Ask all agents — Conductor will synthesize a unified response…`,rows:1,onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),I())}}),(0,k.jsx)(`button`,{className:q.orchBtn,onClick:I,disabled:p||v||!d.trim(),children:p?`⏳`:v?`🔄`:`🎼 Run`})]}),(v||h)&&(0,k.jsxs)(`div`,{className:q.orchSynthesis,children:[(0,k.jsxs)(`div`,{className:q.orchSynthHeader,children:[(0,k.jsx)(`span`,{children:`🎼 Conductor Synthesis`}),v&&(0,k.jsx)(`span`,{className:q.orchSynthSpinner,children:`synthesizing…`})]}),(0,k.jsx)(`div`,{className:q.orchSynthBody,dangerouslySetInnerHTML:{__html:fe(h||`…`)}})]})]}),b&&(0,k.jsx)(`div`,{className:q.modalOverlay,onClick:e=>{e.target===e.currentTarget&&x(null)},children:(0,k.jsxs)(`div`,{className:q.modal,children:[(0,k.jsx)(`div`,{className:q.modalTitle,children:S===`create`?`+ New Agent`:`✏️ Edit Agent`}),S===`create`&&(0,k.jsxs)(`div`,{className:q.formField,children:[(0,k.jsx)(`label`,{className:q.formLabel,children:`Agent name (lowercase, no spaces)`}),(0,k.jsx)(`input`,{className:q.formInput,placeholder:`my-agent`,value:b.name,onChange:e=>x(t=>t&&{...t,name:e.target.value})})]}),(0,k.jsxs)(`div`,{className:q.formField,children:[(0,k.jsx)(`label`,{className:q.formLabel,children:`Tagline`}),(0,k.jsx)(`input`,{className:q.formInput,placeholder:`Short description`,value:b.tagline,onChange:e=>x(t=>t&&{...t,tagline:e.target.value})})]}),(0,k.jsxs)(`div`,{className:q.formField,children:[(0,k.jsx)(`label`,{className:q.formLabel,children:`System Prompt`}),(0,k.jsx)(`textarea`,{className:q.formTextarea,placeholder:`You are an expert in…`,value:b.systemPrompt,onChange:e=>x(t=>t&&{...t,systemPrompt:e.target.value})})]}),w&&(0,k.jsx)(`div`,{className:q.formError,children:w}),(0,k.jsxs)(`div`,{className:q.modalBtns,children:[(0,k.jsx)(`button`,{className:q.cancelBtn,onClick:()=>x(null),children:e(`common.cancel`)}),(0,k.jsx)(`button`,{className:q.modalSaveBtn,onClick:_e,disabled:te,children:te?`…`:S===`create`?`Create Agent`:`Save`})]})]})})]})}var J={root:`_root_1mam6_1`,error:`_error_1mam6_10`,errorHint:`_errorHint_1mam6_16`,quotaBar:`_quotaBar_1mam6_29`,quotaText:`_quotaText_1mam6_37`,quotaUsed:`_quotaUsed_1mam6_43`,quotaPct:`_quotaPct_1mam6_44`,quotaTrack:`_quotaTrack_1mam6_46`,quotaFill:`_quotaFill_1mam6_53`,actionBar:`_actionBar_1mam6_59`,filterBtn:`_filterBtn_1mam6_67`,filterActive:`_filterActive_1mam6_79`,spacer:`_spacer_1mam6_85`,newBtn:`_newBtn_1mam6_87`,uploadBtn:`_uploadBtn_1mam6_98`,searchRow:`_searchRow_1mam6_108`,searchInput:`_searchInput_1mam6_114`,searchBtn:`_searchBtn_1mam6_126`,loading:`_loading_1mam6_136`,empty:`_empty_1mam6_141`,fileList:`_fileList_1mam6_151`,fileRow:`_fileRow_1mam6_159`,fileIcon:`_fileIcon_1mam6_172`,fileInfo:`_fileInfo_1mam6_174`,fileName:`_fileName_1mam6_176`,fileMeta:`_fileMeta_1mam6_184`,fileBtns:`_fileBtns_1mam6_190`,editBtn:`_editBtn_1mam6_196`,viewBtn:`_viewBtn_1mam6_197`,pdfBtn:`_pdfBtn_1mam6_198`,openBtn:`_openBtn_1mam6_199`,delBtn:`_delBtn_1mam6_200`,editorRoot:`_editorRoot_1mam6_204`,editorToolbar:`_editorToolbar_1mam6_211`,backBtn:`_backBtn_1mam6_221`,editorName:`_editorName_1mam6_231`,saveBtn:`_saveBtn_1mam6_238`,editorArea:`_editorArea_1mam6_251`,editorMeta:`_editorMeta_1mam6_266`,viewerRoot:`_viewerRoot_1mam6_276`,imgContainer:`_imgContainer_1mam6_283`,imgView:`_imgView_1mam6_292`,pdfFrame:`_pdfFrame_1mam6_298`};function Wt(e,t){return e===`folder`?`📁`:e===`image`?`🖼`:e===`pdf`||t.includes(`pdf`)?`📕`:e===`video`?`🎬`:e===`audio`?`🎵`:t.includes(`spreadsheet`)||t.includes(`excel`)?`📊`:t.includes(`presentation`)||t.includes(`powerpoint`)?`📽`:t.includes(`document`)||t.includes(`word`)?`📄`:t.includes(`zip`)||t.includes(`archive`)?`📦`:`📄`}function Gt(e){let t=e.mimeType;return e.type===`text`||e.type===`doc`||t.includes(`text`)||t.includes(`json`)||t.includes(`javascript`)||t.includes(`xml`)||t.includes(`csv`)||t.includes(`yaml`)||t.includes(`markdown`)||t.includes(`html`)||t.includes(`css`)||t.includes(`python`)||t.includes(`vnd.google-apps.document`)}function Kt(){let e=P(),[t,n]=(0,_.useState)(null),[r,i]=(0,_.useState)(!0),[a,o]=(0,_.useState)(``),[s,c]=(0,_.useState)(``),[l,u]=(0,_.useState)(``),[d,f]=(0,_.useState)(``),[p,m]=(0,_.useState)(`list`),[h,g]=(0,_.useState)(null),[v,y]=(0,_.useState)(``),[b,x]=(0,_.useState)(null),[S,C]=(0,_.useState)(!1),w=(0,_.useRef)(null),ee=(e=s,t=l)=>{i(!0);let r=`/api/drive`;e&&(r+=`?filter=${e}`),t&&(r+=`${e?`&`:`?`}search=${encodeURIComponent(t)}`),E(r).then(e=>{n(e??{files:[]}),i(!1)}).catch(e=>{o(e.message??`Error`),i(!1)})};(0,_.useEffect)(()=>{ee()},[]);let te=e=>{c(e),ee(e,l)},ne=()=>{u(d),ee(s,d)},T=(e,t)=>{i(!0),E(`/api/drive/read/${e}`).then(n=>{g({id:e,name:t,content:n?.content??``}),y(n?.content??``),m(`editor`),i(!1)}).catch(()=>i(!1))},re=async()=>{if(h&&confirm(`Save changes to "${h.name}" on Drive?`)){C(!0);try{await D(`/api/drive/update/${h.id}`,{content:v}),g(e=>e&&{...e,content:v}),alert(`Saved!`)}catch(e){alert(`Save failed: `+e.message)}finally{C(!1)}}},ie=(e,t)=>{i(!0),E(`/api/drive/download/${e}`).then(n=>{x({id:e,name:t,src:`data:${n?.mimeType??`image/jpeg`};base64,${n?.base64}`,mode:`image`}),m(`image`),i(!1)}).catch(()=>i(!1))},O=(e,t)=>{i(!0),E(`/api/drive/download/${e}`).then(n=>{x({id:e,name:t,src:`data:application/pdf;base64,${n?.base64}`,mode:`pdf`}),m(`pdf`),i(!1)}).catch(()=>i(!1))},ae=(e,t)=>{confirm(`Delete "${t}" from Drive? (moved to trash)`)&&D(`/api/drive/delete/${e}`,{}).then(()=>{n(null),ee()})},A=()=>{let e=prompt(`File name (e.g. notes.txt, script.py):`);e&&D(`/api/drive/upload`,{name:e,content:``,mimeType:`text/plain`}).then(t=>{t?.id?T(t.id,e):ee()}).catch(e=>alert(`Error: `+e.message))},j=()=>{w.current?.click()},oe=e=>{if(!e)return;let t=new FileReader;t.onload=t=>{let r=(t.target?.result).split(`,`)[1]??``;D(`/api/drive/upload`,{name:e.name,content:r,mimeType:e.type||`application/octet-stream`,encoding:`base64`}).then(()=>{n(null),ee()}).catch(e=>alert(`Upload error: `+e.message))},t.readAsDataURL(e)};if(a)return(0,k.jsxs)(`div`,{className:J.error,children:[(0,k.jsx)(`div`,{children:a}),(0,k.jsxs)(`div`,{className:J.errorHint,children:[`Run: `,(0,k.jsx)(`code`,{children:`nha google revoke`}),` then `,(0,k.jsx)(`code`,{children:`nha google auth`})]})]});if(p===`editor`&&h)return(0,k.jsxs)(`div`,{className:J.editorRoot,children:[(0,k.jsxs)(`div`,{className:J.editorToolbar,children:[(0,k.jsx)(`button`,{className:J.backBtn,onClick:()=>m(`list`),children:`← Back`}),(0,k.jsx)(`span`,{className:J.editorName,children:h.name}),(0,k.jsx)(`button`,{className:J.saveBtn,onClick:re,disabled:S,children:S?`Saving…`:`Save to Drive`})]}),(0,k.jsx)(`textarea`,{className:J.editorArea,value:v,onChange:e=>y(e.target.value),spellCheck:!1,onKeyDown:e=>{if(e.key===`Tab`){e.preventDefault();let t=e.currentTarget.selectionStart,n=e.currentTarget.selectionEnd,r=e.currentTarget.value;e.currentTarget.value=r.slice(0,t)+` `+r.slice(n),e.currentTarget.selectionStart=e.currentTarget.selectionEnd=t+2}}}),(0,k.jsxs)(`div`,{className:J.editorMeta,children:[`File ID: `,h.id,` · Tab = 2 spaces · Not auto-saved`]})]});if(p===`image`&&b)return(0,k.jsxs)(`div`,{className:J.viewerRoot,children:[(0,k.jsxs)(`div`,{className:J.editorToolbar,children:[(0,k.jsx)(`button`,{className:J.backBtn,onClick:()=>m(`list`),children:`← Back`}),(0,k.jsx)(`span`,{className:J.editorName,children:b.name})]}),(0,k.jsx)(`div`,{className:J.imgContainer,children:(0,k.jsx)(`img`,{src:b.src,alt:b.name,className:J.imgView})})]});if(p===`pdf`&&b)return(0,k.jsxs)(`div`,{className:J.viewerRoot,children:[(0,k.jsxs)(`div`,{className:J.editorToolbar,children:[(0,k.jsx)(`button`,{className:J.backBtn,onClick:()=>m(`list`),children:`← Back`}),(0,k.jsx)(`span`,{className:J.editorName,children:b.name})]}),(0,k.jsx)(`iframe`,{className:J.pdfFrame,src:b.src,title:b.name})]});let se=t?.files??[],M=t?.quota;return(0,k.jsxs)(`div`,{className:J.root,children:[M&&(0,k.jsxs)(`div`,{className:J.quotaBar,children:[(0,k.jsxs)(`div`,{className:J.quotaText,children:[(0,k.jsxs)(`span`,{className:J.quotaUsed,children:[M.usage,` of `,M.limit,` used`]}),(0,k.jsxs)(`span`,{className:J.quotaPct,children:[M.percentUsed,`%`]})]}),(0,k.jsx)(`div`,{className:J.quotaTrack,children:(0,k.jsx)(`div`,{className:J.quotaFill,style:{width:`${Math.min(M.percentUsed,100)}%`,background:M.percentUsed>90?`var(--red)`:M.percentUsed>70?`var(--amber)`:`var(--green)`}})})]}),(0,k.jsxs)(`div`,{className:J.actionBar,children:[[``,`recent`,`starred`,`shared`].map(e=>(0,k.jsx)(`button`,{className:`${J.filterBtn} ${s===e?J.filterActive:``}`,onClick:()=>te(e),children:e?e.charAt(0).toUpperCase()+e.slice(1):`All Files`},e)),(0,k.jsx)(`div`,{className:J.spacer}),(0,k.jsx)(`button`,{className:J.newBtn,onClick:A,children:`+ New File`}),(0,k.jsx)(`button`,{className:J.uploadBtn,onClick:j,children:e(`drive.upload`)}),(0,k.jsx)(`input`,{ref:w,type:`file`,style:{display:`none`},onChange:e=>oe(e.target.files?.[0])})]}),(0,k.jsxs)(`div`,{className:J.searchRow,children:[(0,k.jsx)(`input`,{className:J.searchInput,value:d,onChange:e=>f(e.target.value),placeholder:`Search files…`,onKeyDown:e=>e.key===`Enter`&&ne()}),(0,k.jsx)(`button`,{className:J.searchBtn,onClick:ne,children:`Search`})]}),r&&(0,k.jsx)(`div`,{className:J.loading,children:(0,k.jsx)(`div`,{className:`spinner`})}),!r&&se.length===0&&(0,k.jsxs)(`div`,{className:J.empty,children:[e(`drive.noFiles`),` found`]}),(0,k.jsx)(`div`,{className:J.fileList,children:se.map(e=>{let t=Gt(e),n=e.type===`image`,r=e.type===`pdf`||e.mimeType.includes(`pdf`);return(0,k.jsxs)(`div`,{className:J.fileRow,onClick:()=>{t?T(e.id,e.name):n?ie(e.id,e.name):r?O(e.id,e.name):e.webViewLink&&window.open(e.webViewLink,`_blank`)},style:{cursor:t||n||r||e.webViewLink?`pointer`:`default`},children:[(0,k.jsx)(`span`,{className:J.fileIcon,children:Wt(e.type,e.mimeType)}),(0,k.jsxs)(`div`,{className:J.fileInfo,children:[(0,k.jsx)(`div`,{className:J.fileName,children:e.name}),(0,k.jsxs)(`div`,{className:J.fileMeta,children:[e.modifiedTime?new Date(e.modifiedTime).toLocaleDateString():``,e.size?` · ${e.size}`:``,e.shared?` · Shared`:``,e.starred?` ★`:``]})]}),(0,k.jsxs)(`div`,{className:J.fileBtns,children:[t&&(0,k.jsx)(`button`,{className:J.editBtn,onClick:t=>{t.stopPropagation(),T(e.id,e.name)},children:`Edit`}),n&&(0,k.jsx)(`button`,{className:J.viewBtn,onClick:t=>{t.stopPropagation(),ie(e.id,e.name)},children:`View`}),r&&(0,k.jsx)(`button`,{className:J.pdfBtn,onClick:t=>{t.stopPropagation(),O(e.id,e.name)},children:`PDF`}),e.webViewLink&&(0,k.jsx)(`a`,{className:J.openBtn,href:e.webViewLink,target:`_blank`,rel:`noreferrer`,onClick:e=>e.stopPropagation(),children:`Open ↗`}),(0,k.jsx)(`button`,{className:J.delBtn,onClick:t=>{t.stopPropagation(),ae(e.id,e.name)},children:`Del`})]})]},e.id)})})]})}var Y={root:`_root_a0x57_1`,loading:`_loading_a0x57_10`,errorBox:`_errorBox_a0x57_12`,errorHint:`_errorHint_a0x57_13`,userRow:`_userRow_a0x57_16`,avatar:`_avatar_a0x57_27`,userLogin:`_userLogin_a0x57_29`,userName:`_userName_a0x57_30`,disconnectBtn:`_disconnectBtn_a0x57_32`,repoBar:`_repoBar_a0x57_43`,repoInput:`_repoInput_a0x57_49`,issuesBtn:`_issuesBtn_a0x57_61`,prsBtn:`_prsBtn_a0x57_72`,repoPills:`_repoPills_a0x57_83`,repoPill:`_repoPill_a0x57_83`,issueCount:`_issueCount_a0x57_106`,tabs:`_tabs_a0x57_112`,tab:`_tab_a0x57_112`,tabActive:`_tabActive_a0x57_131`,markRead:`_markRead_a0x57_137`,content:`_content_a0x57_148`,empty:`_empty_a0x57_150`,notifRow:`_notifRow_a0x57_152`,issueRow:`_issueRow_a0x57_152`,prRow:`_prRow_a0x57_152`,notifRepo:`_notifRepo_a0x57_166`,notifType:`_notifType_a0x57_167`,notifTitle:`_notifTitle_a0x57_168`,notifMeta:`_notifMeta_a0x57_169`,issueNum:`_issueNum_a0x57_171`,issueTitle:`_issueTitle_a0x57_172`,issueMeta:`_issueMeta_a0x57_173`,issueLabel:`_issueLabel_a0x57_174`,prNum:`_prNum_a0x57_176`,prTitle:`_prTitle_a0x57_177`,prAuthor:`_prAuthor_a0x57_178`,prDraft:`_prDraft_a0x57_179`,prMeta:`_prMeta_a0x57_180`};function qt(){let e=P(),[t,n]=(0,_.useState)(null),[r,i]=(0,_.useState)(!0),[a,o]=(0,_.useState)(``),[s,c]=(0,_.useState)(``),[l,u]=(0,_.useState)(`notifs`),d=(e=``)=>{i(!0),E(e?`/api/github?repo=${encodeURIComponent(e)}`:`/api/github`).then(e=>{n(e??{}),i(!1)}).catch(()=>i(!1))};(0,_.useEffect)(()=>{d()},[]);let f=()=>{let e=s.trim();o(e),d(e),u(`issues`)},p=()=>{let e=s.trim();o(e),d(e),u(`prs`)},m=()=>D(`/api/github/mark-read`,{}).then(()=>d(a)),h=()=>{confirm(`Remove GitHub connection? You can reconnect anytime.`)&&D(`/api/config`,{key:`github-token`,value:``}).then(()=>{n(null),i(!1)})};if(r)return(0,k.jsx)(`div`,{className:Y.loading,children:(0,k.jsx)(`div`,{className:`spinner`})});if(t?.error)return(0,k.jsxs)(`div`,{className:Y.errorBox,children:[(0,k.jsx)(`div`,{children:t.error}),(0,k.jsxs)(`div`,{className:Y.errorHint,children:[`Run: `,(0,k.jsx)(`code`,{children:`nha config set github-token YOUR_PAT`})]})]});let g=t?.user,v=t?.notifications??[],y=t?.issues??[],b=t?.prs??[];return(0,k.jsxs)(`div`,{className:Y.root,children:[g?.login&&(0,k.jsxs)(`div`,{className:Y.userRow,children:[g.avatar&&(0,k.jsx)(`img`,{src:g.avatar,className:Y.avatar,alt:g.login}),(0,k.jsxs)(`div`,{style:{flex:1},children:[(0,k.jsxs)(`div`,{className:Y.userLogin,children:[`@`,g.login]}),g.name&&(0,k.jsx)(`div`,{className:Y.userName,children:g.name})]}),(0,k.jsx)(`button`,{className:Y.disconnectBtn,onClick:h,children:`Disconnect`})]}),(0,k.jsxs)(`div`,{className:Y.repoBar,children:[(0,k.jsx)(`input`,{className:Y.repoInput,value:s,onChange:e=>c(e.target.value),placeholder:`owner/repo`,onKeyDown:e=>e.key===`Enter`&&f()}),(0,k.jsx)(`button`,{className:Y.issuesBtn,onClick:f,children:`Issues`}),(0,k.jsx)(`button`,{className:Y.prsBtn,onClick:p,children:`PRs`})]}),g?.repos&&g.repos.length>0&&(0,k.jsx)(`div`,{className:Y.repoPills,children:g.repos.slice(0,12).map(e=>(0,k.jsxs)(`button`,{className:Y.repoPill,onClick:()=>{c(e.full_name),o(e.full_name),d(e.full_name),u(`issues`)},title:e.description??``,children:[e.private?`🔒 `:``,e.full_name,e.open_issues?(0,k.jsx)(`span`,{className:Y.issueCount,children:e.open_issues}):null]},e.full_name))}),(0,k.jsxs)(`div`,{className:Y.tabs,children:[(0,k.jsxs)(`button`,{className:`${Y.tab} ${l===`notifs`?Y.tabActive:``}`,onClick:()=>u(`notifs`),children:[`Notifications `,v.length>0?`(${v.length})`:``]}),y.length>0&&(0,k.jsxs)(`button`,{className:`${Y.tab} ${l===`issues`?Y.tabActive:``}`,onClick:()=>u(`issues`),children:[`Issues (`,y.length,`)`]}),b.length>0&&(0,k.jsxs)(`button`,{className:`${Y.tab} ${l===`prs`?Y.tabActive:``}`,onClick:()=>u(`prs`),children:[`PRs (`,b.length,`)`]}),l===`notifs`&&v.length>0&&(0,k.jsx)(`button`,{className:Y.markRead,onClick:m,children:`Mark all read`})]}),(0,k.jsxs)(`div`,{className:Y.content,children:[l===`notifs`&&(v.length===0?(0,k.jsx)(`div`,{className:Y.empty,children:`No notifications`}):v.map((e,t)=>(0,k.jsxs)(`a`,{className:Y.notifRow,href:e.url,target:`_blank`,rel:`noreferrer`,children:[(0,k.jsx)(`span`,{className:Y.notifRepo,children:e.repo}),(0,k.jsxs)(`span`,{className:Y.notifType,children:[`[`,e.type,`]`]}),(0,k.jsx)(`div`,{className:Y.notifTitle,children:e.title}),(0,k.jsxs)(`div`,{className:Y.notifMeta,children:[e.reason,` · `,e.updated]})]},t))),l===`issues`&&(y.length===0?(0,k.jsxs)(`div`,{className:Y.empty,children:[e(`github.noIssues`),` for `,a]}):y.map((e,t)=>(0,k.jsxs)(`a`,{className:Y.issueRow,href:e.url,target:`_blank`,rel:`noreferrer`,children:[(0,k.jsxs)(`span`,{className:Y.issueNum,children:[`#`,e.number]}),(0,k.jsx)(`span`,{className:Y.issueTitle,children:e.title}),e.assignee&&(0,k.jsxs)(`span`,{className:Y.issueMeta,children:[`→ `,e.assignee]}),e.labels&&(0,k.jsxs)(`span`,{className:Y.issueLabel,children:[`[`,e.labels,`]`]}),(0,k.jsx)(`div`,{className:Y.issueMeta,children:e.updated})]},t))),l===`prs`&&(b.length===0?(0,k.jsxs)(`div`,{className:Y.empty,children:[`No PRs for `,a]}):b.map((e,t)=>(0,k.jsxs)(`a`,{className:Y.prRow,href:e.url,target:`_blank`,rel:`noreferrer`,children:[(0,k.jsxs)(`span`,{className:Y.prNum,children:[`#`,e.number]}),(0,k.jsx)(`span`,{className:Y.prTitle,children:e.title}),(0,k.jsxs)(`span`,{className:Y.prAuthor,children:[`by `,e.author]}),e.draft&&(0,k.jsx)(`span`,{className:Y.prDraft,children:`DRAFT`}),(0,k.jsx)(`div`,{className:Y.prMeta,children:e.updated})]},t)))]})]})}var Jt={loading:`_loading_1h5ss_1`,errorBox:`_errorBox_1h5ss_3`,errorHint:`_errorHint_1h5ss_4`,twoPane:`_twoPane_1h5ss_7`,sidebar:`_sidebar_1h5ss_13`,sidebarTitle:`_sidebarTitle_1h5ss_24`,workspace:`_workspace_1h5ss_36`,searchRow:`_searchRow_1h5ss_42`,searchInput:`_searchInput_1h5ss_50`,searchBtn:`_searchBtn_1h5ss_63`,channelItem:`_channelItem_1h5ss_73`,channelActive:`_channelActive_1h5ss_83`,pageTitle:`_pageTitle_1h5ss_89`,pageMeta:`_pageMeta_1h5ss_97`,disconnectBtn:`_disconnectBtn_1h5ss_99`,empty:`_empty_1h5ss_110`,messagePane:`_messagePane_1h5ss_112`,channelHeader:`_channelHeader_1h5ss_120`,emptyPane:`_emptyPane_1h5ss_129`,message:`_message_1h5ss_112`,msgUser:`_msgUser_1h5ss_146`,msgText:`_msgText_1h5ss_147`,msgTs:`_msgTs_1h5ss_148`,openLink:`_openLink_1h5ss_150`,pageBody:`_pageBody_1h5ss_160`};function Yt(){let e=P(),[t,n]=(0,_.useState)(null),[r,i]=(0,_.useState)(!0),[a,o]=(0,_.useState)(null),[s,c]=(0,_.useState)([]),l=()=>{i(!0),E(`/api/slack/channels`).then(e=>{n(e??{}),i(!1)}).catch(()=>i(!1))},u=e=>{o(e),E(`/api/slack/messages?channel=${e.id}`).then(e=>c(e?.messages??[]))};if((0,_.useEffect)(()=>{l()},[]),r)return(0,k.jsxs)(`div`,{className:Jt.loading,children:[(0,k.jsx)(`div`,{className:`spinner`}),e(`common.loading`)]});if(t?.error)return(0,k.jsxs)(`div`,{className:Jt.errorBox,children:[(0,k.jsx)(`div`,{children:t.error}),(0,k.jsxs)(`div`,{className:Jt.errorHint,children:[`Run: `,(0,k.jsx)(`code`,{children:`nha config set slack-token xoxb-YOUR-TOKEN`})]})]});let d=t?.channels??[];return(0,k.jsxs)(`div`,{className:Jt.twoPane,children:[(0,k.jsxs)(`div`,{className:Jt.sidebar,children:[(0,k.jsxs)(`div`,{className:Jt.sidebarTitle,children:[(0,k.jsx)(`span`,{children:`💬 Slack`}),t?.workspace&&(0,k.jsx)(`span`,{className:Jt.workspace,children:t.workspace})]}),d.length===0&&(0,k.jsx)(`div`,{className:Jt.empty,children:`No channels`}),d.map(e=>(0,k.jsxs)(`div`,{className:`${Jt.channelItem} ${a?.id===e.id?Jt.channelActive:``}`,onClick:()=>u(e),children:[`# `,e.name]},e.id)),(0,k.jsx)(`button`,{className:Jt.disconnectBtn,onClick:()=>D(`/api/config`,{key:`slack-token`,value:``}).then(l),children:`Disconnect`})]}),(0,k.jsx)(`div`,{className:Jt.messagePane,children:a?(0,k.jsxs)(k.Fragment,{children:[(0,k.jsxs)(`div`,{className:Jt.channelHeader,children:[`#`,a.name]}),s.length===0&&(0,k.jsx)(`div`,{className:Jt.empty,children:`No messages`}),s.map((e,t)=>(0,k.jsxs)(`div`,{className:Jt.message,children:[(0,k.jsx)(`span`,{className:Jt.msgUser,children:e.username||e.user||`Unknown`}),(0,k.jsx)(`span`,{className:Jt.msgText,children:e.text}),(0,k.jsx)(`span`,{className:Jt.msgTs,children:new Date(parseFloat(e.ts)*1e3).toLocaleTimeString()})]},t))]}):(0,k.jsx)(`div`,{className:Jt.emptyPane,children:`Select a channel`})})]})}function Xt(){let e=P(),[t,n]=(0,_.useState)(null),[r,i]=(0,_.useState)(!0),[a,o]=(0,_.useState)(null),[s,c]=(0,_.useState)(``),[l,u]=(0,_.useState)(``),d=(e=``)=>{i(!0),E(e?`/api/notion/search?q=${encodeURIComponent(e)}`:`/api/notion`).then(e=>{n(e??{}),i(!1)}).catch(()=>i(!1))},f=e=>{o(e),E(`/api/notion/page?id=${encodeURIComponent(e.id)}`).then(e=>c(e?.content??``))};(0,_.useEffect)(()=>{d()},[]);let p=()=>d(l);if(r)return(0,k.jsxs)(`div`,{className:Jt.loading,children:[(0,k.jsx)(`div`,{className:`spinner`}),e(`common.loading`)]});if(t?.error)return(0,k.jsxs)(`div`,{className:Jt.errorBox,children:[(0,k.jsx)(`div`,{children:t.error}),(0,k.jsxs)(`div`,{className:Jt.errorHint,children:[`Run: `,(0,k.jsx)(`code`,{children:`nha config set notion-token secret_YOUR_TOKEN`})]})]});let m=t?.pages??[];return(0,k.jsxs)(`div`,{className:Jt.twoPane,children:[(0,k.jsxs)(`div`,{className:Jt.sidebar,children:[(0,k.jsx)(`div`,{className:Jt.sidebarTitle,children:`📋 Notion`}),(0,k.jsxs)(`div`,{className:Jt.searchRow,children:[(0,k.jsx)(`input`,{className:Jt.searchInput,value:l,onChange:e=>u(e.target.value),placeholder:`Search pages…`,onKeyDown:e=>e.key===`Enter`&&p()}),(0,k.jsx)(`button`,{className:Jt.searchBtn,onClick:p,children:`Go`})]}),m.length===0&&(0,k.jsx)(`div`,{className:Jt.empty,children:`No pages found`}),m.map(e=>(0,k.jsxs)(`div`,{className:`${Jt.channelItem} ${a?.id===e.id?Jt.channelActive:``}`,onClick:()=>f(e),children:[(0,k.jsx)(`div`,{className:Jt.pageTitle,children:e.title||`Untitled`}),e.last_edited&&(0,k.jsx)(`div`,{className:Jt.pageMeta,children:e.last_edited.slice(0,10)})]},e.id)),(0,k.jsx)(`button`,{className:Jt.disconnectBtn,onClick:()=>D(`/api/config`,{key:`notion-token`,value:``}).then(()=>d()),children:`Disconnect`})]}),(0,k.jsx)(`div`,{className:Jt.messagePane,children:a?(0,k.jsxs)(k.Fragment,{children:[(0,k.jsx)(`div`,{className:Jt.channelHeader,children:a.title}),a.url&&(0,k.jsx)(`a`,{className:Jt.openLink,href:a.url,target:`_blank`,rel:`noreferrer`,children:`Open in Notion ↗`}),(0,k.jsx)(`div`,{className:Jt.pageBody,dangerouslySetInnerHTML:{__html:fe(s||`Loading…`)}})]}):(0,k.jsx)(`div`,{className:Jt.emptyPane,children:`Select a page`})})]})}var X={root:`_root_1l3ll_1`,sidebar:`_sidebar_1l3ll_8`,sidebarHeader:`_sidebarHeader_1l3ll_18`,sidebarTitle:`_sidebarTitle_1l3ll_19`,sidebarBtns:`_sidebarBtns_1l3ll_21`,createBtn:`_createBtn_1l3ll_22`,joinBtn:`_joinBtn_1l3ll_23`,noChannels:`_noChannels_1l3ll_25`,channelItem:`_channelItem_1l3ll_27`,channelActive:`_channelActive_1l3ll_29`,channelName:`_channelName_1l3ll_30`,channelMeta:`_channelMeta_1l3ll_31`,channelCode:`_channelCode_1l3ll_32`,channelDel:`_channelDel_1l3ll_34`,main:`_main_1l3ll_38`,chatHeader:`_chatHeader_1l3ll_41`,chatChannelName:`_chatChannelName_1l3ll_50`,chatChannelId:`_chatChannelId_1l3ll_51`,statusDot:`_statusDot_1l3ll_52`,connected:`_connected_1l3ll_53`,disconnected:`_disconnected_1l3ll_54`,statusText:`_statusText_1l3ll_55`,messages:`_messages_1l3ll_58`,emptyMsgs:`_emptyMsgs_1l3ll_66`,msg:`_msg_1l3ll_68`,msgSelf:`_msgSelf_1l3ll_69`,msgOther:`_msgOther_1l3ll_70`,msgSender:`_msgSender_1l3ll_71`,msgContent:`_msgContent_1l3ll_72`,msgTime:`_msgTime_1l3ll_82`,inputRow:`_inputRow_1l3ll_85`,textInput:`_textInput_1l3ll_86`,sendBtn:`_sendBtn_1l3ll_88`,welcome:`_welcome_1l3ll_92`,welcomeIcon:`_welcomeIcon_1l3ll_103`,welcomeTitle:`_welcomeTitle_1l3ll_104`,welcomeSub:`_welcomeSub_1l3ll_105`,welcomeBox:`_welcomeBox_1l3ll_106`,welcomeBoxTitle:`_welcomeBoxTitle_1l3ll_107`,welcomeStep:`_welcomeStep_1l3ll_108`,welcomeHint:`_welcomeHint_1l3ll_109`,cliCmd:`_cliCmd_1l3ll_110`};function Zt(e){return e.content||e.plaintext||e.message||``}function Qt(e){return e.senderName||e.senderFingerprint?.slice(0,8)||e.sender||`unknown`}function $t(){let e=P(),[t,n]=(0,_.useState)([]),[r,i]=(0,_.useState)(null),[a,o]=(0,_.useState)([]),[s,c]=(0,_.useState)(``),[l,u]=(0,_.useState)(!1),[d]=(0,_.useState)(()=>`nha-ui-${Math.random().toString(36).slice(2,8)}`),f=(0,_.useRef)(null),p=(0,_.useRef)(null);(0,_.useEffect)(()=>{E(`/api/collab/channels`).then(e=>{n(e?.channels??[])}).catch(()=>{})},[]),(0,_.useEffect)(()=>{if(r)return m(r),h(r),()=>{f.current?.close(),u(!1)}},[r]);let m=e=>{E(`/api/collab/messages?channelId=${e}`).then(e=>{e?.messages&&(o(e.messages),setTimeout(()=>{p.current&&(p.current.scrollTop=p.current.scrollHeight)},50))}).catch(()=>{})},h=e=>{f.current?.close();let t=window.location.protocol===`https:`?`wss:`:`ws:`,n=window.location.port===`3030`||window.location.port===`3031`?`3020`:window.location.port||`3020`,r=`${t}//${window.location.hostname}:${n}/ws/alexandria?channel=${e}&agentId=${encodeURIComponent(d)}`,i=new WebSocket(r);f.current=i,i.onopen=()=>u(!0),i.onclose=()=>u(!1),i.onmessage=e=>{try{let t=JSON.parse(e.data);if(!t)return;o(e=>[...e,{...t,id:t.id||Date.now().toString(),type:`message`}]),p.current&&(p.current.scrollTop=p.current.scrollHeight)}catch{}}},g=async()=>{let e=prompt(`Channel name:`);if(!e)return;let t=await D(`/api/collab/create`,{name:e}).catch(()=>null);if(!t||t.error){alert(t?.error||`Error creating channel`);return}let r=t.id;await D(`/api/collab/channels`,{id:r,name:e,role:`creator`}).catch(()=>{});let a={id:r,name:e,role:`creator`};n(e=>[...e,a]),i(r),prompt(`Share this invite code with collaborators:`,r)},v=async()=>{let e=prompt(`Invite code:`);if(!e)return;let t=await D(`/api/collab/join`,{channelId:e}).catch(()=>null);if(!t||t.error){alert(t?.error||`Error joining channel`);return}let r=t.name||e.slice(0,8);await D(`/api/collab/channels`,{id:e,name:r,role:`member`}).catch(()=>{}),n(t=>[...t,{id:e,name:r,role:`member`}]),i(e)},y=async e=>{confirm(`Delete this channel? Messages will be lost.`)&&(D(`/api/collab/delete`,{channelId:e}).catch(()=>{}),n(t=>t.filter(t=>t.id!==e)),r===e&&(i(null),o([]),f.current?.close(),u(!1)))},b=async()=>{let e=s.trim();if(!e||!r)return;c(``);let t=await D(`/api/collab/send`,{channelId:r,message:e}).catch(()=>null);t?.error&&alert(t.error),l||m(r)},x=e=>{navigator.clipboard.writeText(e).catch(()=>{})};return(0,k.jsxs)(`div`,{className:X.root,children:[(0,k.jsxs)(`div`,{className:X.sidebar,children:[(0,k.jsx)(`div`,{className:X.sidebarHeader,children:(0,k.jsx)(`div`,{className:X.sidebarTitle,children:`Alexandria`})}),(0,k.jsxs)(`div`,{className:X.sidebarBtns,children:[(0,k.jsx)(`button`,{className:X.createBtn,onClick:g,children:`+ Create`}),(0,k.jsx)(`button`,{className:X.joinBtn,onClick:v,children:`Join`})]}),t.length===0?(0,k.jsxs)(`div`,{className:X.noChannels,children:[e(`collab.noChannels`),` yet`]}):t.map(e=>(0,k.jsxs)(`div`,{className:`${X.channelItem} ${r===e.id?X.channelActive:``}`,onClick:()=>i(e.id),children:[(0,k.jsx)(`div`,{className:X.channelName,children:e.name}),(0,k.jsxs)(`div`,{className:X.channelMeta,children:[(0,k.jsxs)(`span`,{className:X.channelCode,onClick:t=>{t.stopPropagation(),x(e.id)},title:`Click to copy invite code`,children:[e.id.slice(0,8),`…`]}),(0,k.jsx)(`button`,{className:X.channelDel,onClick:t=>{t.stopPropagation(),y(e.id)},children:`del`})]})]},e.id))]}),(0,k.jsx)(`div`,{className:X.main,children:r?(0,k.jsxs)(k.Fragment,{children:[(0,k.jsxs)(`div`,{className:X.chatHeader,children:[(0,k.jsx)(`div`,{className:X.chatChannelName,children:t.find(e=>e.id===r)?.name??r.slice(0,12)}),(0,k.jsx)(`div`,{className:X.chatChannelId,children:r}),(0,k.jsx)(`div`,{className:`${X.statusDot} ${l?X.connected:X.disconnected}`}),(0,k.jsx)(`span`,{className:X.statusText,children:l?`Live`:`HTTP`})]}),(0,k.jsxs)(`div`,{className:X.messages,ref:p,children:[a.length===0&&(0,k.jsx)(`div`,{className:X.emptyMsgs,children:`No messages yet`}),a.map((e,t)=>{let n=Qt(e),r=Zt(e),i=n===d;return(0,k.jsxs)(`div`,{className:`${X.msg} ${i?X.msgSelf:X.msgOther}`,children:[!i&&(0,k.jsx)(`div`,{className:X.msgSender,children:n}),(0,k.jsx)(`div`,{className:X.msgContent,children:r}),(0,k.jsx)(`div`,{className:X.msgTime,children:new Date(e.timestamp).toLocaleTimeString()})]},e.id||t)})]}),(0,k.jsxs)(`div`,{className:X.inputRow,children:[(0,k.jsx)(`input`,{className:X.textInput,value:s,onChange:e=>c(e.target.value),placeholder:`Send an encrypted message…`,onKeyDown:e=>e.key===`Enter`&&!e.shiftKey&&b()}),(0,k.jsx)(`button`,{className:X.sendBtn,onClick:b,disabled:!s.trim(),children:e(`collab.send`)})]})]}):(0,k.jsxs)(`div`,{className:X.welcome,children:[(0,k.jsx)(`div`,{className:X.welcomeIcon,children:`🔐`}),(0,k.jsx)(`div`,{className:X.welcomeTitle,children:`Alexandria`}),(0,k.jsx)(`div`,{className:X.welcomeSub,children:`E2E encrypted messaging for AI agents and teams`}),(0,k.jsxs)(`div`,{className:X.welcomeBox,children:[(0,k.jsx)(`div`,{className:X.welcomeBoxTitle,children:`HOW TO USE`}),(0,k.jsxs)(`div`,{className:X.welcomeStep,children:[(0,k.jsx)(`strong`,{children:`1. Create a channel`}),` — Click [+ Create] in the sidebar. Give it a name.`]}),(0,k.jsx)(`div`,{className:X.welcomeHint,children:`You get an invite code. Share it with your team or another AI session.`}),(0,k.jsxs)(`div`,{className:X.welcomeStep,children:[(0,k.jsx)(`strong`,{children:`2. Others join`}),` — They click [Join] and paste the invite code.`]}),(0,k.jsx)(`div`,{className:X.welcomeHint,children:`Works from this web UI, the Android app, or the CLI.`}),(0,k.jsxs)(`div`,{className:X.welcomeStep,children:[(0,k.jsx)(`strong`,{children:`3. Chat encrypted`}),` — All messages are E2E encrypted. The server sees only ciphertext.`]})]}),(0,k.jsxs)(`div`,{className:X.welcomeBox,children:[(0,k.jsx)(`div`,{className:X.welcomeBoxTitle,children:`FROM CLI (same channels)`}),(0,k.jsx)(`div`,{className:X.cliCmd,children:`nha collab create "Project X"`}),(0,k.jsx)(`div`,{className:X.cliCmd,children:`nha collab join <invite-code>`}),(0,k.jsx)(`div`,{className:X.cliCmd,children:`nha collab send "Hello from CLI"`}),(0,k.jsx)(`div`,{className:X.cliCmd,children:`nha collab read`})]})]})})]})}var Z={root:`_root_85zy7_2`,header:`_header_85zy7_10`,title:`_title_85zy7_21`,subtitle:`_subtitle_85zy7_28`,headerTabs:`_headerTabs_85zy7_34`,tabBtn:`_tabBtn_85zy7_40`,tabActive:`_tabActive_85zy7_51`,body:`_body_85zy7_58`,editor:`_editor_85zy7_67`,examples:`_examples_85zy7_75`,sectionLabel:`_sectionLabel_85zy7_81`,examplePills:`_examplePills_85zy7_89`,examplePill:`_examplePill_85zy7_89`,editorCols:`_editorCols_85zy7_109`,leftSidebar:`_leftSidebar_85zy7_119`,panel:`_panel_85zy7_128`,panelHeader:`_panelHeader_85zy7_135`,panelTitle:`_panelTitle_85zy7_142`,addBtn:`_addBtn_85zy7_149`,blockLabel:`_blockLabel_85zy7_160`,blockCheck:`_blockCheck_85zy7_170`,authField:`_authField_85zy7_173`,authFieldInput:`_authFieldInput_85zy7_183`,authFieldSelect:`_authFieldSelect_85zy7_193`,authFieldReq:`_authFieldReq_85zy7_204`,removeFieldBtn:`_removeFieldBtn_85zy7_205`,skillsList:`_skillsList_85zy7_208`,skillRow:`_skillRow_85zy7_210`,skillIcon:`_skillIcon_85zy7_218`,skillName:`_skillName_85zy7_220`,skillBadge:`_skillBadge_85zy7_229`,skillBadge_skill:`_skillBadge_skill_85zy7_237`,skillBadge_memory:`_skillBadge_memory_85zy7_238`,skillBadge_provider:`_skillBadge_provider_85zy7_239`,skillBadge_log:`_skillBadge_log_85zy7_240`,skillEmpty:`_skillEmpty_85zy7_242`,skillBtn:`_skillBtn_85zy7_244`,skillsEmpty:`_skillsEmpty_85zy7_246`,snapshotRow:`_snapshotRow_85zy7_249`,snapshotTs:`_snapshotTs_85zy7_258`,snapshotCount:`_snapshotCount_85zy7_259`,snapshotBtn:`_snapshotBtn_85zy7_260`,genStatus:`_genStatus_85zy7_263`,repairStatus:`_repairStatus_85zy7_265`,repairStatusTitle:`_repairStatusTitle_85zy7_266`,repairStatusProg:`_repairStatusProg_85zy7_267`,repairStatusFile:`_repairStatusFile_85zy7_268`,actionRow:`_actionRow_85zy7_271`,actionBtn:`_actionBtn_85zy7_273`,actionBtnIcon:`_actionBtnIcon_85zy7_275`,actionBtnActive:`_actionBtnActive_85zy7_276`,repairBtn:`_repairBtn_85zy7_278`,sandboxBtn:`_sandboxBtn_85zy7_280`,statsBar:`_statsBar_85zy7_282`,rightPanel:`_rightPanel_85zy7_285`,rightTabBar:`_rightTabBar_85zy7_296`,rightTab:`_rightTab_85zy7_296`,rightTabActive:`_rightTabActive_85zy7_313`,repairBar:`_repairBar_85zy7_316`,repairBarRow:`_repairBarRow_85zy7_326`,repairBarIcon:`_repairBarIcon_85zy7_327`,repairBarLabel:`_repairBarLabel_85zy7_328`,repairBarFile:`_repairBarFile_85zy7_329`,repairBarCounter:`_repairBarCounter_85zy7_330`,repairBarTime:`_repairBarTime_85zy7_331`,genBar:`_genBar_85zy7_333`,genBarRow:`_genBarRow_85zy7_343`,genBarRobot:`_genBarRobot_85zy7_344`,robotBob:`_robotBob_85zy7_1`,genBarLabel:`_genBarLabel_85zy7_345`,genBarFile:`_genBarFile_85zy7_346`,genBarCounter:`_genBarCounter_85zy7_347`,genBarTime:`_genBarTime_85zy7_348`,progressTrack:`_progressTrack_85zy7_350`,repairProgress:`_repairProgress_85zy7_351`,genProgress:`_genProgress_85zy7_352`,genDots:`_genDots_85zy7_355`,dot:`_dot_85zy7_356`,dot1:`_dot1_85zy7_357`,dotBounce:`_dotBounce_85zy7_1`,dot2:`_dot2_85zy7_358`,dot3:`_dot3_85zy7_359`,stopBtn:`_stopBtn_85zy7_362`,codeArea:`_codeArea_85zy7_365`,sandboxWrap:`_sandboxWrap_85zy7_366`,sandboxFrame:`_sandboxFrame_85zy7_367`,sandboxEmpty:`_sandboxEmpty_85zy7_368`,sandboxStartBtn:`_sandboxStartBtn_85zy7_369`,codeLayout:`_codeLayout_85zy7_372`,codeRow:`_codeRow_85zy7_381`,ideTabBar:`_ideTabBar_85zy7_389`,ideTab:`_ideTab_85zy7_389`,ideTabActive:`_ideTabActive_85zy7_421`,ideTabError:`_ideTabError_85zy7_426`,ideTabPending:`_ideTabPending_85zy7_427`,ideTabIcon:`_ideTabIcon_85zy7_428`,ideTabName:`_ideTabName_85zy7_429`,ideTabDot:`_ideTabDot_85zy7_430`,codeEditorWrap:`_codeEditorWrap_85zy7_438`,editToggleBtn:`_editToggleBtn_85zy7_449`,editToggleBtnActive:`_editToggleBtnActive_85zy7_460`,codeEditor:`_codeEditor_85zy7_438`,genCursor:`_genCursor_85zy7_482`,cursorBlink:`_cursorBlink_85zy7_1`,diffOverlay:`_diffOverlay_85zy7_491`,diffOverlayHeader:`_diffOverlayHeader_85zy7_500`,diffOverlayActions:`_diffOverlayActions_85zy7_511`,diffAcceptBtn:`_diffAcceptBtn_85zy7_512`,diffRejectBtn:`_diffRejectBtn_85zy7_513`,diffOverlayBody:`_diffOverlayBody_85zy7_514`,diffSame:`_diffSame_85zy7_515`,diffRem:`_diffRem_85zy7_516`,diffAdd:`_diffAdd_85zy7_517`,noFiles:`_noFiles_85zy7_519`,noFilesHero:`_noFilesHero_85zy7_529`,noFilesIcon:`_noFilesIcon_85zy7_536`,noFilesTitle:`_noFilesTitle_85zy7_538`,noFilesTagline:`_noFilesTagline_85zy7_545`,noFilesSteps:`_noFilesSteps_85zy7_550`,noFilesStep:`_noFilesStep_85zy7_550`,noFilesStepNum:`_noFilesStepNum_85zy7_567`,noFilesExamplesHint:`_noFilesExamplesHint_85zy7_581`,noFilesExampleBtn:`_noFilesExampleBtn_85zy7_591`,codeViewer:`_codeViewer_85zy7_605`,codeHeader:`_codeHeader_85zy7_613`,codeFileIcon:`_codeFileIcon_85zy7_626`,codeFileName:`_codeFileName_85zy7_627`,codeFileMeta:`_codeFileMeta_85zy7_628`,fileError:`_fileError_85zy7_630`,fileSyntaxError:`_fileSyntaxError_85zy7_631`,filePending:`_filePending_85zy7_632`,code:`_code_85zy7_365`,codeError:`_codeError_85zy7_647`,codeSyntaxError:`_codeSyntaxError_85zy7_648`,fileSidebar:`_fileSidebar_85zy7_651`,fileSidebarHeader:`_fileSidebarHeader_85zy7_660`,fileTab:`_fileTab_85zy7_670`,fileTabActive:`_fileTabActive_85zy7_686`,fileTabError:`_fileTabError_85zy7_687`,fileTabRow:`_fileTabRow_85zy7_689`,fileTabIcon:`_fileTabIcon_85zy7_690`,fileTabName:`_fileTabName_85zy7_691`,fileTabDir:`_fileTabDir_85zy7_692`,fileTabMeta:`_fileTabMeta_85zy7_693`,projectsList:`_projectsList_85zy7_696`,emptyProjects:`_emptyProjects_85zy7_698`,emptyIcon:`_emptyIcon_85zy7_699`,emptyHint:`_emptyHint_85zy7_700`,projectCard:`_projectCard_85zy7_702`,projectInfo:`_projectInfo_85zy7_703`,projectName:`_projectName_85zy7_704`,projectDesc:`_projectDesc_85zy7_705`,projectMeta:`_projectMeta_85zy7_706`,openBtn:`_openBtn_85zy7_707`,deleteBtn:`_deleteBtn_85zy7_708`,planBanner:`_planBanner_85zy7_711`,planTitle:`_planTitle_85zy7_720`,planText:`_planText_85zy7_721`,planActions:`_planActions_85zy7_722`,planApprove:`_planApprove_85zy7_723`,planReject:`_planReject_85zy7_724`,grepPanel:`_grepPanel_85zy7_727`,grepRow:`_grepRow_85zy7_736`,grepInput:`_grepInput_85zy7_737`,grepBtn:`_grepBtn_85zy7_739`,grepClose:`_grepClose_85zy7_740`,grepCount:`_grepCount_85zy7_741`,grepResults:`_grepResults_85zy7_742`,grepEmpty:`_grepEmpty_85zy7_743`,grepMatch:`_grepMatch_85zy7_744`,grepMatchFile:`_grepMatchFile_85zy7_746`,grepMatchLine:`_grepMatchLine_85zy7_747`,diffPanel:`_diffPanel_85zy7_750`,diffHeader:`_diffHeader_85zy7_759`,diffClose:`_diffClose_85zy7_760`,diffFile:`_diffFile_85zy7_761`,diffSummary:`_diffSummary_85zy7_762`,diffArrow:`_diffArrow_85zy7_763`,diffFileName:`_diffFileName_85zy7_764`,diffAdded:`_diffAdded_85zy7_765`,diffRemoved:`_diffRemoved_85zy7_766`,diffContent:`_diffContent_85zy7_767`,diffInline:`_diffInline_85zy7_770`,diffInlineHeader:`_diffInlineHeader_85zy7_771`,diffRemLine:`_diffRemLine_85zy7_772`,diffAddLine:`_diffAddLine_85zy7_773`,chatPanel:`_chatPanel_85zy7_776`,chatMessages:`_chatMessages_85zy7_785`,chatWelcome:`_chatWelcome_85zy7_787`,chatUser:`_chatUser_85zy7_789`,chatUserBubble:`_chatUserBubble_85zy7_790`,chatAttachPreviews:`_chatAttachPreviews_85zy7_791`,chatAttachBadge:`_chatAttachBadge_85zy7_792`,chatSystem:`_chatSystem_85zy7_794`,chatSystemBubble:`_chatSystemBubble_85zy7_795`,chatSyntaxErr:`_chatSyntaxErr_85zy7_796`,chatAgent:`_chatAgent_85zy7_798`,chatAgentCard:`_chatAgentCard_85zy7_799`,chatAgentHeader:`_chatAgentHeader_85zy7_800`,chatAgentRobot:`_chatAgentRobot_85zy7_801`,chatAgentRobotAnim:`_chatAgentRobotAnim_85zy7_802`,chatAgentLabel:`_chatAgentLabel_85zy7_803`,chatRunningDots:`_chatRunningDots_85zy7_804`,chatAgentText:`_chatAgentText_85zy7_805`,chatToolBadges:`_chatToolBadges_85zy7_806`,toolBadge:`_toolBadge_85zy7_807`,toolBadgeOk:`_toolBadgeOk_85zy7_808`,toolBadgeErr:`_toolBadgeErr_85zy7_809`,cursor:`_cursor_85zy7_811`,blink:`_blink_85zy7_1`,attachPreviews:`_attachPreviews_85zy7_814`,attachBadge:`_attachBadge_85zy7_815`,removeAttachBtn:`_removeAttachBtn_85zy7_816`,projNameRow:`_projNameRow_85zy7_819`,projNameLabel:`_projNameLabel_85zy7_820`,projNameInput:`_projNameInput_85zy7_821`,projActiveRow:`_projActiveRow_85zy7_822`,projActiveName:`_projActiveName_85zy7_823`,chatInputRow:`_chatInputRow_85zy7_826`,attachLabel:`_attachLabel_85zy7_827`,chatTextarea:`_chatTextarea_85zy7_828`,chatSendCol:`_chatSendCol_85zy7_831`,chatSendBtn:`_chatSendBtn_85zy7_832`,chatStopBtn:`_chatStopBtn_85zy7_834`,modalOverlay:`_modalOverlay_85zy7_837`,modal:`_modal_85zy7_837`,modalHeader:`_modalHeader_85zy7_859`,modalTitle:`_modalTitle_85zy7_860`,modalClose:`_modalClose_85zy7_861`,modalBody:`_modalBody_85zy7_863`,modalRow:`_modalRow_85zy7_865`,modalField:`_modalField_85zy7_866`,modalLabel:`_modalLabel_85zy7_867`,modalLabelRow:`_modalLabelRow_85zy7_868`,modalSelect:`_modalSelect_85zy7_870`,modalInput:`_modalInput_85zy7_871`,modalHint:`_modalHint_85zy7_874`,modalAiBox:`_modalAiBox_85zy7_876`,modalAiRow:`_modalAiRow_85zy7_877`,modalAiDesc:`_modalAiDesc_85zy7_878`,modalAiBtn:`_modalAiBtn_85zy7_879`,modalContentArea:`_modalContentArea_85zy7_882`,logView:`_logView_85zy7_885`,modalFooter:`_modalFooter_85zy7_887`,modalCancelBtn:`_modalCancelBtn_85zy7_888`,modalSaveBtn:`_modalSaveBtn_85zy7_889`},en=[{name:`MySaaS`,desc:`Full-stack SaaS web application with Node.js/Express backend and vanilla JS frontend.
531
+
532
+ BACKEND (server.js + routes/):
533
+ - Express server with helmet, cors, rate-limiting, compression middleware
534
+ - JWT authentication: POST /api/auth/register, /api/auth/login, /api/auth/refresh, /api/auth/logout
535
+ - Protected routes middleware checking Bearer token
536
+ - User model with bcrypt password hashing stored in JSON file DB (no external DB needed)
537
+ - Stripe-style subscription routes: GET /api/billing/plans, POST /api/billing/subscribe
538
+ - Dashboard API: GET /api/dashboard/stats (returns mock metrics), GET /api/user/profile
539
+ - Error handling middleware with proper HTTP status codes
540
+
541
+ FRONTEND (public/):
542
+ - index.html: Marketing landing page — sticky glass-morphism nav with logo + "Login" + "Start Free" buttons, animated gradient hero (#6366f1→#8b5cf6→#06b6d4) with headline "Ship faster. Scale smarter." + subheadline + 2 CTA buttons, features grid (6 cards with SVG icons: ⚡Speed, 🔒Security, 📊Analytics, 🤖AI, 🌍Global, 💬Support), pricing section (3 cards: Free/€0 · Pro/€29/mo · Enterprise/custom, Pro card highlighted with gradient border), testimonials carousel (3 quotes with avatar initials), FAQ accordion (5 items), footer with 4 column links + social icons
543
+ - dashboard.html: Protected SPA dashboard — sidebar nav with icons (Dashboard, Analytics, Users, Billing, Settings, Logout), top bar with user avatar + notifications bell, main content: KPI cards row (Total Users, MRR, Churn Rate, Active Sessions all with trend arrows), line chart (Chart.js), recent activity feed, quick actions panel
544
+ - login.html: Split-screen auth page — left panel gradient background with product tagline, right panel with tabbed Login/Register form, social login buttons (Google/GitHub), "Forgot password" link, real-time form validation with inline error messages
545
+ - public/css/main.css: CSS custom properties (--primary, --surface, --text, --border, --radius), dark theme by default, full responsive (mobile breakpoints at 768px, 480px), smooth transitions, glass-morphism card style (backdrop-filter: blur), custom scrollbar
546
+ - public/css/animations.css: keyframes for fadeInUp, slideInRight, pulse, shimmer loading skeleton, gradient-shift for hero background
547
+ - public/js/app.js: SPA router (hash-based), auth token management (localStorage), fetch wrapper with auto-refresh token on 401, Intersection Observer for scroll animations, mobile menu toggle
548
+ - public/js/auth.js: register/login/logout functions, form validation, error display, redirect after auth
549
+ - public/js/dashboard.js: load dashboard stats from API, render Chart.js line chart, populate activity feed, handle logout
550
+
551
+ CONFIG: package.json with all dependencies, .env.example with JWT_SECRET/PORT/NODE_ENV, README with setup instructions`},{name:`MyShop`,desc:`Full-stack e-commerce platform with Express backend and rich frontend.
552
+
553
+ BACKEND:
554
+ - server.js: Express + cors + helmet + morgan logging + static file serving
555
+ - routes/products.js: GET /api/products (with ?category=&sort=&search= query params), GET /api/products/:id, POST /api/products (admin), PUT/DELETE
556
+ - routes/cart.js: session-based cart — GET /api/cart, POST /api/cart/add, PUT /api/cart/update, DELETE /api/cart/remove, POST /api/cart/clear
557
+ - routes/orders.js: POST /api/orders/checkout (validates cart, creates order, returns order ID), GET /api/orders/:id
558
+ - models/products.js: 24 hardcoded products across 6 categories (Electronics, Clothing, Home, Books, Sports, Beauty) each with id/name/price/oldPrice/rating/reviews/image(emoji)/stock/badge(New/Sale/Hot)
559
+ - middleware/auth.js: simple API key middleware for admin routes
560
+
561
+ FRONTEND:
562
+ - index.html: Full e-commerce homepage — sticky nav with logo, search bar (live search on keyup), cart icon with animated badge counter, hamburger mobile menu. Hero: full-width banner with gradient + "Summer Sale — Up to 50% off" + CTA. Category strip: 6 clickable filter pills with emoji icons. Featured products: responsive grid (4 col desktop, 2 mobile) of product cards with image/name/rating stars/price with strikethrough old price/Add to Cart button with animation/wishlist heart toggle. "Load More" button. Promo banner: "Free shipping over €50". Newsletter signup with email input.
563
+ - product.html: Product detail page — breadcrumb, image gallery (main + 4 thumbnails), product info (name, rating, price, stock status), quantity selector, Add to Cart + Buy Now buttons, tabs (Description/Specifications/Reviews), related products grid
564
+ - cart.html: Cart page — line items with image/name/price/quantity stepper/remove button, order summary sidebar (subtotal/shipping/discount/total), promo code input, "Proceed to Checkout" button, "Continue Shopping" link, empty cart state
565
+ - checkout.html: Multi-step checkout — Step 1: Shipping address form (name/email/address/city/zip/country), Step 2: Payment method (Credit Card mock form with card number formatter, PayPal button), Step 3: Order confirmation with order number
566
+ - public/css/main.css: Full e-commerce design system — product card hover effects (translateY + shadow), star rating CSS, badge styles (New=green, Sale=red, Hot=orange), cart animation, responsive grid, dark/light mode toggle
567
+ - public/js/app.js: cart state management (add/remove/update quantity, persist to localStorage), live product filtering by category, search functionality, wishlist toggle, cart badge update animation, fetch products from API
568
+ - public/js/checkout.js: multi-step form navigation, credit card number formatting (spaces every 4 digits), form validation, order submission, confirmation display`},{name:`MyBlog`,desc:`Full-stack blog platform with markdown support, categories, tags, and comments.
569
+
570
+ BACKEND:
571
+ - server.js: Express + marked (markdown parser) + hljs (syntax highlighting) + RSS feed endpoint
572
+ - routes/posts.js: GET /api/posts (paginated, ?page=&category=&tag=&search=), GET /api/posts/:slug, POST/PUT/DELETE (admin auth)
573
+ - routes/comments.js: GET /api/posts/:slug/comments, POST (with name/email/content), DELETE (admin)
574
+ - routes/admin.js: POST /api/admin/login, GET /api/admin/posts, POST /api/admin/posts (create with markdown body), PUT, DELETE
575
+ - models/posts.js: 12 hardcoded blog posts in 4 categories (Tech, Design, Business, Life) with full markdown content, slug, author, date, readTime, tags, coverEmoji
576
+ - Middleware: markdown-to-HTML rendering, excerpt generation (first 160 chars), reading time calc
577
+
578
+ FRONTEND:
579
+ - index.html: Magazine-style homepage — sticky nav with logo + category links + search icon + dark mode toggle. Hero: featured post card (full-width with gradient overlay, category badge, title, excerpt, author + date + read time). Posts grid: masonry-style 3-column layout with post cards (cover emoji in colored square, category pill, title, excerpt, author avatar initials + name + date). Sidebar: "Trending" list (5 posts with rank numbers), Tag cloud (20 tags with size based on frequency), Newsletter signup, About widget. Pagination with numbered pages.
580
+ - post.html: Full article page — hero image area (large emoji + gradient bg), article header (category/title/subtitle/author card with avatar/date/readTime/share buttons), article body with styled markdown (h2 anchors, code blocks with syntax highlighting, blockquotes styled, inline code), "In this article" TOC sidebar (auto-generated from h2/h3), Comments section (threaded list + new comment form with name/email/message), Related posts grid (3 cards)
581
+ - admin.html: Minimal CMS — login form, then: posts list table (title/date/category/status/edit/delete), "New Post" button opens split-view editor (textarea left + live preview right with marked.js), category/tags/slug fields, publish toggle
582
+ - public/css/main.css: Editorial design system — serif font for headings (Georgia/Times), readable line-height 1.8, max-width 720px for article body, syntax highlight theme (dark), category color mapping, dark mode with prefers-color-scheme + toggle class
583
+ - public/js/app.js: dark mode toggle (localStorage persist), search overlay (keyboard shortcut /), category filter, lazy load images, smooth scroll ToC navigation, reading progress bar at top of article page`},{name:`MyPortfolio`,desc:`Developer portfolio — single-page app with animations and a working contact form backend.
584
+
585
+ BACKEND:
586
+ - server.js: Express serving static files + contact form endpoint
587
+ - routes/contact.js: POST /api/contact — validates name/email/message, rate-limits to 3/hour per IP, saves to contacts.json, returns success/error JSON
588
+ - routes/projects.js: GET /api/projects — returns 8 hardcoded project objects with title/description/techStack[]/githubUrl/liveUrl/image(emoji)/featured
589
+
590
+ FRONTEND (single HTML page + separate CSS/JS files):
591
+ - index.html: Full single-page portfolio — (1) Sticky nav: logo initials in gradient circle, links that highlight on scroll (About/Work/Skills/Contact), dark mode toggle, hamburger mobile. (2) Hero: full-viewport, name with gradient text effect, animated typewriter cycling through ["Full-Stack Developer", "UI/UX Designer", "Open Source Contributor", "Problem Solver"], subtext, two buttons (View Work → scroll / Download CV → fake PDF link), animated floating code snippets in background (CSS only). (3) About: two-column — photo placeholder (gradient circle with initials + CSS decoration), bio text + 4 stat counters (Years/Projects/Clients/Coffee) that count up on scroll into view. (4) Work: filter tabs (All/Frontend/Backend/Mobile), responsive project grid, each card has emoji image, title, description, 3 tech badges, GitHub + Live links. (5) Skills: grouped sections — Frontend (HTML/CSS/JS/React/Vue each with animated progress bar %), Backend (Node/Python/Go/SQL), Tools (Git/Docker/AWS/Figma), Languages (EN/IT/ES with flag). (6) Experience: vertical timeline — 4 entries with company, role, date range, bullet points, alternating left/right layout. (7) Contact: two-column — contact info (email/location/availability status green dot), social links (GitHub/LinkedIn/Twitter/Dribbble), contact form (name/email/subject/message textarea + send button with loading state). (8) Footer: minimal — copyright, back-to-top button.
592
+ - public/css/main.css: CSS custom properties for full theming, dark/light mode, smooth transitions on all interactive elements, gradient definitions, card hover effects (lift + shadow), timeline CSS, progress bar animations
593
+ - public/css/animations.css: Intersection Observer triggered classes (.visible), fadeInUp/fadeInLeft/fadeInRight keyframes, typewriter cursor blink, counter increment CSS trick, floating animation for hero decorations
594
+ - public/js/app.js: typewriter effect (array cycling with cursor), scroll-triggered animations (IntersectionObserver), counter animation (requestAnimationFrame), project filter (show/hide by category), dark mode toggle, active nav link on scroll (IntersectionObserver per section), contact form submit (fetch POST to backend, show success/error message, loading spinner on button), mobile menu`},{name:`MyRestaurant`,desc:`Restaurant website with online reservation system and menu management.
595
+
596
+ BACKEND:
597
+ - server.js: Express + nodemailer (mock) for reservation confirmation emails
598
+ - routes/reservations.js: POST /api/reservations (name/email/phone/date/time/guests/notes, validate date is future and time in range 12:00-22:00, check availability mock, save to reservations.json, return confirmation number), GET /api/reservations/availability?date=&guests= (returns available time slots)
599
+ - routes/menu.js: GET /api/menu (full menu grouped by category), GET /api/menu/:category
600
+ - models/menu.js: 40 menu items across 5 categories — Antipasti (8), Primi (8), Secondi (8), Contorni (6), Dolci (5), Bevande (5) — each with name/description/price/allergens[]/isVegetarian/isGlutenFree/emoji
601
+
602
+ FRONTEND:
603
+ - index.html: Premium restaurant website — (1) Full-screen hero: video-style background (CSS animated gradient in warm amber/brown tones), centered logo + tagline "Cucina Autentica dal 1987", reservation CTA button that opens modal. (2) Sticky nav: logo centered, links left/right symmetrically (Menu/Story/Gallery / Reservations/Events/Contact), transparent on hero, solid dark on scroll. (3) Story section: two-column layout — left: chef photo placeholder (sepia gradient + fork/knife icons), right: story text with pull quote, founding year counter. (4) Menu section: tab navigation (Antipasti/Primi/Secondi/Dolci/Bevande), 2-column menu list with item name + description + price, vegetarian/GF badges, "Full Menu" PDF button. (5) Reservation form embedded (name/phone/date picker/time select/guests 1-10/special requests), real-time availability check on date+guests change. (6) Gallery: CSS masonry grid 3x3 with hover overlay (category label + zoom icon), lightbox on click. (7) Hours & Location: two-column — opening hours table (Mon-Sun with times, today highlighted), Google Maps embed placeholder + address/phone/email. (8) Footer: warm dark background, logo, newsletter, social icons (Instagram/Facebook/TripAdvisor).
604
+ - public/css/main.css: Warm luxury design system — amber/gold palette (#d4a853, #8b6914), serif fonts (Georgia for headings), elegant spacing, menu item line styles, reservation form dark theme, gallery hover effects, mobile-first responsive`},{name:`MyJobBoard`,desc:`Full-stack job board with search, filters, applications, and company profiles.
605
+
606
+ BACKEND:
607
+ - server.js: Express + full REST API
608
+ - routes/jobs.js: GET /api/jobs (with ?q=&location=&type=&category=&salary_min=&page=&limit=), GET /api/jobs/:id, POST /api/jobs (company auth), PUT/DELETE. Returns paginated results with total count.
609
+ - routes/companies.js: GET /api/companies/:id, POST /api/companies/register, PUT (update profile)
610
+ - routes/applications.js: POST /api/applications (jobId/name/email/coverLetter/resumeText), GET /api/applications/job/:id (company only)
611
+ - models/jobs.js: 24 hardcoded jobs across 6 categories (Engineering/Design/Marketing/Sales/Data/DevOps), each with title/company/location/type(Remote/Hybrid/Onsite)/salary(€K range)/posted(relative date)/description/requirements[]/benefits[]/companyLogo(emoji)/featured/urgent badges
612
+ - Middleware: search text matching (title+description), salary range filter, pagination logic
613
+
614
+ FRONTEND:
615
+ - 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.
616
+ - 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)
617
+ - 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
618
+ - 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`}],tn=[{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:`✉️`}],nn={js:`📄`,ts:`📄`,css:`🎨`,html:`🌐`,json:`{`,md:`📑`,sql:`🗂`,env:`🔐`,conf:`⚙`,lock:`🔒`};function rn(e){return nn[e.split(`.`).pop()?.toLowerCase()??``]??`📄`}function an(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 on(e){return e===`memory`?`🧠`:e===`provider`?`🤖`:e===`log`?`📄`:`📋`}function sn(){let e=P(),[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)(!1),[w,ee]=(0,_.useState)(!1),[te,ne]=(0,_.useState)(0),[T,re]=(0,_.useState)(0),[ie,O]=(0,_.useState)(``),[ae,A]=(0,_.useState)({fi:0,total:0,name:``}),[j,oe]=(0,_.useState)(null),[se,M]=(0,_.useState)([]),[ce,N]=(0,_.useState)(``),[F,le]=(0,_.useState)(!1),[ue,de]=(0,_.useState)([]),[fe,I]=(0,_.useState)(null),[pe,me]=(0,_.useState)([]),[he,ge]=(0,_.useState)(!1),[L,_e]=(0,_.useState)(null),[ve,ye]=(0,_.useState)([]),[R,z]=(0,_.useState)(!1),[be,xe]=(0,_.useState)(``),[Se,Ce]=(0,_.useState)([]),[we,Te]=(0,_.useState)([]),[Ee,De]=(0,_.useState)([]),[Oe,ke]=(0,_.useState)(null),[B,Ae]=(0,_.useState)(`0s`),[je,Me]=(0,_.useState)(`0s`),Ne=(0,_.useRef)(0),Pe=(0,_.useRef)(0),Fe=(0,_.useRef)(null),Ie=(0,_.useRef)(null),Le=(0,_.useRef)(null),Re=(0,_.useRef)(null),ze=(0,_.useRef)(null),Be=(0,_.useRef)(null);function Ve(e){let t=Math.floor((Date.now()-e)/1e3),n=Math.floor(t/60);return(n>0?`${n}m `:``)+`${t%60}s`}(0,_.useEffect)(()=>(S||w?Fe.current=setInterval(()=>{S&&Ae(Ve(Ne.current)),w&&Me(Ve(Pe.current))},1e3):Fe.current&&=(clearInterval(Fe.current),null),()=>{Fe.current&&clearInterval(Fe.current)}),[S,w]);function He(){Le.current&&(Le.current.scrollTop=Le.current.scrollHeight)}(0,_.useEffect)(()=>{He()},[se]),(0,_.useEffect)(()=>{a&&p.length>0&&!he&&(ge(!0),E(`/api/studio/webcraft/skills/${encodeURIComponent(a)}`).then(e=>{e?.skills&&me(e.skills)}).catch(()=>{}))},[a,p.length,he]);async function Ue(e,t){if(S||!e||e.length<5)return;C(!0),m([]),g(0),A({fi:0,total:0,name:``}),Ne.current=Date.now(),Ae(`0s`),Ie.current=new AbortController;let n=Date.now();try{let r=await fetch(`/api/studio/webcraft/generate`,{method:`POST`,headers:{"Content-Type":`application/json`},signal:Ie.current.signal,body:JSON.stringify({projectName:t,description:e,blocks:l,authFields:d})});if(!r.ok||!r.body){C(!1);return}let i=r.body.getReader(),a=new TextDecoder,o=``,s=[];for(;;){let{done:e,value:t}=await i.read();if(e)break;o+=a.decode(t,{stream:!0});let r=o.split(`
531
619
 
532
620
  `);o=r.pop()??``;for(let e of r){let t=e.replace(/^data: /,``).trim();if(t)try{let e=JSON.parse(t);if(e.type===`processing`||e.type===`planning`)A(t=>({...t,name:e.type===`planning`?`📋 Pianificazione struttura...`:e.msg||`Avvio...`}));else if(e.type===`file_start`)s.push({name:e.name,content:``,_pending:!0}),m([...s]),A({fi:e.fi,total:e.total,name:e.name}),g(s.length-1);else if(e.type===`file_chunk`){let t=s.find(t=>t.name===e.name);t&&(t.content+=e.chunk,t._pending=!1),m([...s])}else if(e.type===`file_done`){let t=s.find(t=>t.name===e.name);t&&(t._pending=!1,e.syntaxError&&(t._syntaxError=e.syntaxError)),m([...s]),A({fi:e.fi,total:e.total,name:e.name})}else if(e.type===`file_error`){let t=s.find(t=>t.name===e.name);t&&(t._error=!0,t._pending=!1),m([...s])}else e.type===`done`&&(oe({seconds:Math.round((Date.now()-n)/1e3),tokIn:e.tokIn??0,tokOut:e.tokOut??0,files:s.length}),C(!1),ge(!1),me([]),s.some(e=>e._error||e._syntaxError)?setTimeout(()=>ze.current?.(),800):setTimeout(()=>Be.current?.(),800))}catch{}}}}catch(e){e.name!==`AbortError`&&M(t=>[...t,{role:`system`,text:`Errore generazione: `+e.message}]),C(!1)}}async function We(){let e=ce.trim();if(!(a&&p.length>0)){if(!e||e.length<5)return;let t=a||`MyProject`;o(t),c(e),N(``),await Ue(e,t);return}if(!e&&ue.length===0||F||S)return;let t=[...ue];if(de([]),N(``),e.toLowerCase().startsWith(`/plan `)||e.toLowerCase().startsWith(`piano: `)){let t=e.replace(/^\/plan[ ]*/i,``).replace(/^piano:[ ]*/i,``);M(t=>[...t,{role:`user`,text:e}]),await Ge(`[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}M(n=>[...n,{role:`user`,text:e,attachments:t}]),await Ge(e,null,t)}async function Ge(e,t,n){if(F)return;le(!0);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){M(e=>[...e,{role:`agent`,text:`Errore: ${i.status}`,tools:[]}]),le(!1);return}let o={role:`agent`,text:``,tools:[]};M(e=>[...e,o]);let s=i.body.getReader(),c=new TextDecoder,l=``,u=!1;for(;;){let{done:e,value:n}=await s.read();if(e)break;l+=c.decode(n,{stream:!0});let i=l.split(`
533
621
 
@@ -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-Duwu_0IN.js"></script>
11
+ <script type="module" crossorigin src="/assets/index-DSF5tD3Z.js"></script>
12
12
  <link rel="stylesheet" crossorigin href="/assets/index-CIKvCFm_.css">
13
13
  </head>
14
14
  <body>