@mmmbuto/nexuscrew 0.8.56 → 0.8.57

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/CHANGELOG.md CHANGED
@@ -4,6 +4,55 @@ All notable changes to NexusCrew are tracked here.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.8.57 — 2026-08-11 — "Three Wires, One Subscription"
8
+
9
+ - **OpenCode Go is a managed provider on Claude Code, Codex-VL and Pi.** One
10
+ subscription, one environment variable (`OPENCODE_API_KEY`), three profiles —
11
+ because the gateway is not one uniform API but three: Anthropic Messages,
12
+ OpenAI Responses and Chat Completions. Each client gets the wire it actually
13
+ speaks, with `deepseek-v4-flash` as the default model on all three.
14
+
15
+ - **The model lists were measured, not copied from the docs.** The published
16
+ endpoint table assigns each model a single wire, but the gateway translates
17
+ between them, so the table understates what works and overstates it in
18
+ places. Every one of the 25 advertised model IDs was tried on all three
19
+ wires, and a second pass re-tried the failures with sane parameters to tell a
20
+ wire refusal apart from a request the gateway forwarded empty. What went into
21
+ the catalog is that matrix: 12 models on Messages, 6 on Responses, 21 on
22
+ Chat. Three IDs the live catalog still advertises are dead upstream — two
23
+ deprecated, one unavailable — and are in none of the lists.
24
+
25
+ - **The Claude profile sends the key as `x-api-key`, not as a bearer token.**
26
+ This gateway's Messages endpoint answers `401 Missing API key` to
27
+ `Authorization: Bearer`, which is the shape every other gateway in the
28
+ catalog uses. Copying the neighbouring profile would have produced a cell
29
+ that fails at first use with an authentication error and no obvious cause.
30
+ A test breaks on exactly that substitution.
31
+
32
+ - **The URL roots differ by client and both are easy to get wrong.** Claude
33
+ receives the root without `/v1`, because the client appends `/v1/messages`;
34
+ Codex-VL receives the base *with* `/v1` and appends `/responses`. A doubled
35
+ `/v1` is a 404.
36
+
37
+ - **The Pi profile requires the key instead of delegating it.** Auth delegation
38
+ belongs to the providers Pi resolves from its own login store. This one
39
+ exists only as a generated extension whose API key is an environment
40
+ reference, so delegating would have reported a cell as configured while no
41
+ key existed anywhere — a failure deferred to first use. It now fails closed
42
+ before launch, like the other extension-based provider.
43
+
44
+ - **No context window is declared for these models.** Their real limits on this
45
+ provider have not been measured, and an invented number would quietly become
46
+ the threshold at which cells compact.
47
+
48
+ - **What is not verified yet.** These profiles are proven at the protocol
49
+ level: every advertised pair was exercised against the live API. They have
50
+ not been exercised inside a running cell, so streaming, tool calls,
51
+ interleaved reasoning and resume remain unverified. The provider also does
52
+ not expose `/v1/messages/count_tokens`, which Claude Code uses for context
53
+ accounting; whether the client degrades quietly or reports an error is not
54
+ yet known.
55
+
7
56
  ## 0.8.56 — 2026-08-08 — "The Catalog Learns Its Order"
8
57
 
9
58
  - **Grok Build is a managed client (`grok.native`).** xAI's `grok` TUI joins
@@ -90,4 +90,4 @@ Minimum version required to store current data is: `+H+`.
90
90
  `).filter(o=>o!==""),promptMode:e.promptMode};return e.modelFlag&&(s.model={flag:e.modelFlag,value:e.modelValue||""}),e.promptMode==="flag"&&(s.promptFlag=e.promptFlag),t&&(s.env=Object.fromEntries(e.envRows.filter(o=>!o.remove&&o.key).map(o=>[o.key,o.value]))),s}function fs({children:e,onClose:t,label:n,error:s=""}){const o=N.useRef(null),a=N.useRef(null),u=N.useRef(t);return u.current=t,N.useEffect(()=>{const h=document.activeElement,p=o.current,m=()=>Array.from((p==null?void 0:p.querySelectorAll('button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [href], [tabindex]:not([tabindex="-1"])'))||[]).filter(w=>w.offsetParent!==null),v=requestAnimationFrame(()=>{var w;return(w=m()[0]||p)==null?void 0:w.focus({preventScroll:!0})}),y=w=>{var x;if(w.key==="Escape"){w.preventDefault(),(x=u.current)==null||x.call(u);return}if(w.key!=="Tab")return;const b=m();if(!b.length){w.preventDefault(),p==null||p.focus();return}const S=b[0],C=b[b.length-1];w.shiftKey&&document.activeElement===S?(w.preventDefault(),C.focus()):!w.shiftKey&&document.activeElement===C&&(w.preventDefault(),S.focus())};return document.addEventListener("keydown",y),()=>{cancelAnimationFrame(v),document.removeEventListener("keydown",y),h&&h.isConnected&&typeof h.focus=="function"&&h.focus({preventScroll:!0})}},[]),N.useEffect(()=>{s&&requestAnimationFrame(()=>{var h;return(h=a.current)==null?void 0:h.scrollIntoView({block:"nearest"})})},[s]),l.jsx("div",{className:"nc-fleet-modal",role:"presentation",onMouseDown:h=>{h.target===h.currentTarget&&t()},children:l.jsxs("div",{ref:o,className:"nc-fleet-modal-dialog",role:"dialog","aria-modal":"true","aria-label":n||f("settings"),tabIndex:-1,children:[e,s&&l.jsx("div",{ref:a,className:"nc-err nc-fleet-modal-error",role:"alert","aria-live":"assertive",children:s})]})})}function $d({token:e,targets:t=[],readonly:n=!1,onPower:s,onImport:o}){const[a,u]=N.useState([]),[h,p]=N.useState(0);N.useEffect(()=>{let x=!0;async function R(){const $=[{route:[],label:f("local")}].concat((t||[]).map(K=>({route:Array.isArray(K.route)?K.route:[],label:K.label||(K.route||[]).join(" › ")}))),B=await Promise.all($.map(async K=>{const V={...K,available:!1,readonly:!1,capabilities:[],provider:null,cells:[],unmanaged:[],err:""};try{const Y=await bs(e,K.route);V.available=!!Y.available,V.capabilities=Y.capabilities||[],V.provider=Y.provider||null,V.cells=(Y.cells||[]).map(te=>({...te,route:K.route}));try{V.readonly=!!(await ef(e,K.route)).readonlyDefault}catch{}try{const te=await Zh(e,K.route),Q=new Set(V.cells.map(J=>J.tmuxSession).filter(Boolean));V.unmanaged=(te.sessions||[]).filter(J=>J&&!Q.has(J.name))}catch{}}catch(Y){V.err=String(Y&&Y.message||Y)}return V}));x&&u(B)}R();const E=setInterval(R,6e3);return()=>{x=!1,clearInterval(E)}},[e,t,h]);const m=(x,R)=>Array.isArray(x.capabilities)&&x.capabilities.includes(R)&&!n&&!x.readonly,v=()=>p(x=>x+1),y=(x,R)=>{s&&s({...x,route:R})},w=(x,R)=>{s&&s({...x,route:R})},b=async(x,R)=>{try{await $o(e,x.cell,R)}catch{}v()},S=async(x,R)=>{if(window.confirm(f("fleet-remove-cell").replace("{id}",x.cell))){try{await ey(e,x.cell,!0,R)}catch{}v()}},C=async(x,R)=>{if(window.confirm(f("terminate-confirm").replace("{name}",x.name))){try{await Qh(e,x.name,R)}catch{}v()}};return l.jsxs("div",{className:"nc-fleet-inventory",children:[l.jsxs("div",{className:"nc-fleet-section-head",children:[l.jsx("b",{children:f("fleet-inventory")}),l.jsx("small",{children:f("fleet-inventory-help")})]}),a.map(x=>{const R=x.route.length?x.route.join("/"):"local";return l.jsxs("div",{className:"nc-fleet-pos",children:[l.jsxs("div",{className:"nc-fleet-pos-title",children:[l.jsx("span",{className:`dot ${x.available?"on":"warn"}`}),l.jsx("b",{children:x.label}),l.jsx("small",{children:x.available?`${x.cells.length} ${f("fleet-cells")} · ${x.unmanaged.length} ${f("fleet-tmux")}`:x.err||f("fleet-not-available")})]}),x.cells.map(E=>l.jsxs("div",{className:"nc-fleet-item nc-fleet-cell",children:[l.jsxs("span",{children:[l.jsx("b",{children:E.cell}),l.jsx("small",{children:`${E.engine||""}${E.key?`·${E.key}`:""}${E.active?"":` · ${f("cell-off")}`}`})]}),l.jsxs("span",{className:"nc-fleet-cell-actions",children:[E.active&&m(x,"down")&&l.jsx("button",{className:"nc-btn ghost",title:f("power-off"),onClick:()=>w(E,x.route),children:f("stop")}),!E.active&&m(x,"up")&&l.jsx("button",{className:"nc-btn ghost",title:f("power-on"),onClick:()=>y(E,x.route),children:f("start")}),m(x,"restart")&&E.active&&l.jsx("button",{className:"nc-btn ghost",title:f("restart"),onClick:()=>b(E,x.route),children:f("restart")}),m(x,"remove")&&l.jsx("button",{className:"nc-btn danger",title:f("delete"),onClick:()=>S(E,x.route),children:"×"})]})]},`${R}:${E.cell}`)),x.unmanaged.map(E=>l.jsxs("div",{className:"nc-fleet-item nc-fleet-unmanaged",children:[l.jsxs("span",{children:[l.jsx("b",{children:E.name}),l.jsx("small",{children:f("fleet-tmux")})]}),l.jsxs("span",{className:"nc-fleet-cell-actions",children:[m(x,"import")&&o&&l.jsx("button",{className:"nc-btn ghost",title:f("import-as-cell"),onClick:()=>o(E,x.route),children:f("import-as-cell")}),l.jsx("button",{className:"nc-btn danger",title:f("terminate"),onClick:()=>C(E,x.route),children:"×"})]})]},`${R}:u:${E.name}`)),x.available&&x.cells.length===0&&x.unmanaged.length===0&&l.jsx("div",{className:"nc-empty",children:f("fleet-inventory-empty")})]},R)})]})}function aj({cells:e=[],engines:t=[],models:n=[],busy:s,canRestore:o=!1,onRestore:a,onClose:u}){const[h,p]=N.useState("export"),[m,v]=N.useState([]),[y,w]=N.useState(()=>new Set(e.map(T=>T.id))),[b,S]=N.useState(()=>new Set(t.map(T=>T.id))),[C,x]=N.useState([]),[R,E]=N.useState([]),[$,B]=N.useState(""),K=new Set(t.map(T=>T.id)),V=new Set(e.map(T=>T.id)),Y=(T,F)=>T(k=>{const I=new Set(k);return I.has(F)?I.delete(F):I.add(F),I}),te=()=>{const T=ej(e,y,t,b,new Date,n);if(T.ok===!1){B(f(`fleet-backup-${T.error}`));return}const F=e.filter(W=>y.has(W.id)).length,k=t.filter(W=>b.has(W.id)).length;if(T.cells.length!==F){B(f("fleet-backup-invalid-cell"));return}if(T.engines.length!==k){B(f("fleet-backup-invalid-engine"));return}if(!T.cells.length&&!T.engines.length){B(f("fleet-backup-select-one"));return}const I=new Blob([`${JSON.stringify(T,null,2)}
91
91
  `],{type:"application/json"}),D=URL.createObjectURL(I),M=document.createElement("a");M.href=D,M.download=`nexuscrew-fleet-${new Date().toISOString().slice(0,10)}.json`,document.body.appendChild(M),M.click(),M.remove(),setTimeout(()=>URL.revokeObjectURL(D),0),B("")},Q=async T=>{if(B(""),x([]),E([]),!!T){if(T.size>1024*1024){B(f("fleet-backup-too-large"));return}try{const F=tj(await T.text());if(!F.ok){B(f(`fleet-backup-${F.error}`));return}v(Array.isArray(F.models)?F.models:[]);const k=new Set(F.engines.map(I=>I.id));E(F.engines.map(I=>({engine:I,exists:K.has(I.id),selected:!K.has(I.id)}))),x(F.cells.map(I=>{const D=K.has(I.engine)||k.has(I.engine),M=V.has(I.id);return{cell:I,engine:D?I.engine:"",selected:D&&!M,exists:M}}))}catch(F){B(String(F.message||F))}}},J=(T,F)=>x(k=>k.map((I,D)=>D===T?{...I,...F}:I)),H=(T,F)=>E(k=>k.map((I,D)=>D===T?{...I,...F}:I)),L=new Set([...K,...R.filter(T=>T.selected).map(T=>T.engine.id)]),A=C.filter(T=>T.selected&&T.engine&&L.has(T.engine)),z=R.filter(T=>T.selected),O=[...new Map([...t.map(T=>[T.id,T.label||T.id]),...R.filter(T=>T.selected).map(T=>[T.engine.id,T.engine.label||T.engine.id])]).entries()];return l.jsxs("div",{className:"nc-set-form nc-fleet-form nc-backup-dialog",children:[l.jsx("b",{children:f("fleet-backup")}),l.jsx("small",{children:f("fleet-backup-help")}),l.jsxs("div",{className:"nc-set-tabs nc-backup-tabs",children:[l.jsx("button",{type:"button",className:`nc-set-tabbtn${h==="export"?" on":""}`,onClick:()=>{p("export"),B("")},children:f("fleet-backup-export")}),l.jsx("button",{type:"button",className:`nc-set-tabbtn${h==="import"?" on":""}`,disabled:!o,title:o?"":f("fleet-backup-restore-unavailable"),onClick:()=>{p("import"),B("")},children:f("fleet-backup-import")})]}),h==="export"?l.jsxs(l.Fragment,{children:[l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>{w(new Set(e.map(T=>T.id))),S(new Set(t.map(T=>T.id)))},children:f("select-all")}),l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>{w(new Set),S(new Set)},children:f("select-none")})]}),l.jsxs("div",{className:"nc-backup-list",children:[l.jsx("b",{children:f("fleet-engines")}),t.map(T=>{var F;return l.jsxs("label",{className:"nc-check nc-backup-row",children:[l.jsx("input",{type:"checkbox",checked:b.has(T.id),onChange:()=>Y(S,T.id)}),l.jsxs("span",{children:[l.jsx("b",{children:T.label||T.id}),l.jsxs("small",{children:[T.id,(F=T.envKeys)!=null&&F.length?` · ${T.envKeys.length} ${f("fleet-backup-env-names")}`:""]})]})]},T.id)}),l.jsx("b",{children:f("fleet-cells")}),e.map(T=>l.jsxs("label",{className:"nc-check nc-backup-row",children:[l.jsx("input",{type:"checkbox",checked:y.has(T.id),onChange:()=>Y(w,T.id)}),l.jsxs("span",{children:[l.jsx("b",{children:T.id}),l.jsxs("small",{children:[T.engine," · ",f("fleet-system-prompt")," ",(T.prompt||"").length," ",f("characters")]})]})]},T.id)),!e.length&&!t.length&&l.jsx("div",{className:"nc-empty",children:f("fleet-backup-empty")})]}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:u,children:f("cancel")}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:!y.size&&!b.size,onClick:te,children:f("fleet-backup-download")})]})]}):l.jsxs(l.Fragment,{children:[l.jsx("input",{type:"file",accept:"application/json,.json",disabled:s,onChange:T=>Q(T.target.files&&T.target.files[0])}),l.jsx("small",{children:f("fleet-backup-import-help")}),!!(C.length||R.length)&&l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>{E(T=>T.map(F=>({...F,selected:!0}))),x(T=>T.map(F=>({...F,selected:!!F.engine})))},children:f("select-all")}),l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>{E(T=>T.map(F=>({...F,selected:!1}))),x(T=>T.map(F=>({...F,selected:!1})))},children:f("select-none")})]}),l.jsxs("div",{className:"nc-backup-list",children:[!!R.length&&l.jsx("b",{children:f("fleet-engines")}),R.map((T,F)=>{var k;return l.jsx("div",{className:"nc-backup-import-row",children:l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:T.selected,onChange:I=>H(F,{selected:I.target.checked})}),l.jsxs("span",{children:[l.jsx("b",{children:T.engine.label||T.engine.id}),l.jsxs("small",{children:[T.engine.id," · ",T.exists?f("fleet-backup-overwrite"):f("fleet-backup-new"),(k=T.engine.envKeys)!=null&&k.length?` · ${f("fleet-backup-env-values-required")}`:""]})]})]})},T.engine.id)}),!!C.length&&l.jsx("b",{children:f("fleet-cells")}),C.map((T,F)=>l.jsxs("div",{className:"nc-backup-import-row",children:[l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:T.selected,disabled:!T.engine||!L.has(T.engine),onChange:k=>J(F,{selected:k.target.checked})}),l.jsxs("span",{children:[l.jsx("b",{children:T.cell.id}),l.jsxs("small",{children:[T.exists?f("fleet-backup-overwrite"):f("fleet-backup-new")," · ",f("fleet-system-prompt")," ",T.cell.systemPrompt.length," ",f("characters")]})]})]}),l.jsxs("select",{value:T.engine,onChange:k=>J(F,{engine:k.target.value,selected:!!k.target.value}),children:[l.jsx("option",{value:"",children:f("fleet-backup-engine-missing")}),O.map(([k,I])=>l.jsx("option",{value:k,children:I},k))]})]},T.cell.id))]}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:u,children:f("cancel")}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:s||!A.length&&!z.length,onClick:()=>a({engineRows:R,cellRows:C,models:m}),children:f("fleet-backup-restore")})]})]}),$&&l.jsx("div",{className:"nc-err",children:$})]})}function lj({state:e,setState:t,busy:n,onSave:s,catalog:o}){var R;const a=e.form,u=E=>t({...e,form:{...a,...E}}),h=a.envRows||[],p=[...new Map(o.map(E=>[E.client,E.clientLabel||E.client])).entries()],m=o.filter(E=>E.client===a.client),v=Zo(o,a),y=typeof(v==null?void 0:v.credentialEnv)=="string"?v.credentialEnv:"",w=Array.isArray(v==null?void 0:v.credentialUsedBy)?v.credentialUsedBy:[],b=(v==null?void 0:v.credentialSource)||"missing",S=!!(v!=null&&v.credentialEnv)||a.credentialProfile==="a"||a.credentialProfile==="p",C=!!y&&e.mode==="new"&&(v==null?void 0:v.authConfigured)!==!0&&!a.credentialValue&&!a.allowMissingCredential,x=E=>{E&&u({client:E.client,provider:E.provider,credentialProfile:E.credentialProfile||"",managedModel:E.model||"",protocol:E.protocol||"",permissionPolicy:E.permissionPolicyDefault||"standard",credentialSourcePolicy:"auto",rc:!!E.rc,displayName:E.custom?f("fleet-custom-provider-default"):"",baseUrl:E.custom?"":E.endpoint||"",envKey:E.defaultEnvKey||"",providerId:"nexuscrew-custom",credentialValue:"",credentialReveal:!1,allowMissingCredential:!1,...e.mode==="new"?{id:E.id,label:""}:{}})};return l.jsxs("div",{className:"nc-set-form nc-fleet-form",children:[l.jsx("b",{children:e.mode==="new"?f("fleet-new-engine"):`${f("edit")} ${a.id}`}),l.jsx("input",{value:a.id,disabled:e.mode!=="new",placeholder:"id",onChange:E=>u({id:E.target.value})}),l.jsx("input",{value:a.label,placeholder:f("label"),onChange:E=>u({label:E.target.value})}),l.jsxs("select",{value:a.kind,disabled:e.mode!=="new",onChange:E=>u({kind:E.target.value}),children:[l.jsx("option",{value:"managed",children:f("fleet-managed")}),l.jsx("option",{value:"custom",children:f("fleet-custom")})]}),a.kind==="managed"?l.jsxs(l.Fragment,{children:[l.jsxs("div",{className:"nc-fleet-pair",children:[l.jsx("select",{value:a.client,disabled:e.mode!=="new",onChange:E=>x(o.find($=>$.client===E.target.value&&$.default)||o.find($=>$.client===E.target.value)),children:p.map(([E,$])=>l.jsx("option",{value:E,children:$},E))}),l.jsx("select",{value:((R=Zo(o,a))==null?void 0:R.id)||"",disabled:e.mode!=="new",onChange:E=>x(o.find($=>$.id===E.target.value)),children:m.map(E=>l.jsx("option",{value:E.id,children:E.label},E.id))})]}),a.client!=="shell"&&l.jsxs(l.Fragment,{children:[l.jsx("input",{value:a.managedModel,list:"nc-managed-models",placeholder:f(v!=null&&v.requiresModel?"fleet-model-required":"fleet-model-default"),onChange:E=>u({managedModel:E.target.value})}),l.jsx("datalist",{id:"nc-managed-models",children:[...(v==null?void 0:v.models)||[],...a.modelOptions||[]].filter((E,$,B)=>E&&B.indexOf(E)===$).map(E=>l.jsx("option",{value:E},E))})]}),v!=null&&v.supportsUnsafe?l.jsxs("select",{value:a.permissionPolicy,onChange:E=>u({permissionPolicy:E.target.value}),children:[l.jsx("option",{value:"standard",children:f("fleet-standard-permissions")}),l.jsx("option",{value:"unsafe",children:f("fleet-unsafe-permissions")})]}):l.jsx("small",{children:f("fleet-standard-permissions")}),(v==null?void 0:v.supportsUnsafe)&&a.permissionPolicy==="unsafe"&&l.jsx("small",{className:"nc-err",children:f("fleet-unsafe-warning")}),S&&l.jsxs("select",{"aria-label":f("fleet-credential-source-policy"),value:a.credentialSourcePolicy||"auto",onChange:E=>u({credentialSourcePolicy:E.target.value}),children:[l.jsx("option",{value:"auto",children:f("fleet-credential-source-policy-auto")}),l.jsx("option",{value:"nexuscrew-store",children:f("fleet-credential-source-policy-nexuscrew-store")}),l.jsx("option",{value:"environment",children:f("fleet-credential-source-policy-environment")})]}),(v==null?void 0:v.credentialEnv)===!0&&l.jsxs(l.Fragment,{children:[l.jsx("input",{value:a.envKey,placeholder:f("fleet-api-key-env"),onChange:E=>u({envKey:E.target.value})}),l.jsx("small",{children:f("fleet-custom-secret-help")})]}),y&&l.jsxs("section",{className:"nc-fleet-key","aria-label":f("fleet-key-section"),children:[l.jsxs("div",{className:"nc-fleet-key-head",children:[l.jsx("b",{children:f("fleet-key-section")}),l.jsx("span",{children:f(`fleet-credential-source-${b}`)})]}),l.jsxs("label",{className:"nc-field",children:[f("fleet-key-variable"),l.jsx("input",{value:y,readOnly:!0,"aria-label":f("fleet-key-variable")})]}),l.jsx("small",{children:w.length?f("fleet-key-used-by").replace("{engines}",w.join(", ")):f("fleet-key-used-by-none")}),w.length>0&&l.jsx("small",{children:f("fleet-key-shared-impact").replace("{key}",y).replace("{engines}",w.join(", "))}),l.jsxs("div",{className:"nc-fleet-key-input",children:[l.jsx("input",{type:a.credentialReveal?"text":"password",value:a.credentialValue||"","aria-label":f("fleet-key-value").replace("{key}",y),autoComplete:"new-password",spellCheck:!1,autoCapitalize:"none",autoCorrect:"off",placeholder:v!=null&&v.authConfigured||e.mode==="edit"?f("fleet-key-blank-keeps"):f("fleet-key-enter"),onChange:E=>u({credentialValue:E.target.value,allowMissingCredential:E.target.value?!1:a.allowMissingCredential})}),l.jsx("button",{type:"button",className:"nc-btn ghost","aria-label":f(a.credentialReveal?"fleet-key-hide":"fleet-key-reveal"),onClick:()=>u({credentialReveal:!a.credentialReveal}),children:f(a.credentialReveal?"fleet-key-hide":"fleet-key-reveal")})]}),l.jsx("small",{children:f("fleet-key-local-help")}),e.mode==="new"&&(v==null?void 0:v.authConfigured)!==!0&&!a.credentialValue&&l.jsxs("label",{className:"nc-check nc-fleet-key-missing",children:[l.jsx("input",{type:"checkbox",checked:!!a.allowMissingCredential,onChange:E=>u({allowMissingCredential:E.target.checked})}),f("fleet-key-create-missing")]}),(v==null?void 0:v.notice)&&l.jsx("small",{className:"nc-fleet-provider-notice",children:f(`fleet-provider-notice-${v.notice}`)})]}),(v==null?void 0:v.notice)&&!y&&l.jsx("small",{className:"nc-fleet-provider-notice",children:f(`fleet-provider-notice-${v.notice}`)}),a.provider==="custom"&&l.jsxs(l.Fragment,{children:[l.jsx("input",{value:a.displayName,placeholder:f("fleet-provider-display"),onChange:E=>u({displayName:E.target.value})}),l.jsx("input",{value:a.baseUrl,placeholder:"https://api.example.com/v1",onChange:E=>u({baseUrl:E.target.value})}),((v==null?void 0:v.protocols)||[]).length>1&&l.jsx("select",{value:a.protocol,onChange:E=>u({protocol:E.target.value}),children:v.protocols.map(E=>l.jsx("option",{value:E,children:E},E))}),l.jsxs("div",{className:"nc-fleet-pair",children:[l.jsx("input",{value:a.envKey,placeholder:f("fleet-api-key-env"),onChange:E=>u({envKey:E.target.value})}),l.jsx("input",{value:a.providerId,placeholder:f("fleet-provider-id"),onChange:E=>u({providerId:E.target.value})})]}),l.jsxs("small",{children:[a.protocol," · ",f("fleet-custom-secret-help")]})]}),l.jsx("small",{children:f(a.client==="shell"?"fleet-shell-engine-help":"fleet-managed-help")})]}):l.jsxs(l.Fragment,{children:[l.jsx("input",{value:a.command,placeholder:f("command-path"),onChange:E=>u({command:E.target.value})}),l.jsx("textarea",{value:a.argsText,placeholder:f("args-lines"),onChange:E=>u({argsText:E.target.value})}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:a.rc,onChange:E=>u({rc:E.target.checked})})," ",f("fleet-remote-control")]}),l.jsxs("select",{value:a.promptMode,onChange:E=>u({promptMode:E.target.value}),children:[l.jsx("option",{value:"send-keys",children:"send-keys"}),l.jsx("option",{value:"flag",children:"flag"})]}),a.promptMode==="flag"&&l.jsx("input",{value:a.promptFlag,placeholder:"prompt flag",onChange:E=>u({promptFlag:E.target.value})}),l.jsxs("div",{className:"nc-fleet-pair",children:[l.jsx("input",{value:a.modelFlag,placeholder:"model flag",onChange:E=>u({modelFlag:E.target.value})}),l.jsx("input",{value:a.modelValue,placeholder:"model default",onChange:E=>u({modelValue:E.target.value})})]}),l.jsx("small",{children:f("env-write-only")}),h.map((E,$)=>l.jsxs("div",{className:"nc-fleet-env",children:[l.jsx("input",{value:E.key,disabled:E.configured,placeholder:"ENV_KEY",onChange:B=>{const K=h.slice();K[$]={...E,key:B.target.value},u({envRows:K})}}),l.jsx("input",{type:"password",value:E.value,placeholder:E.configured?"•••••• (unchanged)":"value",onChange:B=>{const K=h.slice();K[$]={...E,value:B.target.value},u({envRows:K})}}),l.jsx("button",{className:"nc-btn danger",onClick:()=>u({envRows:h.filter((B,K)=>K!==$)}),children:"×"})]},`${E.key}-${$}`)),l.jsx("button",{className:"nc-btn ghost",onClick:()=>u({envRows:[...h,{key:"",value:"",configured:!1}]}),children:"+ env"})]}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{className:"nc-btn ghost",onClick:()=>t(null),children:f("cancel")}),l.jsx("button",{className:"nc-btn primary",disabled:n||!a.id||C||a.kind==="custom"&&!a.command||a.kind==="managed"&&(v==null?void 0:v.requiresModel)&&!a.managedModel||a.kind==="managed"&&(v==null?void 0:v.credentialEnv)===!0&&!a.envKey||a.kind==="managed"&&a.provider==="custom"&&(!a.displayName||!a.baseUrl||!a.envKey||!a.providerId),onClick:s,children:f("save")})]})]})}function cj({state:e,setState:t,busy:n,onSave:s,onTest:o,profiles:a=[],canTest:u=!0}){const[h,p]=N.useState(null),[m,v]=N.useState(!1),y=e.form,w=x=>t({...e,form:{...y,...x}}),b=/^[^\x00-\x1f\x7f]{1,128}$/.test(y.id||""),S=!!(y.id||"").trim()&&!!(y.engine||"").trim()&&b,C=async()=>{p(null),v(!0);try{p(await o(y.engine,y.id))}catch(x){p({outcome:"unverified",detail:String(x&&x.message||x)})}v(!1)};return l.jsxs("div",{className:"nc-fleet-form",children:[l.jsxs("label",{className:"nc-field",children:[f("model-editor-engine"),l.jsxs("select",{value:y.engine||"",disabled:n||e.mode==="edit",onChange:x=>{p(null),w({engine:x.target.value})},children:[l.jsx("option",{value:"",children:"—"}),a.map(x=>l.jsx("option",{value:x.id,children:x.label?`${x.id} · ${x.label}`:x.id},x.id))]})]}),l.jsxs("label",{className:"nc-field",children:[f("model-editor-id"),l.jsx("input",{value:y.id||"",disabled:n||e.mode==="edit",placeholder:"qwen3.9-max",onChange:x=>{p(null),w({id:x.target.value})}})]}),l.jsx("small",{className:"nc-set-hint",children:f("model-editor-id-help")}),l.jsxs("label",{className:"nc-field",children:[f("model-editor-context"),l.jsx("input",{inputMode:"numeric",value:y.contextWindow||"",disabled:n,onChange:x=>w({contextWindow:x.target.value.replace(/[^0-9]/g,"").slice(0,9)})})]}),l.jsxs("label",{className:"nc-field",children:[f("model-editor-max-tokens"),l.jsx("input",{inputMode:"numeric",value:y.maxTokens||"",disabled:n,onChange:x=>w({maxTokens:x.target.value.replace(/[^0-9]/g,"").slice(0,9)})})]}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:y.reasoning===!0,disabled:n,onChange:x=>w({reasoning:x.target.checked})})," ",f("model-editor-reasoning")]}),l.jsxs("div",{className:"nc-set-row",children:[u&&l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||m||!S,onClick:C,children:f(m?"model-test-running":"model-test")}),h&&l.jsxs("span",{className:`nc-model-test ${h.outcome}`,children:[f(`model-test-${h.outcome}`),h.outcome==="ok"&&Number.isInteger(h.latencyMs)?` · ${h.latencyMs}ms`:""]})]}),h&&h.detail&&l.jsx("small",{className:"nc-set-hint",children:h.detail}),h&&h.outcome==="unverified"&&l.jsx("small",{className:"nc-set-hint",children:f("model-test-unverified-help")}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>t(null),children:f("cancel")}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:n||!S,onClick:()=>s(y),children:f("save")})]})]})}function uj({token:e,route:t,targets:n=[],location:s,setLocation:o,state:a,setState:u,engines:h,mcpServers:p=[],busy:m,onSave:v}){var H;const[y,w]=N.useState(null),[b,S]=N.useState(""),C=a.form,x=L=>u({...a,form:{...C,...L}}),R=h.find(L=>L.id===C.engine),E=((H=R==null?void 0:R.managed)==null?void 0:H.client)==="shell",$=L=>{var O,T,F,k;const A=h.find(I=>I.id===L),z={...C.commands||{}};((O=R==null?void 0:R.managed)==null?void 0:O.client)==="shell"&&(C.command?z[C.engine]=C.command:delete z[C.engine]),x({engine:L,model:((T=C.models)==null?void 0:T[L])||((F=A==null?void 0:A.managed)==null?void 0:F.model)||((k=A==null?void 0:A.model)==null?void 0:k.value)||"",commands:z,command:z[L]||""})},B=L=>{const A={...C.commands||{}};L?A[C.engine]=L:delete A[C.engine],x({command:L,commands:A})},K=E&&/[|&;<>()`$*?{}\[\]~]/.test(C.command||""),V=[...new Set([...p||[],...Array.isArray(C.mcp)?C.mcp:[]])].sort(),Y=Array.isArray(C.mcp)?C.mcp.length?"some":"none":"all",te=L=>{var A;return x({mcp:L==="all"?void 0:L==="none"?[]:(A=C.mcp)!=null&&A.length?C.mcp:[...V]})},Q=L=>{const A=Array.isArray(C.mcp)?C.mcp:[];x({mcp:A.includes(L)?A.filter(z=>z!==L):[...A,L].sort()})},J=async L=>{try{const A=await Jh(e,L,t);w(A),x({cwd:A.path}),S("")}catch(A){S(String(A.message||A))}};return l.jsxs("div",{className:"nc-set-form nc-fleet-form",children:[l.jsx("b",{children:a.mode==="new"?f("fleet-new-cell"):`${f("edit")} ${C.id}`}),a.mode==="new"&&l.jsxs("label",{className:"nc-field",children:[f("location"),l.jsx("span",{className:"nc-req",children:" *"}),l.jsxs("select",{value:s,onChange:L=>{o(L.target.value),x({engine:""})},children:[l.jsx("option",{value:"",children:f("local")}),n.map(L=>l.jsxs("option",{value:L.route.join("/"),disabled:L.status&&L.status!=="up",children:[L.label,L.status&&L.status!=="up"?` · ${f("node-offline")}`:""]},L.route.join("/")))]})]}),l.jsx("input",{value:C.id,disabled:a.mode!=="new",placeholder:"id",onChange:L=>x({id:L.target.value})}),l.jsx("input",{value:C.label||"",maxLength:64,placeholder:f("fleet-cell-label"),onChange:L=>x({label:L.target.value})}),l.jsxs("div",{className:"nc-fleet-pair",children:[l.jsx("input",{value:C.cwd,placeholder:f("cwd"),onChange:L=>x({cwd:L.target.value})}),l.jsx("button",{className:"nc-btn ghost",onClick:()=>y?w(null):J(C.cwd),children:f("browse")})]}),y&&l.jsxs("div",{className:"nc-fs",children:[l.jsx("div",{className:"nc-fs-path",children:y.path}),l.jsxs("div",{className:"nc-fs-list",children:[y.parent&&l.jsxs("button",{className:"nc-fs-item nc-fs-nav",onClick:()=>J(y.parent),children:["↑ ",f("fs-parent")]}),(y.dirs||[]).map(L=>l.jsxs("button",{className:"nc-fs-item",onClick:()=>J(`${y.path.replace(/\/$/,"")}/${L}`),children:["📁 ",L]},L))]})]}),b&&l.jsx("div",{className:"nc-err",children:b}),l.jsx("select",{value:C.engine,onChange:L=>$(L.target.value),children:h.map(L=>l.jsx("option",{value:L.id,children:L.label},L.id))}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:!!C.boot,onChange:L=>x({boot:L.target.checked})})," ",f("fleet-boot")]}),E?l.jsxs(l.Fragment,{children:[l.jsx("input",{value:C.command||"",maxLength:4096,placeholder:f("fleet-shell-command-placeholder"),onChange:L=>B(L.target.value)}),l.jsx("small",{children:C.command?f("fleet-shell-command-help"):f("fleet-shell-interactive")}),K&&l.jsx("small",{className:"nc-note",children:f("fleet-shell-command-metachar")})]}):l.jsxs(l.Fragment,{children:[l.jsx("input",{value:C.model||"",list:"nc-cell-models",placeholder:f("fleet-model-override"),onChange:L=>x({model:L.target.value})}),l.jsx("datalist",{id:"nc-cell-models",children:((R==null?void 0:R.availableModels)||[]).map(L=>l.jsx("option",{value:L},L))}),l.jsx("textarea",{value:C.prompt||"",placeholder:f("cell-prompt"),onChange:L=>x({prompt:L.target.value})}),l.jsx("small",{children:f("cell-prompt-help")}),l.jsxs("label",{className:"nc-field",children:[f("cell-mcp"),l.jsxs("select",{value:Y,onChange:L=>te(L.target.value),children:[l.jsx("option",{value:"all",children:f("cell-mcp-all")}),l.jsx("option",{value:"none",children:f("cell-mcp-none")}),l.jsx("option",{value:"some",children:f("cell-mcp-some")})]})]}),Y==="some"&&l.jsx("div",{className:"nc-fleet-mcp-list",children:V.map(L=>l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:(C.mcp||[]).includes(L),onChange:()=>Q(L)})," ",L]},L))}),l.jsx("small",{children:f("cell-mcp-help")})]}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{className:"nc-btn ghost",onClick:()=>u(null),children:f("cancel")}),l.jsx("button",{className:"nc-btn primary",disabled:m||!C.id||!C.cwd||!C.engine,onClick:v,children:f("save")})]})]})}function B_({token:e,route:t=[],state:n,setState:s,busy:o,onSave:a}){const[u,h]=N.useState(null),[p,m]=N.useState([]),[v,y]=N.useState(""),w=Array.isArray(t)?t.join("/"):"";N.useEffect(()=>{let R=!0;return Jl(e,w?w.split("/"):[]).then(E=>{R&&(m(E.engines||[]),y(""))}).catch(E=>{R&&(m([]),y(String(E.message||E)))}),()=>{R=!1}},[e,w]);const b=n.form,S=R=>s({...n,form:{...b,...R}}),C=async R=>{try{const E=await Jh(e,R,t);h(E),S({cwd:E.path})}catch{}},x=!b.id&&b.tmuxSession?b.tmuxSession.replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,32):b.id;return l.jsxs("div",{className:"nc-set-form nc-fleet-form",children:[l.jsxs("b",{children:[f("import-as-cell")," · ",b.tmuxSession]}),l.jsx("small",{children:f("import-help")}),l.jsx("input",{value:b.tmuxSession,disabled:!0,placeholder:"tmux session",readOnly:!0}),l.jsx("input",{value:b.id,placeholder:f("name"),onChange:R=>S({id:R.target.value})}),l.jsxs("div",{className:"nc-fleet-pair",children:[l.jsx("input",{value:b.cwd,placeholder:f("cwd"),onChange:R=>S({cwd:R.target.value})}),l.jsx("button",{className:"nc-btn ghost",type:"button",onClick:()=>u?h(null):C(b.cwd),children:f("browse")})]}),u&&l.jsxs("div",{className:"nc-fs",children:[l.jsx("div",{className:"nc-fs-path",children:u.path}),l.jsxs("div",{className:"nc-fs-list",children:[u.parent&&l.jsxs("button",{className:"nc-fs-item nc-fs-nav",onClick:()=>C(u.parent),children:["↑ ",f("fs-parent")]}),(u.dirs||[]).map(R=>l.jsxs("button",{className:"nc-fs-item",onClick:()=>C(`${u.path.replace(/\/$/,"")}/${R}`),children:["📁 ",R]},R))]})]}),l.jsxs("select",{value:b.engine,onChange:R=>S({engine:R.target.value}),children:[l.jsx("option",{value:"",children:f("import-engine-required")}),p.map(R=>l.jsx("option",{value:R.id,children:R.label},R.id))]}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:!!b.boot,onChange:R=>S({boot:R.target.checked})})," ",f("fleet-boot")]}),(n.err||v)&&l.jsx("div",{className:"nc-err",children:n.err||v}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{className:"nc-btn ghost",onClick:()=>s(null),children:f("cancel")}),l.jsx("button",{className:"nc-btn primary",disabled:o||!b.tmuxSession||!b.engine||!p.length,onClick:a,children:f(x?"import-as-cell":"save")})]})]})}function El(e){const t=Ks(e);return t===null?`~/${e}`:t?`~/${t}`:"~"}function dj(e){if(!e||typeof e.path!="string"||typeof e.home!="string")return"";const{path:t,home:n}=e;return!n||t===n||!t.startsWith(n+"/")?"":t.slice(n.length+1).replace(/\/+$/,"")}function hj({token:e,route:t,cell:n,busy:s=!1,onSaved:o,onClose:a}){const[u,h]=N.useState(""),[p,m]=N.useState(null),[v,y]=N.useState(!1),[w,b]=N.useState(""),S=typeof(n==null?void 0:n.cwdSuggestion)=="string"&&Ks(n.cwdSuggestion)!==null?Ks(n.cwdSuggestion):null,[C,x]=N.useState(S),R=n==null?void 0:n.id,E=s||v,$=async Q=>{const J=Ks(Q);if(J===null){m({rel:"",dirs:[],loading:!1,err:f("fleet-cwd-repair-invalid")});return}m({rel:J,dirs:[],loading:!0,err:""});try{const H=await Jh(e,J,t),L=dj(H);m({rel:L,dirs:Array.isArray(H.dirs)?H.dirs:[],loading:!1,err:""})}catch(H){m({rel:J,dirs:[],loading:!1,err:String(H&&H.message||H)})}},B=Q=>{if(!p)return;const J=p.rel?`${p.rel}/${Q}`:Q;$(J)},K=()=>{p!=null&&p.rel&&$(p.rel.split("/").slice(0,-1).join("/"))},V=()=>{p&&(h(p.rel||""),m(null),b(""),x(null))},Y=()=>{C!==null&&(h(C),x(null),b(""))},te=async()=>{if(E)return;const Q=Ks(u);if(Q===null){b(f("fleet-cwd-repair-invalid"));return}const J=El(Q);let H=!0;try{H=window.confirm(f("fleet-cwd-repair-confirm").replace("{id}",String(R||"")).replace("{path}",J))}catch{H=!1}if(H){y(!0),b(""),x(null);try{const L=await Z_(e,R,{cwdRel:Q},t);o==null||o(L)}catch(L){const A=L&&L.data||{};if(A.code==="unportable-cwd"){b(f("fleet-cwd-repair-unportable"));const z=Array.isArray(A.cells)?A.cells.find(T=>T&&T.id===R):null,O=z&&typeof z.suggestion=="string"?z.suggestion:null;O!==null&&Ks(O)!==null&&x(O)}else b(String(L&&L.message||L))}finally{y(!1)}}};return l.jsxs("div",{className:"nc-set-form nc-fleet-form nc-cwd-repair",children:[l.jsx("b",{children:f("fleet-cwd-repair-title").replace("{id}",String(R||""))}),l.jsx("small",{className:"nc-set-info",children:f("fleet-cwd-repair-help")}),l.jsx("small",{className:"nc-cwd-no-source",children:f("fleet-cwd-repair-no-source-path")}),l.jsxs("label",{className:"nc-field",children:[f("cwd"),l.jsxs("div",{className:"nc-cwd-rel-row",children:[l.jsx("span",{className:"nc-cwd-rel-prefix",children:"~/"}),l.jsx("input",{value:u,placeholder:f("fleet-cwd-repair-placeholder"),autoComplete:"off",spellCheck:"false",autoCapitalize:"none",onChange:Q=>h(Q.target.value)}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:E,onClick:()=>p?m(null):$(""),children:f(p?"close":"fleet-cwd-repair-browse")})]})]}),l.jsx("div",{className:"nc-cwd-preview",children:f("fleet-cwd-repair-preview").replace("{path}",El(u))}),p&&l.jsxs("div",{className:"nc-fs",children:[l.jsx("div",{className:"nc-fs-path",children:El(p.rel)}),l.jsxs("div",{className:"nc-fs-list",children:[p.rel&&l.jsxs("button",{type:"button",className:"nc-fs-item nc-fs-nav",onClick:K,children:["↑ ",f("fs-parent")]}),p.loading&&l.jsx("div",{className:"nc-fs-empty",children:"…"}),!p.loading&&p.dirs.length===0&&l.jsx("div",{className:"nc-fs-empty",children:f("fleet-cwd-repair-fs-empty")}),!p.loading&&p.dirs.map(Q=>l.jsxs("button",{type:"button",className:"nc-fs-item",onClick:()=>B(Q),children:["📁 ",Q]},Q))]}),p.err&&l.jsx("div",{className:"nc-err",children:p.err}),l.jsx("div",{className:"nc-sheet-actions",children:l.jsx("button",{type:"button",className:"nc-btn primary",disabled:E||p.loading||!!p.err,onClick:V,children:f("fleet-cwd-repair-use-current")})})]}),w&&l.jsx("div",{className:"nc-err",role:"alert",children:w}),C!==null&&l.jsxs("div",{className:"nc-cwd-suggestion",role:"status",children:[l.jsx("span",{children:f("fleet-cwd-repair-suggestion")}),l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:Y,children:f("fleet-cwd-repair-use-suggestion").replace("{path}",El(C))})]}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:v,onClick:a,children:f("cancel")}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:E,onClick:te,children:v?"…":f("save")})]})]})}function fj({token:e,readonly:t,targets:n=[],startNewCell:s=!1,initialLocation:o=""}){const[a,u]=N.useState({engines:[],cells:[],managedCatalog:[]}),[h,p]=N.useState({available:!1,capabilities:[]}),[m,v]=N.useState(!1),[y,w]=N.useState(null),[b,S]=N.useState(null),[C,x]=N.useState({}),[R,E]=N.useState(null),[$,B]=N.useState(!1),[K,V]=N.useState(""),[Y,te]=N.useState(""),[Q,J]=N.useState(o),[H,L]=N.useState(!1),[A,z]=N.useState(null),[O,T]=N.useState(null),[F,k]=N.useState(null),[I,D]=N.useState(!1),[M,W]=N.useState([]),[G,ue]=N.useState(null),[le,he]=N.useState("manage"),we=N.useRef(!1),re=Q?Q.split("/"):[],_e=N.useCallback(async()=>{try{const j=await bs(e,re);p(j);try{const X=await ef(e,re);L(!!X.readonlyDefault)}catch{L(!1)}if(j.provider==="builtin"&&(j.capabilities||[]).includes("definitions")){const X=await Jl(e,re),ie=new Map((j.engines||[]).map(pe=>[pe.id,pe]));if(X.engines=(X.engines||[]).map(pe=>{var ke;return{...pe,availableModels:((ke=ie.get(pe.id))==null?void 0:ke.models)||[]}}),u(X),(j.capabilities||[]).includes("credentials"))try{W((await v0(e,re)).credentials||[])}catch{W([])}else W([])}V("")}catch(j){V(String(j.message||j))}finally{v(!0)}},[e,Q]);N.useEffect(()=>{_e();const j=setInterval(_e,5e3);return()=>clearInterval(j)},[_e]);const ze=new Set((h.cells||[]).filter(j=>j.active).map(j=>j.cell)),ut=h.provider==="builtin"&&(h.capabilities||[]).includes("edit"),nt=(h.capabilities||[]).includes("restore");N.useEffect(()=>{!s||we.current||!ut||!a.engines.length||(we.current=!0,E({mode:"new",form:O_(a.engines[0].id)}))},[s,ut,a.engines]);const Ne=async j=>{B(!0),V(""),te("");try{await j(),await _e()}catch(X){V(String(X.message||X))}B(!1)},jt=async(j,X)=>{const ie=await k0(e,j,X,re);return x(pe=>({...pe,[`${j}::${X}`]:ie})),ie},tn=j=>Ne(async()=>{const X={id:String(j.id||"").trim(),engine:String(j.engine||"").trim()};for(const ie of["contextWindow","maxTokens"]){const pe=String(j[ie]||"").trim();pe&&(X[ie]=Number(pe))}j.reasoning===!0&&(X.reasoning=!0),await S0(e,X,re),S(null),await _e()}),De=()=>Ne(async()=>{var Xe;const j=y.mode==="new",X=y.form,ie=a.managedCatalog||[],pe=X.kind==="managed"?Zo(ie,X):null,ke=typeof(pe==null?void 0:pe.credentialEnv)=="string"?pe.credentialEnv:"",me=ke&&X.credentialValue||"",xe=oj(X,j,ie);!j&&y.form.kind==="custom"&&!y.form.modelFlag&&(xe.model=null),!j&&y.form.kind==="custom"&&y.form.promptMode!=="flag"&&(xe.promptFlag=null);let We;if(j)We=await y0(e,xe,re);else{const je=y.original,_t=new Set(y.form.envRows.filter(Rt=>!Rt.remove).map(Rt=>Rt.key)),Sn=(je.envKeys||[]).filter(Rt=>!_t.has(Rt)),Rn=Object.fromEntries(y.form.envRows.filter(Rt=>!Rt.remove&&Rt.key&&(!Rt.configured||Rt.value!=="")).map(Rt=>[Rt.key,Rt.value]));We=await w0(e,je.id,xe,y.form.kind==="custom"?{set:Rn,remove:Sn}:void 0,re)}let lt=null;if(ke&&me)try{lt=await wg(e,ke,me,re),W(lt.credentials||[])}catch{throw await _e(),j&&w({mode:"edit",original:{...xe,id:X.id},form:{...X,credentialReveal:!1}}),new Error(f(j?"fleet-key-partial-create":"fleet-key-partial-edit"))}await _e(),w(null),te(f("fleet-saved"));const Ke=((Xe=((lt==null?void 0:lt.credentials)||[]).find(je=>je.envKey===ke))==null?void 0:Xe.activeCells)||[],pt=[...new Set([...(We==null?void 0:We.activeCells)||[],...Ke])];if(pt.length&&window.confirm(f("fleet-restart-confirm").replace("{cells}",pt.join(", "))))for(const je of pt)await $o(e,je,re)}),Tt=()=>Ne(async()=>{var lt,Ke,pt,Xe,je,_t;const j=R.mode==="new",X=R.form,ie={...j?{id:X.id}:{},cwd:X.cwd,engine:X.engine,boot:!!X.boot},pe={...X.commands||{}},ke=a.engines.find(Sn=>Sn.id===X.engine);((lt=ke==null?void 0:ke.managed)==null?void 0:lt.client)==="shell"&&typeof X.command=="string"&&X.command.length?pe[X.engine]=X.command:((Ke=ke==null?void 0:ke.managed)==null?void 0:Ke.client)==="shell"&&delete pe[X.engine],(Object.keys(pe).length||!j)&&(ie.commands=pe);const me=(X.label||"").trim();j?me&&(ie.label=me):ie.label=me||null,j?Array.isArray(X.mcp)&&(ie.mcp=X.mcp):ie.mcp=Array.isArray(X.mcp)?X.mcp:null,j?(((pt=ke==null?void 0:ke.managed)==null?void 0:pt.client)!=="shell"&&X.model&&(ie.model=X.model),((Xe=ke==null?void 0:ke.managed)==null?void 0:Xe.client)!=="shell"&&X.prompt&&(ie.prompt=X.prompt)):(ie.model=((je=ke==null?void 0:ke.managed)==null?void 0:je.client)==="shell"?null:X.model||null,((_t=ke==null?void 0:ke.managed)==null?void 0:_t.client)!=="shell"&&(ie.prompt=X.prompt||null));const xe=j?await C0(e,ie,re):await Z_(e,R.original.id,ie,re),We=j?X.id:R.original.id;E(null),te(f("fleet-saved")),!j&&(xe!=null&&xe.active)&&window.confirm(f("fleet-restart-confirm").replace("{cells}",We))&&await $o(e,We,re)}),Qe=t||H,vt=h.capabilities||[],mt=re.length>0&&Qe,it=j=>M.find(X=>{var ie;return(ie=X.engines)==null?void 0:ie.includes(j.id)})||null,dt=()=>Ne(async()=>{var ie;const j=await wg(e,G.envKey,G.value,re);W(j.credentials||[]),ue(null),te(f("fleet-credential-saved"));const X=((ie=(j.credentials||[]).find(pe=>pe.envKey===G.envKey))==null?void 0:ie.activeCells)||[];if(X.length&&window.confirm(f("fleet-restart-confirm").replace("{cells}",X.join(", "))))for(const pe of X)await $o(e,pe,re)}),ot=j=>Ne(async()=>{if(!window.confirm(f("fleet-credential-remove-confirm").replace("{key}",j.envKey)))return;const X=await _0(e,j.envKey,re);W(X.credentials||[]),te(f("fleet-credential-removed"))}),ht=j=>z({...j,route:Array.isArray(j==null?void 0:j.route)?j.route:re}),st=async j=>{if(!A)return;const X=A.cell||A.id,ie=Array.isArray(A.route)?A.route:re;if(j.action==="up"){const pe=await Xh(e,{cell:X,boot:!!j.boot,...j.engine?{engine:j.engine}:{},...j.model!==void 0?{model:j.model}:{},...j.permissionPolicy?{permissionPolicy:j.permissionPolicy}:{}},ie),ke=df(pe);ke&&te(ke.text)}else await Il(e,{cell:X,boot:!!j.boot},ie)},ft=(j,X)=>{V(""),T({mode:"new",route:Array.isArray(X)?X:re,form:{tmuxSession:j.name,id:"",engine:"",cwd:"",boot:!1},err:""})},be=()=>Ne(async()=>{const j=O.form;if(!j.engine){T({...O,err:f("import-engine-required")});return}await E0(e,{tmuxSession:j.tmuxSession,id:j.id||void 0,engine:j.engine,cwd:j.cwd||void 0,boot:!!j.boot},j.route||re),T(null),te(f("fleet-saved"))}),ce=({engineRows:j=[],cellRows:X=[],models:ie=[]})=>Ne(async()=>{const pe=j.filter(je=>je.selected),ke=pe.map(je=>ob(je.engine));if(ke.some(je=>!je))throw new Error(f("fleet-backup-invalid-engine"));const me=pe.filter(je=>je.exists).map(je=>je.engine.id);if(me.length&&!window.confirm(f("fleet-backup-confirm-engine-overwrite").replace("{engines}",me.join(", "))))return;const xe=[...new Set([...a.engines.map(je=>je.id),...ke.map(je=>je.id)])],We=[];for(const je of X.filter(_t=>_t.selected)){const _t=nj(je.cell,je.engine,xe);if(!_t)throw new Error(`${je.cell.id}: ${f("fleet-backup-engine-missing")}`);We.push(_t)}const lt=X.filter(je=>je.selected&&je.exists).map(je=>je.cell.id);if(lt.length&&!window.confirm(f("fleet-backup-confirm-overwrite").replace("{cells}",lt.join(", "))))return;const Ke=ke.length?await j0(e,ke,me.length>0,re,ie):{needsRestart:[]},pt=We.length?await N0(e,We,re):{needsRestart:[]},Xe=[...new Set([...Ke.needsRestart||[],...pt.needsRestart||[]])];D(!1),te(`${f("fleet-backup-restored").replace("{n}",String(We.length))}${ke.length?` · ${ke.length} ${f("fleet-engines").toLowerCase()}`:""}${Xe.length?` · ${f("fleet-backup-needs-restart").replace("{cells}",Xe.join(", "))}`:""}`)}),U=l.jsxs("label",{className:"nc-field",children:[f("location"),l.jsxs("select",{value:Q,onChange:j=>{J(j.target.value),w(null),E(null),V(""),te(""),L(!1),v(!1),p({available:!1,capabilities:[]}),u({engines:[],cells:[],managedCatalog:[]}),W([]),ue(null)},children:[l.jsx("option",{value:"",children:f("local")}),n.map(j=>l.jsxs("option",{value:j.route.join("/"),disabled:j.status&&j.status!=="up",children:[j.label,j.status&&j.status!=="up"?` · ${f("node-offline")}`:""]},j.route.join("/")))]})]}),ne=l.jsxs("div",{className:"nc-fleet-view-tabs",role:"tablist","aria-label":f("tab-fleet"),children:[l.jsx("button",{type:"button",role:"tab","aria-selected":le==="manage",className:`nc-set-tabbtn${le==="manage"?" on":""}`,onClick:()=>he("manage"),children:f("fleet-manage-location")}),l.jsx("button",{type:"button",role:"tab","aria-selected":le==="overview",className:`nc-set-tabbtn${le==="overview"?" on":""}`,onClick:()=>he("overview"),children:f("fleet-network-overview")})]});return m?ut?l.jsxs("div",{className:"nc-set-tab nc-fleet-editor",children:[ne,le==="overview"?l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"nc-set-info",children:f("fleet-overview-help")}),l.jsx($d,{token:e,targets:n,readonly:t,onPower:ht,onImport:ft})]}):l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"nc-set-info",children:f("fleet-manage-help")}),U,l.jsxs("div",{className:"nc-set-row nc-fleet-backup-actions",children:[l.jsx("button",{className:"nc-btn ghost",disabled:Qe||$,onClick:()=>{V(""),D(!0)},children:f("fleet-backup")}),l.jsx("small",{children:f("fleet-backup-help")})]}),l.jsxs("div",{className:"nc-fleet-section-head",children:[l.jsx("b",{children:f("fleet-cells")}),l.jsx("span",{className:"nc-fleet-head-actions",children:l.jsxs("button",{className:"nc-btn primary",disabled:Qe||$||!a.engines.length,onClick:()=>{var j;V(""),E({mode:"new",form:O_((j=a.engines[0])==null?void 0:j.id)})},children:["+ ",f("add")]})})]}),a.cells.map(j=>{const X=ze.has(j.id),ie=j.needsRepair===!0;return l.jsxs("div",{className:"nc-fleet-item",children:[l.jsxs("span",{children:[l.jsx("b",{children:j.id}),j.label?l.jsxs("small",{className:"nc-fleet-label",children:[" ",j.label]}):null,l.jsxs("small",{children:[j.engine," · ",ie?l.jsx("span",{className:"nc-fleet-tag nc-fleet-tag-warn",children:f("fleet-cwd-needs-repair")}):j.cwd,X?` · ${f("service-active")}`:` · ${f("cell-off")}`]})]}),l.jsxs("span",{children:[X&&vt.includes("down")&&l.jsx("button",{className:"nc-btn ghost",disabled:Qe||$,onClick:()=>Ne(()=>Il(e,{cell:j.id},re)),children:f("stop")}),!X&&vt.includes("up")&&l.jsx("button",{className:"nc-btn primary",disabled:Qe||$,onClick:()=>ht({cell:j.id,id:j.id,engine:j.engine,model:j.model,models:j.models,permissionPolicies:j.permissionPolicies,active:!1,boot:j.boot}),children:f("start")}),X&&vt.includes("restart")&&l.jsx("button",{className:"nc-btn ghost",disabled:Qe||$,onClick:()=>Ne(()=>$o(e,j.id,re)),children:f("restart")}),ie?l.jsx("button",{className:"nc-btn ghost",disabled:Qe||$,onClick:()=>{V(""),k(j)},children:f("fleet-cwd-repair")}):l.jsx("button",{className:"nc-btn ghost",disabled:Qe||$,onClick:()=>{var pe;V(""),E({mode:"edit",original:j,form:{...j,commands:{...j.commands||{}},command:((pe=j.commands)==null?void 0:pe[j.engine])||""}})},children:f("edit")}),l.jsx("button",{className:"nc-btn danger",disabled:Qe||$,onClick:()=>Ne(async()=>{window.confirm(f("fleet-remove-cell").replace("{id}",j.id))&&await ey(e,j.id,!0,re)}),children:"×"})]})]},j.id)}),l.jsxs("div",{className:"nc-fleet-section-head",children:[l.jsx("b",{children:f("fleet-engines")}),l.jsxs("button",{className:"nc-btn primary",disabled:Qe||$,onClick:()=>{V(""),w({mode:"new",form:ij()})},children:["+ ",f("add")]})]}),a.engines.map(j=>{var ie,pe;const X=it(j);return l.jsxs("div",{className:"nc-fleet-item",children:[l.jsxs("span",{children:[l.jsx("b",{children:j.label}),l.jsx("small",{children:j.managed?`${j.id} · ${j.managed.client} / ${j.managed.provider} · ${(ie=j.managedInfo)!=null&&ie.configured?f("fleet-ready"):((pe=j.managedInfo)==null?void 0:pe.reason)||f("fleet-not-ready")}`:`${j.id} · ${j.command}`}),X&&l.jsxs("small",{children:[X.envKey," · ",f(`fleet-credential-source-${X.source||"missing"}`)]})]}),l.jsxs("span",{children:[X&&l.jsx("button",{className:"nc-btn ghost",disabled:Qe||$,onClick:()=>{V(""),ue({envKey:X.envKey,value:""})},children:X.configured?f("fleet-credential-change"):f("fleet-credential-set")}),(X==null?void 0:X.source)==="local"&&l.jsx("button",{className:"nc-btn danger",disabled:Qe||$,onClick:()=>ot(X),children:f("fleet-credential-forget")}),l.jsx("button",{className:"nc-btn ghost",disabled:Qe||$,onClick:()=>{V(""),w({mode:"edit",original:j,form:rj(j)})},children:f("edit")}),l.jsx("button",{className:"nc-btn danger",disabled:Qe||$,onClick:()=>Ne(async()=>{window.confirm(f("fleet-remove-engine").replace("{id}",j.id))&&await b0(e,j.id,re)}),children:"×"})]})]},j.id)}),l.jsxs("div",{className:"nc-fleet-section-head",children:[l.jsx("b",{children:f("fleet-models")}),l.jsxs("button",{className:"nc-btn primary",disabled:Qe||$,onClick:()=>{V(""),S({mode:"new",form:{id:"",engine:""}})},children:["+ ",f("add")]})]}),!(a.models||[]).length&&l.jsx("small",{className:"nc-set-hint",children:f("fleet-no-models")}),(a.models||[]).map(j=>{const X=`${j.engine}::${j.id}`,ie=C[X],pe=(a.engines||[]).some(ke=>ke.managed&&ke.managed.model===j.id);return l.jsxs("div",{className:"nc-fleet-item",children:[l.jsxs("span",{children:[l.jsx("b",{children:j.id}),l.jsxs("small",{children:[j.engine,j.contextWindow?` · ${j.contextWindow}`:"",pe?` · ${f("model-in-use")}`:""]}),ie&&l.jsxs("small",{className:`nc-model-test ${ie.outcome}`,children:[f(`model-test-${ie.outcome}`),ie.outcome==="ok"&&Number.isInteger(ie.latencyMs)?` · ${ie.latencyMs}ms`:""]})]}),l.jsxs("span",{children:[vt.includes("model-test")&&l.jsx("button",{className:"nc-btn ghost",disabled:$||mt,onClick:()=>Ne(()=>jt(j.engine,j.id)),children:f("model-test")}),l.jsx("button",{className:"nc-btn danger",disabled:Qe||$,onClick:()=>Ne(()=>x0(e,j.id,j.engine,re)),children:"×"})]})]},X)})]}),b&&l.jsx(fs,{onClose:()=>S(null),label:f("fleet-models"),error:K,children:l.jsx(cj,{state:b,setState:S,busy:$,onSave:tn,onTest:jt,profiles:a.managedCatalog||[],canTest:vt.includes("model-test")&&!mt})}),y&&l.jsx(fs,{onClose:()=>w(null),label:f("fleet-new-engine"),error:K,children:l.jsx(lj,{state:y,setState:w,busy:$,onSave:De,catalog:a.managedCatalog||[]})}),R&&l.jsx(fs,{onClose:()=>E(null),label:f("fleet-new-cell"),error:K,children:l.jsx(uj,{token:e,route:re,targets:n,location:Q,setLocation:J,state:R,setState:E,engines:a.engines,mcpServers:a.mcpServers||[],busy:$,onSave:Tt})}),F&&l.jsx(fs,{onClose:()=>k(null),label:f("fleet-cwd-repair-title").replace("{id}",F.id),error:"",children:l.jsx(hj,{token:e,route:re,cell:F,busy:$,onSaved:async()=>{k(null),te(f("fleet-cwd-repaired")),await _e()},onClose:()=>k(null)})}),Y&&l.jsx("div",{className:"nc-set-note",children:Y}),K&&l.jsx("div",{className:"nc-err",children:K}),I&&l.jsx(fs,{onClose:()=>D(!1),label:f("fleet-backup"),error:K,children:l.jsx(aj,{cells:a.cells,engines:a.engines,models:a.models||[],busy:$,canRestore:nt,onRestore:ce,onClose:()=>D(!1)})}),G&&l.jsx(fs,{onClose:()=>ue(null),label:f("fleet-credential-title"),error:K,children:l.jsxs("div",{className:"nc-fleet-form nc-credential-form",children:[l.jsx("b",{children:f("fleet-credential-title")}),l.jsx("small",{children:f("fleet-credential-help")}),l.jsxs("label",{className:"nc-field",children:[G.envKey,l.jsx("input",{type:"password",autoComplete:"off",spellCheck:"false",autoCapitalize:"none",value:G.value,onChange:j=>ue({...G,value:j.target.value})})]}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{className:"nc-btn ghost",onClick:()=>ue(null),children:f("cancel")}),l.jsx("button",{className:"nc-btn primary",disabled:$||!G.value,onClick:dt,children:f("save")})]})]})}),O&&l.jsx(fs,{onClose:()=>T(null),label:f("import-as-cell"),error:K,children:l.jsx(B_,{token:e,route:O.route||re,state:O,setState:T,busy:$,onSave:be})}),A&&l.jsx(Bl,{cell:A,token:e,route:Array.isArray(A.route)?A.route:re,onConfirm:async j=>{try{await st(j)}finally{await _e()}},onClose:()=>z(null)})]}):l.jsxs("div",{className:"nc-set-tab",children:[ne,le==="overview"?l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"nc-set-info",children:f("fleet-overview-help")}),l.jsx($d,{token:e,targets:n,readonly:t,onPower:ht,onImport:ft})]}):l.jsxs(l.Fragment,{children:[U,l.jsxs("div",{className:"nc-set-info",children:[f(K?"fleet-editor-load-error":"fleet-editor-unavailable"),!K&&h.reason?` ${h.reason}`:""]})]}),K&&l.jsx("div",{className:"nc-err",children:K}),O&&l.jsx(fs,{onClose:()=>T(null),label:f("import-as-cell"),error:K,children:l.jsx(B_,{token:e,route:O.route||re,state:O,setState:T,busy:$,onSave:be})}),A&&l.jsx(Bl,{cell:A,token:e,route:Array.isArray(A.route)?A.route:re,onConfirm:async j=>{try{await st(j)}finally{await _e()}},onClose:()=>z(null)})]}):l.jsxs("div",{className:"nc-set-tab",children:[ne,le==="overview"?l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"nc-set-info",children:f("fleet-overview-help")}),l.jsx($d,{token:e,targets:n,readonly:t,onPower:ht,onImport:ft})]}):l.jsxs(l.Fragment,{children:[U,l.jsx("div",{className:"nc-set-info",children:f("fleet-editor-loading")})]})]})}const Bf="nc_notification_speech_v1",Nl="nc-notification-speech",Hh="nc-notification-speech-preview",pj=320,mj=2,gj=3e4,vj=1e4,_j=6e4,yj=64,z_=Object.freeze({enabled:!1}),wj=Object.freeze({it:"it-IT",en:"en-US",es:"es-ES"}),bj=Object.freeze({it:new Set(["che","con","correzione","della","delle","difetto","il","lavoro","nessun","non","per","pronto","pubblicata","pubblicato","rilascio","sono","stato","tutti","verificata","verificato","versione","completata","completato","riepilogo"]),en:new Set(["all","and","completed","fix","for","issue","no","published","ready","release","summary","the","verified","version","with","work"]),es:new Set(["con","correccion","defecto","el","esta","para","publicada","publicado","resumen","sin","todos","trabajo","verificada","verificado","version","y"])}),zf=new WeakSet;function $f(e){return{enabled:(e&&typeof e=="object"&&!Array.isArray(e)?e:{}).enabled===!0}}function lb(){try{return typeof localStorage<"u"?localStorage:null}catch{return null}}function $_(e=lb()){if(!e)return{...z_};try{return $f(JSON.parse(e.getItem(Bf)||"null"))}catch{return{...z_}}}function Sj(e,t=lb()){const n=$f(e);if(t)try{t.setItem(Bf,JSON.stringify(n))}catch{}return n}function Ur(){try{return typeof window<"u"?window:null}catch{return null}}function ea(e=Ur()){try{return!!(e&&e.speechSynthesis&&typeof e.speechSynthesis.speak=="function"&&typeof e.SpeechSynthesisUtterance=="function")}catch{return!1}}function cb(e=Ur()){return!!(e&&(typeof e=="object"||typeof e=="function")&&zf.has(e))}function Wh(e=Ur()){e&&(typeof e=="object"||typeof e=="function")&&zf.delete(e)}function Tr(e){const t=String(e||"").trim().toLowerCase().split("-")[0];return wj[t]||""}function uc(e){return String(e||"").normalize("NFC").replace(/[\p{Cc}\p{Cf}]+/gu," ").replace(/\s+/g," ").trim()}function xj(e){const t=uc(e).normalize("NFD").replace(new RegExp("\\p{M}+","gu"),"").toLowerCase(),n=new Set(t.match(new RegExp("\\p{L}+","gu"))||[]);if(n.size<4)return"";const s=Object.entries(bj).map(([o,a])=>({lang:o,score:[...n].reduce((u,h)=>u+(a.has(h)?1:0),0)})).sort((o,a)=>a.score-o.score);return s[0].score>=3&&s[0].score-s[1].score>=2?s[0].lang:""}function kj(e,t){const n=Tr(e&&e.lang);return n||Tr(xj(e&&e.body))||Tr(t)}function ub(e){try{const t=e&&e.speechSynthesis&&e.speechSynthesis.getVoices;return typeof t=="function"?Array.from(t.call(e.speechSynthesis)||[]).filter(Boolean):[]}catch{return[]}}function db(e,t){const n=Tr(t);if(!n)return null;const s=Array.from(e||[]).filter(h=>h&&typeof h.lang=="string"&&h.lang.trim()),o=s.filter(h=>h.lang.trim().toLowerCase()===n.toLowerCase()),a=n.slice(0,2).toLowerCase(),u=s.filter(h=>h.lang.trim().toLowerCase().split("-")[0]===a);return o.find(h=>h.default===!0)||o[0]||u.find(h=>h.default===!0)||u[0]||null}function F_(e){return uc(e).replace(/\bBearer\s+\S+/gi,"Bearer [redacted]").replace(/\b(?:sk|hf|zai|xox[baprs]|gh[pousr]|npm)[_-][A-Za-z0-9._-]{8,}\b/gi,"[redacted]").replace(/\b(?:token|password|secret|credential|api[_-]?key)\s*[=:]\s*(?:"[^"]*"|'[^']*'|\S+)/gi,"[redacted]").replace(/\b[A-Z][A-Z0-9_]{2,}\s*=\s*(?:"[^"]*"|'[^']*'|\S+)/g,"[redacted]").replace(/(?:\/home\/[^/\s]+|\/Users\/[^/\s]+|\/data\/(?:data|user\/\d+)\/[^/\s]+)(?:\/[^\s]*)?/g,"[private path]").replace(/\b[A-Za-z]:\\Users\\[^\\\s]+(?:\\[^\s]*)?/g,"[private path]")}function Cj(e,t=pj){const n=F_(e&&e.title),s=F_(e&&e.body),o=[n,s&&s!==n?s:""].filter(Boolean).join(". "),a=Array.from(o);return a.length<=t?o:`${a.slice(0,Math.max(0,t-1)).join("").trimEnd()}…`}function Ej(e){try{return!!(e&&e.visibilityState==="visible"&&typeof e.hasFocus=="function"&&e.hasFocus())}catch{return!1}}function hb(e=Ur()){if(!ea(e))return!1;try{return e.speechSynthesis.cancel(),!0}catch{return!1}}function Nj(e){try{e&&typeof e.dispatchEvent=="function"&&typeof e.Event=="function"&&e.dispatchEvent(new e.Event(Hh))}catch{}}function jj(e,t,n=Ur(),s={}){var m;if(Wh(n),!ea(n))return Promise.resolve(!1);const o=uc(e);if(!o||(m=s.signal)!=null&&m.aborted)return Promise.resolve(!1);const a=Number.isFinite(s.timeoutMs)&&s.timeoutMs>0?s.timeoutMs:vj,u=s.setTimer||((v,y)=>setTimeout(v,y)),h=s.clearTimer||(v=>clearTimeout(v)),p=s.signal;return Nj(n),new Promise(v=>{let y=!1,w=!1,b=null,S=null;const C=x=>{if(!y){if(y=!0,p&&S&&p.removeEventListener("abort",S),b!==null&&h(b),x)zf.add(n);else try{n.speechSynthesis.cancel()}catch{}v(x)}};S=()=>C(!1),p&&p.addEventListener("abort",S,{once:!0});try{n.speechSynthesis.cancel();const x=new n.SpeechSynthesisUtterance(o);x.lang=Tr(t);const R=db(ub(n),x.lang);R&&(x.voice=R),x.onstart=()=>{w=!0},x.onend=()=>C(w),x.onerror=()=>C(!1),b=u(()=>C(!1),a),n.speechSynthesis.speak(x)}catch{C(!1)}})}function Rj(e={}){const t=e.scope||Ur(),n=e.document||t&&t.document,s=Number.isInteger(e.maxPending)&&e.maxPending>=0?e.maxPending:mj,o=Number.isFinite(e.watchdogMs)&&e.watchdogMs>0?e.watchdogMs:gj,a=Number.isFinite(e.dedupWindowMs)&&e.dedupWindowMs>0?e.dedupWindowMs:_j,u=Number.isInteger(e.maxDedup)&&e.maxDedup>0?e.maxDedup:yj,h=e.now||Date.now,p=e.setTimer||((H,L)=>setTimeout(H,L)),m=e.clearTimer||(H=>clearTimeout(H)),v=e.isPrimed||(()=>cb(t)),y=t&&t.speechSynthesis;let w=null,b=null,S=[],C=[],x=()=>{};const R=new Map,E=()=>{C=ub(t)};if(E(),y&&typeof y.addEventListener=="function")y.addEventListener("voiceschanged",E),x=()=>y.removeEventListener("voiceschanged",E);else if(y&&"onvoiceschanged"in y){const H=y.onvoiceschanged,L=(...A)=>{E(),typeof H=="function"&&H.apply(y,A)};y.onvoiceschanged=L,x=()=>{y.onvoiceschanged===L&&(y.onvoiceschanged=H)}}const $=H=>{if(H&&typeof H.id=="string"&&H.id)return`id:${H.id}`;const L=Number(H&&H.ts),A=uc(H&&H.title);return Number.isFinite(L)&&A?`frame:${L}:${A}`:""},B=H=>{if(!H)return!0;const L=h();for(const[A,z]of R)L-z>=a&&R.delete(A);if(R.has(H))return!1;for(R.set(H,L);R.size>u;)R.delete(R.keys().next().value);return!0},K=()=>{b!==null&&m(b),b=null},V=()=>{K(),w&&(w.onend=null,w.onerror=null,w=null),hb(t)},Y=H=>{if(!ea(t))return S=[],"unsupported";let L;try{L=new t.SpeechSynthesisUtterance(H.text),L.lang=Tr(H.lang);const z=db(C,L.lang);z&&(L.voice=z)}catch{return S=[],"error"}w=L;const A=()=>{if(w!==L)return;K(),w=null,L.onend=null,L.onerror=null;const z=S.shift();z&&Y(z)};L.onend=A,L.onerror=A;try{return b=p(()=>{if(w!==L)return;w=null,L.onend=null,L.onerror=null;try{t.speechSynthesis.cancel()}catch{}K();const z=S.shift();z&&Y(z)},o),t.speechSynthesis.speak(L),"speaking"}catch{return A(),"error"}},te=(H,L)=>{if(!ea(t))return"unsupported";const A=Cj(H);if(!A)return"empty";if(!B($(H)))return"duplicate";if(!Ej(n))return"inactive";if(!v())return"unprimed";const z={text:A,lang:L};return H&&H.urgency==="high"?(S=[],V(),Y(z)):w?s===0?"dropped":(S.length>=s&&S.shift(),S.push(z),"queued"):Y(z)},Q=()=>{S=[],V()};return{enqueue:te,stop:Q,dispose:()=>{Q(),x(),x=()=>{}}}}function fb(){const[e,t]=N.useState($_);N.useEffect(()=>{const s=o=>{if((o==null?void 0:o.type)==="storage"&&o.key!==Bf&&o.key!==null)return;const a=(o==null?void 0:o.type)===Nl?$f(o.detail):$_();t(a)};return window.addEventListener(Nl,s),window.addEventListener("storage",s),()=>{window.removeEventListener(Nl,s),window.removeEventListener("storage",s)}},[]);const n=N.useCallback(s=>{const o=Sj({enabled:s===!0});return t(o),window.dispatchEvent(new CustomEvent(Nl,{detail:o})),o.enabled},[]);return[e.enabled,n]}function Pj({text:e}){const[t,n]=N.useState(!1),s=async()=>{try{await navigator.clipboard.writeText(e),n(!0),setTimeout(()=>n(!1),1500)}catch{}};return l.jsxs("div",{className:"nc-set-copyline",children:[l.jsx("code",{children:e}),l.jsxs("button",{type:"button",className:"nc-btn ghost",onClick:s,children:[l.jsx(Ge,{name:"copy",size:14})," ",f(t?"copied":"copy")]})]})}function Aj({value:e}){const[t,n]=N.useState("");return N.useEffect(()=>{let s=!0;return a2.toDataURL(e,{margin:1,width:220}).then(o=>{s&&n(o)}).catch(()=>{}),()=>{s=!1}},[e]),t?l.jsx("img",{src:t,width:"220",height:"220",alt:"NexusCrew pairing QR"}):null}function Lj({token:e,nodes:t,roster:n,settings:s,readonly:o,refresh:a,refreshAliases:u,vlUnavailable:h=[]}){const[p,m]=N.useState(null),[v,y]=N.useState(null),[w,b]=N.useState(null),[S,C]=N.useState({ssh:"",sshPort:"",name:""}),[x,R]=N.useState(""),[E,$]=N.useState(""),[B,K]=N.useState(!1),[V,Y]=N.useState(null),te=Date.now(),Q=s&&s.deviceName||"",J=(t||[]).filter(k=>k&&k.direction==="outbound"&&k.name&&k.ssh),H=J.find(k=>k.name===x)||J[0]||null,L=H?Xd(H.tunnel,te):null,A=H!=null&&H.shared?L!=null&&L.up?"share-local-active":"share-local-pending":L!=null&&L.up?"share-local-private":"share-local-private-down",z=[{key:"peer-group-hubs",rows:(t||[]).filter(k=>k.kind!=="transitive"&&k.kind!=="vl"&&k.relation!=="client")},{key:"peer-group-clients",rows:(t||[]).filter(k=>k.kind!=="transitive"&&k.kind!=="vl"&&k.relation==="client")},{key:"peer-group-routed",rows:(t||[]).filter(k=>k.kind==="transitive")},{key:"peer-group-vl",rows:(t||[]).filter(k=>k.kind==="vl")}],O=V&&(t||[]).find(k=>`${k.kind||"direct"}:${k.nodeId||k.name}`===V)||null,T=async k=>{if(H){m(null),y(`${H.name}:share`);try{const I=await B0(e,H.name,k);await a(),I&&I.reversePoolPending===!0&&m(`${H.name}: ${f("share-reverse-pool-pending")}`)}catch(I){const D=I!=null&&I.data&&I.data.shared===!1?I.data:null;if(D)try{await a()}catch{}const M=I!=null&&I.data&&typeof I.data.hint=="string"?I.data.hint:"",W=(D==null?void 0:D.revoked)===!0&&(D==null?void 0:D.localReconcilePending)===!0?f("share-off-local-reconcile-pending"):(D==null?void 0:D.revoked)===!1&&(D==null?void 0:D.reconcilePending)===!0?f("share-off-hub-reconcile-pending"):"",G=I!=null&&I.data&&I.data.reversePoolPending===!0?f("share-reverse-pool-pending"):"",ue=I!=null&&I.data&&typeof I.data.code=="string"?I.data.code:"",le=I!=null&&I.data&&typeof I.data.detail=="string"?I.data.detail.trim():"",he=le&&le!==String(I.message||"")?le:"";m(`${H.name}: ${String(I.message||I)}${ue?` [${ue}]`:""}${he?` — ${he}`:""}${M?` — ${M}`:""}${W?` — ${W}`:""}${G?` — ${G}`:""}`)}y(null)}},F=async()=>{m(null);const k=_s(S.name||E||Q||"NexusCrew"),I=Fx({name:k,ssh:S.ssh,sshPort:S.sshPort});if(!I.ok){m(f(I.error));return}y("invite");try{b(await M0(e,{...E||Q?{label:E||Q}:{},name:k,ssh:I.value.ssh,...I.value.sshPort?{sshPort:I.value.sshPort}:{}}))}catch(D){m(String(D.message||D))}y(null)};return l.jsxs("div",{className:"nc-set-tab",children:[l.jsx("div",{className:"nc-sheet-label",children:f("peer-inventory-title")}),(t||[]).length===0&&l.jsx("div",{className:"nc-empty",children:f("no-nodes")}),z.map(k=>k.rows.length>0&&l.jsxs("div",{className:"nc-peer-group",children:[l.jsxs("div",{className:"nc-peer-group-title",children:[f(k.key)," ",l.jsx("span",{children:k.rows.length})]}),k.rows.map(I=>{const D=y2(I);if(!D)return null;const M=`${I.kind||"direct"}:${I.nodeId||I.name}`,W=D.routed?{up:D.reach.up,since:null}:Xd(I.tunnel,te);return l.jsxs("button",{type:"button",className:`nc-set-node nc-node-row${D.routed?" routed":""}`,"aria-label":`${D.title} — ${f("node-detail-open")}`,onClick:()=>Y(M),children:[l.jsx("span",{className:`nc-dot ${D.reach.up?"on":""}`}),l.jsxs("span",{className:"nc-node-row-text",children:[l.jsx("b",{children:D.title}),l.jsxs("small",{children:[D.routed?D.routeLabel:`${D.subtitle} · ${f(D.exposure.shortKey)}`,!D.routed&&D.exposure.shortKey==="visibility-selected"?` (${D.exposure.count})`:""]})]}),l.jsxs("span",{className:`nc-set-tunnel${D.reach.up?" up":""}`,children:[f(D.reach.key),W.since?` · ${W.since}`:""]}),l.jsx("span",{className:"nc-node-row-more",children:l.jsx(Ge,{name:"chevronDown",size:14})})]},M)})]},k.key)),h.length>0&&l.jsxs("div",{className:"nc-err",children:[f("vl-owners-unavailable"),": ",h.map(k=>k.label||k.route.join("/")).join(", ")]}),O&&l.jsx(M2,{node:O,nodes:t||[],token:e,readonly:o,refresh:a,onClose:()=>Y(null)}),(n||[]).some(k=>!k.direct&&k.instanceId)&&l.jsxs("div",{className:"nc-set-form",children:[l.jsx("div",{className:"nc-sheet-label",children:f("routed-node-aliases")}),l.jsx("small",{className:"nc-set-hint",children:f("routed-node-aliases-help")}),(n||[]).filter(k=>!k.direct&&k.instanceId).map(k=>l.jsxs("div",{className:"nc-set-node",children:[l.jsxs("div",{className:"nc-set-node-head",children:[l.jsx("span",{className:`nc-dot ${k.status==="up"?"on":""}`}),l.jsx("b",{children:k.label||k.name}),l.jsx("small",{children:(k.route||[]).join(" › ")})]}),l.jsxs("div",{className:"nc-set-node-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:o||!!v,onClick:async()=>{const I=window.prompt(f("node-local-alias"),k.alias||"");if(I!=null){if(I.trim()&&!Ir(I.normalize("NFC"))){m(f("err-label"));return}y(`${k.instanceId}:alias`),m(null);try{I.trim()?await I0(e,k.instanceId,I):await xg(e,k.instanceId),u()}catch(D){m(String(D.message||D))}y(null)}},children:f("alias-on-device")}),k.alias&&l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:o||!!v,onClick:async()=>{y(`${k.instanceId}:alias-reset`),m(null);try{await xg(e,k.instanceId),u()}catch(I){m(String(I.message||I))}y(null)},children:f("reset-alias")})]})]},k.instanceId))]}),H&&l.jsxs("div",{className:"nc-set-form nc-local-share",children:[l.jsx("div",{className:"nc-sheet-label",children:f("share-local-heading")}),J.length>1&&l.jsxs("label",{className:"nc-field",children:[f("share-local-hub"),l.jsx("select",{value:H.name,disabled:o||!!v,onChange:k=>R(k.target.value),children:J.map(k=>l.jsx("option",{value:k.name,children:k.label||k.name},k.name))})]}),l.jsxs("label",{className:"nc-check nc-node-share",children:[l.jsx("input",{type:"checkbox",checked:H.shared===!0,disabled:o||!!v,onChange:k=>T(k.target.checked)}),l.jsxs("span",{children:[l.jsx("b",{children:f("share-local-through").replace("{device}",Q||f("local")).replace("{hub}",H.label||H.name)}),l.jsx("small",{children:f(H.shared?"share-node-on-desc":"share-node-off-desc")})]})]}),l.jsx("div",{className:`nc-set-test${H.shared&&(L!=null&&L.up)?" ok":L!=null&&L.up?"":" ko"}`,children:f(A)}),!(L!=null&&L.up)&&l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:o||!!v,onClick:()=>T(H.shared===!0),children:f("share-local-reconnect")})]}),l.jsx(Xw,{token:e,deviceDefault:Q,localNodeId:s&&s.nodeId||"",localNameDefault:s&&s.localName||"",readonly:o,onSuccess:a}),l.jsxs("div",{className:"nc-set-form",children:[l.jsx("div",{className:"nc-sheet-label",children:f("invite-node")}),l.jsx("small",{className:"nc-set-hint",children:f("invite-v2-hint")}),l.jsxs("div",{className:"nc-set-info nc-invite-endpoint",children:[f("invite-target-local"),": ",l.jsx("b",{children:Q||f("invite-target-this")})]}),l.jsxs("label",{className:"nc-field",children:[f("invite-endpoint-label"),l.jsx("input",{placeholder:"user@host",value:S.ssh,disabled:o,onChange:k=>C({...S,ssh:k.target.value})}),l.jsx("small",{className:"nc-set-hint",children:f("invite-endpoint-needed")})]}),J.length>0&&l.jsx("small",{className:"nc-set-hint nc-invite-hub-hint",children:f("invite-hub-only")}),B&&l.jsxs("div",{className:"nc-invite-advanced",children:[l.jsxs("label",{className:"nc-field",children:[f("node-ssh-port-label"),l.jsx("input",{inputMode:"numeric",placeholder:"22",value:S.sshPort,disabled:o,onChange:k=>C({...S,sshPort:k.target.value.replace(/[^0-9]/g,"").slice(0,5)})})]}),l.jsxs("label",{className:"nc-field",children:[f("device-name-label"),l.jsx("input",{placeholder:Q||"NexusCrew",value:E,disabled:o,onChange:k=>$(k.target.value)}),l.jsx("small",{className:"nc-set-hint",children:f("device-name-hint")})]}),l.jsxs("label",{className:"nc-field",children:[f("node-name-label"),l.jsx("input",{placeholder:_s(E||Q||f("node-name-ph")),value:S.name,disabled:o,onChange:k=>C({...S,name:k.target.value?_s(k.target.value):""})})]})]}),l.jsxs("div",{className:"nc-set-row nc-invite-actions",children:[l.jsx("button",{type:"button",className:"nc-btn primary",disabled:o||!!v||!S.ssh.trim(),onClick:F,children:f("create-pairing-link")}),l.jsxs("button",{type:"button",className:"nc-btn ghost",disabled:!!v,onClick:()=>K(k=>!k),children:[B?"▾":"▸"," ",f("pair-advanced")]})]}),w&&l.jsxs(l.Fragment,{children:[l.jsx(Aj,{value:w.pairingUrl}),l.jsx(Pj,{text:w.pairingUrl}),l.jsx("div",{className:"nc-set-info",children:f("invite-next-steps")})]})]}),p&&l.jsx("div",{className:"nc-err",children:p})]})}function Tj({token:e,readonly:t}){const[n,s]=N.useState("idle"),[o,a]=N.useState(!1),[u,h]=N.useState(null);N.useEffect(()=>{let m=!1;return I2().then(v=>{m||s(v)}),()=>{m=!0}},[]);const p=async()=>{h(null),a(!0);try{n==="subscribed"?(await B2(e),s("idle")):(await O2(e),s("subscribed"))}catch(m){const v=String(m.message||m);v==="push-denied"?(s("denied"),h(f("push-denied"))):v==="push-unsupported"?(s("unsupported"),h(f("push-unsupported"))):h(v)}a(!1)};return n==="unsupported"?l.jsx("div",{className:"nc-set-info",children:f("push-unsupported")}):l.jsxs(l.Fragment,{children:[l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:t||o||n==="denied",title:t?f("settings-readonly"):"",onClick:p,children:f(n==="subscribed"?"push-disable":"push-enable")}),l.jsx("span",{className:"nc-set-info",children:f(n==="subscribed"?"push-on":n==="denied"?"push-denied":"push-off")})]}),u&&l.jsx("div",{className:"nc-err",children:u})]})}function Mj(){const[e,t]=fb(),[n,s]=N.useState(""),[o,a]=N.useState(""),[u,h]=N.useState(!1),[p,m]=N.useState(cb),v=N.useRef(0),y=N.useRef(!1),w=N.useRef(null),b=ea();N.useEffect(()=>()=>{var x;v.current+=1,y.current&&((x=w.current)==null||x.abort(),w.current=null,y.current=!1,Wh())},[]);const S=async()=>{const x=v.current+=1,R=typeof AbortController=="function"?new AbortController:null;s(""),a(""),h(!0),m(!1),y.current=!0,w.current=R;const E=await jj(f("notification-speech-preview"),Ol(),void 0,R?{signal:R.signal}:{});return x!==v.current||(w.current=null,y.current=!1,h(!1),m(E),E?a(f("notification-speech-preview-ok")):s(f("notification-speech-preview-failed"))),E},C=x=>{var R;if(t(x),s(""),a(""),x)S();else{v.current+=1;const E=y.current;(R=w.current)==null||R.abort(),w.current=null,y.current=!1,h(!1),m(!1),Wh(),E||hb()}};return l.jsxs("div",{className:"nc-set-form",children:[l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox","aria-label":f("notification-speech-enable"),checked:e,disabled:!b,onChange:x=>C(x.target.checked)}),l.jsxs("span",{children:[l.jsx("b",{children:f("notification-speech-enable")}),l.jsx("small",{children:f("notification-speech-help")})]})]}),b?l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:!e||u,onClick:()=>{S()},children:f(u?"notification-speech-testing":"notification-speech-test")})}):l.jsx("div",{className:"nc-set-info",children:f("notification-speech-unsupported")}),e&&!p&&!u&&!n&&l.jsx("div",{className:"nc-set-info",children:f("notification-speech-needs-test")}),o&&l.jsx("div",{className:"nc-set-info",role:"status",children:o}),n&&l.jsx("div",{className:"nc-err",children:n})]})}function Dj({token:e,readonly:t,nodes:n=[],settings:s=null}){const[o,a]=N.useState(null),[u,h]=N.useState([]),[p,m]=N.useState({name:"",mode:"primary-failover",targets:[]}),[v,y]=N.useState(null),[w,b]=N.useState(!1),[S,C]=N.useState(null),[x,R]=N.useState(""),E=N.useCallback(async()=>{try{const[F,k]=await Promise.all([$0(e),U0(e)]);a(F),h(Array.isArray(k==null?void 0:k.groups)?k.groups:[]),R("")}catch(F){R(String(F.message||F))}},[e]);N.useEffect(()=>{E()},[E]);const $=async F=>{b(!0),C(null),R("");try{a(await F0(e,F))}catch(k){R(String(k.message||k))}b(!1)},B=async()=>{b(!0),C(null),R("");try{C({kind:"test",...await H0(e)})}catch(F){R(String(F.message||F))}b(!1)},K=async()=>{b(!0),C(null),R("");try{C({kind:"stop",...await W0(e)})}catch(F){R(String(F.message||F))}b(!1)},V=[],Y=new Set,te=(F,k)=>{const I=typeof F=="string"?F.toLowerCase():"";!/^[a-f0-9]{32}$/.test(I)||Y.has(I)||(Y.add(I),V.push({id:I,label:k||I}))};te(s==null?void 0:s.nodeId,f("audio-group-local"));for(const F of n||[])te((F==null?void 0:F.nodeId)||(F==null?void 0:F.instanceId),(F==null?void 0:F.label)||(F==null?void 0:F.name)||(F==null?void 0:F.nodeId));for(const F of p.targets)te(F,`${F} (${f("audio-group-unavailable-target")})`);const Q=(F=null)=>{R(""),F?(y(F.name),m({name:F.name,mode:F.mode,targets:[...F.targets||[]]})):(y(null),m({name:"",mode:"primary-failover",targets:[]}))},J=(F,k)=>m(I=>({...I,targets:k?[...new Set([...I.targets,F])]:I.targets.filter(D=>D!==F)})),H=async()=>{const F=p.name.trim().toLowerCase();if(!/^[a-z0-9][a-z0-9-]{0,31}$/.test(F)||p.targets.length<1){R(f("audio-group-invalid"));return}b(!0),R("");try{const k=await K0(e,F,{targets:p.targets,mode:p.mode}),I=k==null?void 0:k.group;if(!I||!I.name)throw new Error(f("audio-group-save-failed"));h(D=>[...D.filter(M=>M.name!==I.name),I].sort((M,W)=>M.name.localeCompare(W.name))),Q(null)}catch(k){R(String(k.message||k))}b(!1)},L=async F=>{b(!0),R("");try{await q0(e,F),h(k=>k.filter(I=>I.name!==F)),v===F&&Q(null)}catch(k){R(String(k.message||k))}b(!1)},A=(o==null?void 0:o.installed)===!0,z=(o==null?void 0:o.liveness)==="ready",O=(o==null?void 0:o.consent)===!0&&A&&z,T=S?S.kind==="stop"?f(S.stopped?"audio-stop-stopped":"audio-stop-idle"):S.status==="accepted"||S.status==="spoken"?f("audio-test-accepted"):S.status==="unknown"?f("audio-test-unknown"):`${f("audio-test-refused")}${S.reason?` (${S.reason})`:""}`:"";return l.jsxs("div",{className:"nc-set-tab nc-audio-settings",children:[l.jsxs("div",{className:"nc-set-info",children:[l.jsx("b",{children:f("audio-title")}),l.jsx("br",{}),f("audio-help")]}),o?l.jsxs(l.Fragment,{children:[l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox","aria-label":f("audio-consent"),checked:o.consent===!0,disabled:t||w,onChange:F=>{$(F.target.checked)}}),l.jsxs("span",{children:[l.jsx("b",{children:f("audio-consent")}),l.jsx("small",{children:f("audio-consent-help")})]})]}),l.jsxs("div",{className:"nc-set-form",children:[l.jsx("div",{className:"nc-sheet-label",children:f("audio-capability")}),l.jsxs("div",{className:"nc-set-info",children:[f("audio-adapter"),": ",o.adapter||f("audio-adapter-none"),l.jsx("br",{}),f("audio-installed"),": ",f(A?"audio-installed-yes":"audio-installed-no"),l.jsx("br",{}),f("audio-liveness"),": ",f(z?"audio-liveness-ready":"audio-liveness-unavailable"),Array.isArray(o.languages)&&o.languages.length>0&&l.jsxs(l.Fragment,{children:[l.jsx("br",{}),f("audio-languages"),": ",o.languages.join(", ")]})]}),o.limits&&l.jsxs("small",{className:"nc-set-hint",children:[f("audio-limits"),": ",o.limits]})]}),!o.consent&&l.jsx("div",{className:"nc-set-info",children:f("audio-test-needs-consent")}),!A&&l.jsx("div",{className:"nc-set-info",children:f("audio-unavailable")}),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn primary",disabled:t||w||!O,title:t?f("settings-readonly"):"",onClick:()=>{B()},children:f(w?"audio-testing":"audio-test")}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:w,onClick:()=>{K()},children:f(w?"audio-stopping":"audio-stop")}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:w,onClick:()=>{E()},children:f("refresh")})]}),l.jsxs("div",{className:"nc-set-form",children:[l.jsx("div",{className:"nc-sheet-label",children:f("audio-groups-title")}),l.jsx("small",{className:"nc-set-hint",children:f("audio-groups-help")}),u.length===0&&l.jsx("div",{className:"nc-set-info",children:f("audio-groups-empty")}),u.map(F=>{var k;return l.jsxs("div",{className:"nc-set-row",children:[l.jsxs("span",{children:[l.jsx("b",{children:F.name})," ",l.jsxs("small",{children:["· ",F.mode==="fanout"?f("audio-group-fanout"):f("audio-group-primary")," · ",((k=F.targets)==null?void 0:k.length)||0]})]}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:t||w,onClick:()=>Q(F),children:f("audio-group-edit")}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:t||w,onClick:()=>{L(F.name)},children:f("audio-group-delete")})]},F.name)}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:t||w,onClick:()=>Q(null),children:f("audio-group-new")})}),l.jsxs("label",{className:"nc-field",children:[f("audio-group-name"),l.jsx("input",{"aria-label":f("audio-group-name"),value:p.name,maxLength:"32",disabled:t||w,onChange:F=>m(k=>({...k,name:F.target.value}))})]}),l.jsxs("label",{className:"nc-field",children:[f("audio-group-mode"),l.jsxs("select",{"aria-label":f("audio-group-mode"),value:p.mode,disabled:t||w,onChange:F=>m(k=>({...k,mode:F.target.value})),children:[l.jsx("option",{value:"primary-failover",children:f("audio-group-primary")}),l.jsx("option",{value:"fanout",children:f("audio-group-fanout")})]})]}),l.jsx("div",{className:"nc-set-info",children:f("audio-group-targets")}),V.length===0?l.jsx("small",{className:"nc-set-hint",children:f("audio-group-no-targets")}):V.map(F=>l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:p.targets.includes(F.id),disabled:t||w,onChange:k=>J(F.id,k.target.checked)}),l.jsxs("span",{children:[F.label,l.jsx("small",{children:F.id})]})]},F.id)),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn primary",disabled:t||w,onClick:()=>{H()},children:f("audio-group-save")}),v&&l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:w,onClick:()=>Q(null),children:f("audio-group-cancel")})]})]})]}):l.jsx("div",{className:"nc-set-info",children:f("audio-loading")}),T&&l.jsx("div",{className:"nc-set-note",role:"status",children:T}),x&&l.jsx("div",{className:"nc-err",children:x})]})}function Ij(){const[e,t]=Cf();return l.jsxs("div",{className:"nc-set-tab nc-input-settings",children:[l.jsx("div",{className:"nc-set-info",children:f("input-settings-local")}),l.jsxs("div",{className:"nc-set-form",children:[l.jsxs("label",{className:"nc-field",children:[f("terminal-keyboard-gesture"),l.jsx("select",{"aria-label":f("terminal-keyboard-gesture"),value:e.terminalKeyboardGesture,onChange:n=>t({terminalKeyboardGesture:n.target.value}),children:jw.map(n=>l.jsx("option",{value:n,children:f(`terminal-keyboard-${n}`)},n))}),l.jsx("small",{children:f("terminal-keyboard-gesture-help")})]}),l.jsxs("label",{className:"nc-field",children:[f("keybar-layout"),l.jsx("select",{"aria-label":f("keybar-layout"),value:e.keybarLayout,onChange:n=>t({keybarLayout:n.target.value}),children:Rw.map(n=>l.jsx("option",{value:n,children:f(`keybar-layout-${n}`)},n))}),l.jsx("small",{children:f("keybar-layout-help")})]})]}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:e.keybarKeepsKeyboardClosed,onChange:n=>t({keybarKeepsKeyboardClosed:n.target.checked})}),l.jsxs("span",{children:[l.jsx("b",{children:f("keybar-ime-lock")}),l.jsx("small",{children:f("keybar-ime-lock-help")})]})]}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:e.voiceKeepsKeyboardClosed,onChange:n=>t({voiceKeepsKeyboardClosed:n.target.checked})}),l.jsxs("span",{children:[l.jsx("b",{children:f("voice-ime-lock")}),l.jsx("small",{children:f("voice-ime-lock-help")})]})]}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:e.showKeybarEnter,onChange:n=>t({showKeybarEnter:n.target.checked})}),l.jsxs("span",{children:[l.jsx("b",{children:f("keybar-enter-show")}),l.jsx("small",{children:f("keybar-enter-show-help")})]})]}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>t(ms),children:f("input-settings-reset")})})]})}function Oj({token:e,roster:t=[],readonly:n}){const s=[{key:"local",route:[],label:f("diagnostics-local"),status:"up"},...t.filter(O=>Array.isArray(O.route)&&O.route.length).map(O=>({key:O.route.join("/"),route:O.route,label:O.label||O.name,status:O.status}))],[o,a]=N.useState("local"),u=s.find(O=>O.key===o)||s[0],[h,p]=N.useState(null),[m,v]=N.useState([]),[y,w]=N.useState(""),[b,S]=N.useState(!1),[C,x]=N.useState(!0),[R,E]=N.useState(900),[$,B]=N.useState("all"),[K,V]=N.useState(""),Y=N.useRef(0),te=N.useRef(null),Q=N.useCallback(async()=>{try{const O=await X0(e,u.route);if(p(O),w(""),!b){const T=await Q0(e,{after:Y.current,limit:200},u.route);Array.isArray(T.records)&&T.records.length&&(Y.current=T.cursor,v(F=>[...F,...T.records].slice(-500)))}}catch(O){w(O&&O.status===404?f("diagnostics-unsupported"):String(O.message||O))}},[e,u.key,b]);N.useEffect(()=>{Y.current=0,v([]),p(null),w("")},[u.key]),N.useEffect(()=>{let O=null,T=!0;const F=()=>{!T||document.visibilityState==="hidden"||Q()},k=()=>{O&&clearInterval(O),O=document.visibilityState==="hidden"?null:setInterval(F,2e3),document.visibilityState!=="hidden"&&F()};return document.addEventListener("visibilitychange",k),k(),()=>{T=!1,O&&clearInterval(O),document.removeEventListener("visibilitychange",k)}},[Q]),N.useEffect(()=>{C&&te.current&&(te.current.scrollTop=te.current.scrollHeight)},[m,C]);const J=m.filter(O=>($==="all"||O.level===$)&&(!K||String(O.component||"").toLowerCase().includes(K.toLowerCase()))),H=J.map(O=>`${O.ts} ${O.level.toUpperCase()} ${O.component} ${O.code} ${O.message}${Object.keys(O.meta||{}).length?` ${JSON.stringify(O.meta)}`:""}`).join(`
92
92
  `),L=async O=>{w("");try{const T=await O();p(T),await Q()}catch(T){w(String(T.message||T))}},A=async()=>{try{await navigator.clipboard.writeText(H)}catch{w(f("copy-manual"))}},z=()=>{try{const O=new Blob([`${JSON.stringify(J,null,2)}
93
- `],{type:"application/json"}),T=URL.createObjectURL(O),F=document.createElement("a");F.href=T,F.download="nexuscrew-diagnostics.json",F.click(),URL.revokeObjectURL(T)}catch{w(f("diagnostics-export-failed"))}};return l.jsxs("div",{className:"nc-set-tab nc-diagnostics",children:[l.jsxs("label",{className:"nc-field",children:[f("diagnostics-target"),l.jsx("select",{value:u.key,onChange:O=>a(O.target.value),children:s.map(O=>l.jsxs("option",{value:O.key,children:[O.label,O.status!=="up"?` · ${O.status}`:""]},O.key))})]}),l.jsxs("div",{className:"nc-set-form nc-diag-controls",children:[l.jsx("div",{className:"nc-sheet-label",children:f("diagnostics-verbose")}),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("select",{"aria-label":f("diagnostics-duration"),value:R,onChange:O=>E(Number(O.target.value)),disabled:n,children:[300,900,1800,3600].map(O=>l.jsxs("option",{value:O,children:[O/60," min"]},O))}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:n||(h==null?void 0:h.verbose)===!0,onClick:()=>L(()=>Cg(e,!0,R,u.route)),children:f("enable")}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||(h==null?void 0:h.verbose)!==!0,onClick:()=>L(()=>Cg(e,!1,R,u.route)),children:f("stop")})]}),l.jsx("small",{className:"nc-set-hint",children:h!=null&&h.verbose?f("diagnostics-expires").replace("{time}",new Date(h.expiresAt).toLocaleTimeString()):f("diagnostics-off")})]}),l.jsxs("div",{className:"nc-diag-filters",children:[l.jsxs("select",{"aria-label":f("diagnostics-level"),value:$,onChange:O=>B(O.target.value),children:[l.jsx("option",{value:"all",children:f("diagnostics-all-levels")}),["debug","info","warn","error"].map(O=>l.jsx("option",{value:O,children:O},O))]}),l.jsx("input",{"aria-label":f("diagnostics-component"),placeholder:f("diagnostics-component"),value:K,onChange:O=>V(O.target.value)})]}),l.jsxs("div",{className:"nc-set-row",children:[l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:b,onChange:O=>S(O.target.checked)})," ",f("diagnostics-pause")]}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:C,onChange:O=>x(O.target.checked)})," ",f("diagnostics-autoscroll")]})]}),l.jsx("pre",{ref:te,className:"nc-diag-log","aria-label":f("diagnostics-log"),children:H||f("diagnostics-empty")}),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:A,children:f("copy")}),l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:z,children:f("diagnostics-export")}),l.jsx("button",{type:"button",className:"nc-btn danger",disabled:n,onClick:()=>{window.confirm(f("diagnostics-clear-confirm"))&&L(async()=>{const O=await J0(e,u.route);return Y.current=0,v([]),O})},children:f("diagnostics-clear")})]}),y&&l.jsx("div",{className:"nc-err",children:y})]})}function Bj({token:e,settings:t,readonly:n,refresh:s,roster:o,section:a,setSection:u}){const[h,p]=N.useState(null),[m,v]=N.useState(null),[y,w]=N.useState(!1),[b,S]=N.useState(!1),[C,x]=N.useState(null),[R,E]=N.useState(!0),[$,B]=N.useState(!1);N.useEffect(()=>{x(t&&t.update||null),E(!t||t.autoUpdate!==!1),B(!!(t&&t.alternateScreen))},[t]);const K=async()=>{p(null),v(null),S(!0);try{const A=await L0(e);v(A.note||"ok"),w(!1)}catch(A){p(String(A.message||A))}S(!1)},V=async()=>{p(null),v(null),S(!0);try{const A=await V0(e);v(`${A.note||"ok"}${A.target?` (${A.target})`:""}`)}catch(A){p(String(A.message||A))}S(!1)},Y=async A=>{p(null),v(null),S(!0);try{await Kd(e,{autoUpdate:A}),E(A),s&&await s()}catch(z){p(String(z.message||z))}S(!1)},te=async A=>{p(null),v(null),S(!0);try{await Kd(e,{alternateScreen:A}),B(A),s&&await s()}catch(z){p(String(z.message||z))}S(!1)},Q=async()=>{p(null),v(null),S(!0);try{x(await Y0(e))}catch(A){p(String(A.message||A))}S(!1)},J=async()=>{p(null),v(null),S(!0);try{const A=await G0(e);x(A),v(f("npm-update-restarting"))}catch(A){p(String(A.message||A))}S(!1)},H=()=>{window.confirm(f("composer-clear-confirm"))&&(p(null),XE()?(window.dispatchEvent(new Event(Ih)),v(f("composer-clear-done"))):p(f("composer-clear-failed")))},L=t&&t.service;return l.jsxs("div",{className:"nc-set-tab",children:[l.jsx("div",{className:"nc-system-tabs",role:"tablist","aria-label":f("tab-system"),children:["general","diagnostics"].map(A=>l.jsx("button",{type:"button",role:"tab","aria-selected":a===A,className:`nc-set-tabbtn${a===A?" on":""}`,onClick:()=>u(A),children:f(`system-${A}`)},A))}),a==="general"&&l.jsxs(l.Fragment,{children:[l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:f("system-this-node")}),t&&l.jsxs("div",{className:"nc-set-info",children:["v",t.version," · ",t.platform," · :",t.port,l.jsx("br",{}),L&&L.installed?f("service-installed"):f("service-missing"),L&&L.installed?` · ${L.active?f("service-active"):f("service-inactive")}`:"",L?` · boot ${L.boot?"on":"off"}`:""]}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||b,title:n?f("settings-readonly"):"",onClick:V,children:f("service-regenerate")})}),l.jsx(Tj,{token:e,readonly:n}),l.jsx(Mj,{})]}),l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:f("system-updates")}),l.jsxs("div",{className:"nc-set-form nc-update-settings",children:[l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:R,disabled:n||b||C&&!C.supported,onChange:A=>Y(A.target.checked)}),l.jsxs("span",{children:[l.jsx("b",{children:f("npm-auto-update")}),l.jsx("small",{children:f("npm-auto-update-help")})]})]}),C&&l.jsxs("div",{className:"nc-set-info",children:[f("npm-update-current")," v",C.current,C.latest?` · ${f("npm-update-latest")} v${C.latest}`:""," · ",f(`npm-update-${C.supported?C.phase:"unsupported"}`)]}),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||b||!C||!C.supported,onClick:Q,children:f("npm-update-check")}),C&&C.available&&l.jsx("button",{type:"button",className:"nc-btn primary",disabled:n||b||C.phase==="installing",onClick:J,children:f("npm-update-install")})]}),C&&C.lastError&&l.jsx("div",{className:"nc-err",children:C.lastError})]})]}),l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:f("system-security")}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||b,title:n?f("settings-readonly"):"",onClick:()=>{p(null),v(null),w(!0)},children:f("token-rotate")})})]}),l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:f("system-local-data")}),l.jsxs("div",{className:"nc-set-form",children:[l.jsx("div",{className:"nc-sheet-label",children:f("composer-clear-data")}),l.jsx("small",{className:"nc-set-hint",children:f("composer-clear-data-help")}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:H,children:f("composer-clear-data")})})]})]})]}),a==="diagnostics"&&l.jsxs("section",{className:"nc-system-group nc-system-diagnostics",children:[l.jsx("h3",{children:f("system-diagnostics")}),l.jsxs("div",{className:"nc-set-form nc-alternate-screen-settings",children:[l.jsx("div",{className:"nc-sheet-label",children:f("system-terminal")}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox","aria-label":f("alternate-screen"),checked:$,disabled:n||b,onChange:A=>te(A.target.checked)}),l.jsxs("span",{children:[l.jsx("b",{children:f("alternate-screen")}),l.jsx("small",{children:f("alternate-screen-help")})]})]})]}),l.jsx(Oj,{token:e,roster:o,readonly:n})]}),y&&l.jsxs("div",{className:"nc-set-confirm",children:[l.jsx("div",{children:f("token-rotate-explain")}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:b,onClick:()=>w(!1),children:f("cancel")}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:b,onClick:K,children:f("confirm")})]})]}),m&&l.jsx("div",{className:"nc-set-note",children:m}),h&&l.jsx("div",{className:"nc-err",children:h})]})}function zj({token:e,onClose:t,initialTab:n="nodes",initialLocation:s="",startNewCell:o=!1}){En();const a=n==="diagnostics"?"diagnostics":"general",[u,h]=N.useState(n==="diagnostics"?"system":n),p=N.useRef(null),m=N.useRef(null),[v,y]=N.useState({start:!1,end:!1}),[w,b]=N.useState(a),[S,C]=N.useState(null),[x,R]=N.useState([]),[E,$]=N.useState([]),[B,K]=N.useState(!1),[V,Y]=N.useState(null),[te,Q]=N.useState(0),J=sf(e,!0,te),H=N.useCallback(()=>{const A=p.current;if(!A)return;const z=A.scrollWidth>A.clientWidth+1,O={start:z&&A.scrollLeft>1,end:z&&A.scrollLeft+A.clientWidth<A.scrollWidth-1};y(T=>T.start===O.start&&T.end===O.end?T:O)},[]);N.useEffect(()=>{const A=p.current;if(!A)return;const z=typeof ResizeObserver=="function"?new ResizeObserver(H):null;return z==null||z.observe(A),window.addEventListener("resize",H),H(),()=>{z==null||z.disconnect(),window.removeEventListener("resize",H)}},[H]),N.useEffect(()=>{var z,O;(O=(z=m.current)==null?void 0:z.scrollIntoView)==null||O.call(z,{behavior:"smooth",block:"nearest",inline:"nearest"});const A=window.requestAnimationFrame?window.requestAnimationFrame(H):setTimeout(H,0);return()=>{window.cancelAnimationFrame?window.cancelAnimationFrame(A):clearTimeout(A)}},[u,H]);const L=N.useCallback(async()=>{var A;try{const z=await ny(e);C(z),Y(null)}catch(z){Y(String(z.message||z))}try{const O=(await P0(e)).peers||[];let T=[],F=[];try{const[k,I]=await Promise.all([Ut("/api/config",e).then(G=>G.json()).catch(()=>null),sy(e).catch(()=>null)]),D=k&&typeof k.instanceId=="string"?k.instanceId:"",M=[{instanceId:D||null,route:[],label:null},...fy(I,D)],W=await Promise.all(M.map(async G=>{try{return{ok:!0,peers:((await iy(e,G.route)).nodes||[]).map(he=>hy(he,G)).filter(Boolean)}}catch(ue){return{ok:!1,owner:G,error:ue}}}));for(const G of W){if(G.ok){T.push(...G.peers);continue}G.owner.route.length!==0&&F.push({instanceId:G.owner.instanceId,label:G.owner.label,route:G.owner.route,failure:/timeout/i.test(String(((A=G.error)==null?void 0:A.message)||G.error))?"timeout":"unreachable"})}}catch{}$(F),R([...O,...T])}catch(z){Y(String(z.message||z))}},[e]);return N.useEffect(()=>{L();const A=setInterval(L,5e3);return()=>clearInterval(A)},[L]),N.useEffect(()=>{let A=!1;return Ut("/api/config",e).then(z=>z.json()).then(z=>{A||K(!!z.readonlyDefault)}).catch(()=>{}),()=>{A=!0}},[e]),l.jsx("div",{className:"nc-set-overlay",onClick:t,children:l.jsxs("div",{className:"nc-set-panel",onClick:A=>A.stopPropagation(),children:[l.jsxs("div",{className:"nc-set-head",children:[l.jsx(Ge,{name:"gear",size:18}),l.jsx("b",{children:f("settings")}),l.jsx("button",{type:"button",className:"nc-set-close",onClick:t,title:f("close"),children:l.jsx(Ge,{name:"x",size:18})})]}),B&&l.jsx("div",{className:"nc-set-readonly",children:f("settings-readonly")}),V&&l.jsx("div",{className:"nc-err",children:V}),l.jsx("div",{className:`nc-set-tabs-wrap${v.start?" has-start-overflow":""}${v.end?" has-end-overflow":""}`,children:l.jsx("div",{className:"nc-set-tabs",ref:p,onScroll:H,children:["nodes","fleet","audio","input","system"].map(A=>l.jsx("button",{ref:u===A?m:null,type:"button",className:`nc-set-tabbtn${u===A?" on":""}`,onClick:()=>h(A),children:f(`tab-${A}`)},A))})}),l.jsxs("div",{className:"nc-set-body",children:[u==="nodes"&&l.jsx(Lj,{token:e,nodes:x,roster:J,settings:S,readonly:B,vlUnavailable:E,refresh:L,refreshAliases:()=>Q(A=>A+1)}),u==="fleet"&&l.jsx(fj,{token:e,readonly:B,startNewCell:o,initialLocation:s,targets:J.map(A=>({route:A.route,label:A.label||A.name,status:A.status}))}),u==="audio"&&l.jsx(Dj,{token:e,readonly:B,nodes:x,settings:S}),u==="input"&&l.jsx(Ij,{}),u==="system"&&l.jsx(Bj,{token:e,settings:S,readonly:B,refresh:L,roster:J,section:w,setSection:b})]})]})})}function $j({token:e,initialPair:t,deviceDefault:n="",localNodeId:s="",localNameDefault:o="",onPairDone:a,onDone:u}){En();const[h,p]=N.useState(t?"pair":"welcome"),[m,v]=N.useState(!1),[y,w]=N.useState(null),b=async()=>{v(!0),w(null);try{await Kd(e,{wizardDone:!0}),a&&a(),u()}catch(S){w(String(S.message||S)),v(!1)}};return l.jsx("div",{className:"nc-wiz-overlay",children:l.jsxs("div",{className:"nc-wiz",children:[l.jsxs("div",{className:"nc-wiz-head",children:[l.jsx("b",{children:f("wizard-title")}),l.jsx("small",{children:f("hydra-simple")})]}),h==="welcome"&&l.jsxs("div",{className:"nc-wiz-body",children:[l.jsx("div",{className:"nc-wiz-done",children:f("local-ready")}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{className:"nc-btn ghost",disabled:m,onClick:b,children:f("local-only")}),l.jsx("button",{className:"nc-btn primary",disabled:m,onClick:()=>p("pair"),children:f("add-node")})]})]}),h==="pair"&&l.jsxs("div",{className:"nc-wiz-body",children:[l.jsx(Xw,{token:e,initial:t||"",autoStart:!!t,deviceDefault:n,localNodeId:s,localNameDefault:o,onBusyChange:v,onSuccess:async()=>{a&&a(),p("done")}}),l.jsx("div",{className:"nc-sheet-actions",children:l.jsx("button",{className:"nc-btn ghost",disabled:m,onClick:()=>{a&&a(),p("welcome")},children:f("back")})})]}),h==="done"&&l.jsxs("div",{className:"nc-wiz-body",children:[l.jsx("div",{className:"nc-wiz-done",children:f("node-connected")}),l.jsx("div",{className:"nc-sheet-actions",children:l.jsx("button",{className:"nc-btn primary",disabled:m,onClick:b,children:f("finish")})})]}),y&&l.jsx("div",{className:"nc-err",children:y})]})})}function Fj(e,t){if(typeof EventSource>"u"||!e)return()=>{};const n=new EventSource(`/api/events?token=${encodeURIComponent(e)}`);return n.onmessage=s=>{try{const o=JSON.parse(s.data);o&&typeof o=="object"&&typeof o.type=="string"&&t(o)}catch{}},()=>{try{n.close()}catch{}}}const Hj=6e3,Wj=12e3;function Uj({n:e,onClose:t}){return l.jsxs("div",{className:`nc-ntf-toast${e.urgency==="high"?" high":""}`,role:"status","aria-live":"polite",children:[l.jsxs("div",{className:"nc-ntf-toast-txt",children:[l.jsx("b",{children:e.title}),e.body&&l.jsx("small",{children:e.body}),e.session&&l.jsx("span",{className:"nc-ntf-from",children:e.session})]}),l.jsx("button",{type:"button",className:"nc-ntf-x",onClick:t,title:f("close"),children:l.jsx(Ge,{name:"x",size:14})})]})}function Kj({ask:e,token:t,onAnswered:n,onDismiss:s}){const[o,a]=N.useState(""),[u,h]=N.useState(!1),[p,m]=N.useState(null),[v,y]=N.useState(!1),w=async S=>{const C=String(S||"").trim();if(!(!C||u)){m(null),h(!0);try{await ex(t,e.id,C),n(e.id)}catch(x){m(String(x.message||x))}h(!1)}},b=async()=>{if(!v){y(!0);try{await tx(t,e.id),s(e.id)}catch{y(!1)}}};return l.jsxs("div",{className:"nc-ask-card",children:[l.jsxs("div",{className:"nc-ask-head",children:[l.jsx("span",{className:"nc-ntf-from",children:e.session}),l.jsxs("code",{className:"nc-ask-id",children:["#",e.id]}),l.jsx("button",{type:"button",className:"nc-ask-dismiss",title:f("ask-dismiss"),"aria-label":f("ask-dismiss"),disabled:v,onClick:b,children:l.jsx(Ge,{name:"x",size:14})})]}),l.jsx("div",{className:"nc-ask-q",children:e.question}),Array.isArray(e.options)&&e.options.length>0&&l.jsx("div",{className:"nc-ask-opts",children:e.options.map(S=>l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:u,onClick:()=>w(S),children:S},S))}),l.jsxs("div",{className:"nc-ask-reply",children:[l.jsx("textarea",{rows:2,placeholder:f("ask-reply-ph"),value:o,disabled:u,onChange:S=>a(S.target.value)}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:u||!o.trim(),onClick:()=>w(o),children:f("send")})]}),p&&l.jsx("div",{className:"nc-err",children:p})]})}function qj({token:e}){const[t]=En(),[n]=fb(),[s,o]=N.useState([]),[a,u]=N.useState([]),[h,p]=N.useState(()=>{try{return/(?:^|[#&])ask=/.test(location.hash)}catch{return!1}}),m=N.useRef(0),v=N.useRef(null);v.current||(v.current=Rj());const y=N.useRef({enabled:n,lang:t});y.current={enabled:n,lang:t};const w=N.useCallback(x=>{o(R=>R.filter(E=>E.key!==x))},[]),b=N.useCallback(x=>{const R=`t${m.current+=1}`;o($=>[...$.slice(-3),{...x,key:R}]),setTimeout(()=>w(R),x.urgency==="high"?Wj:Hj);const E=y.current;if(E.enabled)try{v.current.enqueue(x,kj(x,E.lang))}catch{}},[w]);N.useEffect(()=>{n||v.current.stop()},[n]),N.useEffect(()=>{const x=()=>{(document.visibilityState!=="visible"||!document.hasFocus())&&v.current.stop()},R=()=>v.current.stop();return document.addEventListener("visibilitychange",x),window.addEventListener("blur",x),window.addEventListener(Hh,R),()=>{document.removeEventListener("visibilitychange",x),window.removeEventListener("blur",x),window.removeEventListener(Hh,R),typeof v.current.dispose=="function"?v.current.dispose():v.current.stop()}},[]),N.useEffect(()=>{if(!e)return;let x=!1;Z0(e).then(E=>{x||u(E.asks||[])}).catch(()=>{});const R=Fj(e,E=>{E.type==="notify"?b(E):E.type==="ask"&&E.ask&&E.ask.id?u($=>$.some(B=>B.id===E.ask.id)?$:[...$,E.ask]):E.type==="ask-answered"&&E.id?u($=>$.filter(B=>B.id!==E.id)):E.type==="ask-dismissed"&&E.id&&u($=>$.filter(B=>B.id!==E.id))});return()=>{x=!0,R()}},[e,b]);const S=x=>u(R=>R.filter(E=>E.id!==x)),C=x=>u(R=>R.filter(E=>E.id!==x));return l.jsxs(l.Fragment,{children:[s.length>0&&l.jsx("div",{className:"nc-ntf-toasts",children:s.map(x=>l.jsx(Uj,{n:x,onClose:()=>w(x.key)},x.key))}),a.length>0&&!h&&l.jsxs("button",{type:"button",className:"nc-ask-badge",onClick:()=>p(!0),title:f("asks-title"),children:["? ",l.jsx("span",{className:"nc-ask-count",children:a.length})]}),a.length>0&&h&&l.jsxs("div",{className:"nc-ask-panel",children:[l.jsxs("div",{className:"nc-ask-panel-head",children:[l.jsx("b",{children:f("asks-title")}),l.jsx("span",{className:"nc-ask-count",children:a.length}),l.jsx("button",{type:"button",className:"nc-ntf-x",onClick:()=>p(!1),title:f("close"),children:l.jsx(Ge,{name:"x",size:16})})]}),l.jsx("div",{className:"nc-ask-panel-body",children:a.map(x=>l.jsx(Kj,{ask:x,token:e,onAnswered:S,onDismiss:C},x.id))})]})]})}const Vj=4e3;async function Yj(e){const t=await Ut("/api/sessions",e);if((t==null?void 0:t.ok)===!1)throw new Error(`HTTP ${t.status}`);const n=await t.json();if(!Array.isArray(n==null?void 0:n.sessions))throw new Error("invalid sessions payload");return n.sessions}async function Fd(e,t=[]){var h;const[n,s]=await Promise.allSettled([t.length?Zh(e,t):Yj(e),bs(e,t)]),o=n.status==="fulfilled"&&Array.isArray((h=n.value)==null?void 0:h.sessions)?n.value.sessions:Array.isArray(n.value)?n.value:null,a=s.status==="fulfilled"?s.value:null,u=(a==null?void 0:a.available)===!0&&Array.isArray(a.cells)?a.cells:null;return{sessions:o,cells:u,fresh:Array.isArray(o)&&Array.isArray(u)}}function pb(e,t,n){return n===!0&&(e==null?void 0:e.degraded)!==!0&&(e==null?void 0:e.active)===!0&&e.tmux!==!1&&!!e.tmuxSession&&(t||[]).some(s=>(s==null?void 0:s.name)===e.tmuxSession)}function Gj(e){const t=new Map((e.sessions||[]).map(o=>[o.name,o])),n=[],s=(o,a,u,h=[],p="")=>{const m=new Map((a||[]).map(v=>[v.name,v]));for(const v of o||[]){const y=m.get(v.tmuxSession)||{},w=af(v,y),b=pb(v,a,u);n.push({key:Go(h,v.tmuxSession||v.cell),session:v.tmuxSession,route:h,cellName:v.cell,label:v.cell,node:h.length?h.join("/"):"",nodeLabel:p,live:b,selectable:b,verified:u===!0,working:w.working,degraded:!!v.degraded,active:v.active===!0,activity:y.activity||v.activity||0,subtitle:w.subtitle})}};s(e.cells,[...t.values()],e.localFresh===!0);for(const o of e.nodeGroups||[]){const a=Array.isArray(o.route)?o.route:[];o.kind==="vl"||!a.length||s(o.cells,o.sessions,o.switcherFresh===!0,a,o.label||o.name||"")}return n}function Xj(e){const t=new Map,n=Array.isArray(e.sessions)?e.sessions:[],s=Array.isArray(e.cells)?e.cells:[],o=new Map(n.map(u=>[u.name,u])),a=new Set(s.map(u=>u.tmuxSession).filter(Boolean));t.set("local",lf(s,n.filter(u=>!a.has(u.name)),o));for(const u of e.nodeGroups||[]){const h=Array.isArray(u.route)?u.route:[];if(u.kind==="vl"||!h.length)continue;const p=Array.isArray(u.cells)?u.cells:[],m=Array.isArray(u.sessions)?u.sessions:[],v=new Set(p.map(y=>y.tmuxSession).filter(Boolean));t.set(h.join("/"),$l({...u,route:h,cells:p,sessions:m,unmanaged:m.filter(y=>!v.has(y.name))}).rawItems)}return t}function Qj(e,t,n,s){return[...new Set(e.map(a=>a.node||"local"))].flatMap(a=>{const u=e.filter(v=>(v.node||"local")===a),h=new Map((t.get(a)||[]).map(v=>[v.key,v])),p=new Map(u.map(v=>[v.key,v])),m=u.map(v=>{const y=h.get(v.key);return{...v,label:(y==null?void 0:y.label)||v.label,live:(y==null?void 0:y.live)??v.live,fresh:(y==null?void 0:y.fresh)===!0,activity:(y==null?void 0:y.activity)??v.activity}});return vs(m,n,"all",$i(s,a)).map(v=>p.get(v.key))})}function Jj({token:e,current:t,onPick:n,onClose:s}){const[o,a]=N.useState(Bg),[u,h]=N.useState(!1),[p,m]=N.useState(!1),[v,y]=N.useState(""),[w,b]=N.useState(""),[S,C]=N.useState(""),x=N.useRef(null),R=N.useRef(null),E=N.useMemo(()=>Gj(o),[o]),$=N.useMemo(()=>Xj(o),[o]),{pins:B,orders:K,canMoveRoster:V,moveRoster:Y,stepRoster:te}=of(),Q=N.useMemo(()=>Qj(E,$,B,K),[E,$,B,K]),J=N.useMemo(()=>u?Q:Q.filter(O=>O.selectable||O.degraded&&O.active),[Q,u]),H=N.useMemo(()=>E.find(O=>O.key===w&&O.selectable),[E,w]);N.useEffect(()=>{var F;const O=document.activeElement;(F=R.current)==null||F.focus();const T=k=>{k.key==="Escape"&&s()};return document.addEventListener("keydown",T),()=>{var k;document.removeEventListener("keydown",T),(k=O==null?void 0:O.focus)==null||k.call(O)}},[s]),N.useEffect(()=>{let O=!0,T=!1;const F=async()=>{if(T)return;T=!0;const I=Bg(),D=Array.isArray(I.nodeGroups)?I.nodeGroups:[],M=Fd(e),W=re=>re.kind!=="vl"&&Array.isArray(re.route)&&re.route.length>0,G=await Promise.all(D.filter(W).map(async re=>({group:re,result:await Fd(e,re.route)}))),ue=await M;if(!O)return;const le=new Map(G.map(({group:re,result:_e})=>[JSON.stringify(re.route||[]),_e])),he=D.map(re=>{if(!W(re))return{...re,switcherFresh:!1};const _e=le.get(JSON.stringify(re.route||[]));return _e?{...re,sessions:_e.sessions||re.sessions||[],cells:_e.cells||re.cells||[],switcherFresh:_e.fresh}:{...re,switcherFresh:!1}}),we=xy({...I,sessions:ue.sessions||I.sessions||[],cells:ue.cells||I.cells||[],localFresh:ue.fresh,nodeGroups:he,refreshedAt:Date.now()});a(we),m(!0),T=!1};F();const k=setInterval(F,Vj);return()=>{O=!1,clearInterval(k)}},[e]);const L=O=>O.degraded?f("cell-degraded"):O.verified?O.selectable?O.working?f("cell-working"):f("cell-idle"):f("cell-off"):f("cell-switcher-not-confirmed"),A=O=>{if(y(""),!O.selectable){y(f("cell-switcher-not-active"));return}b(O.key)},z=async()=>{const O=H;if(!O){y(f("cell-switcher-select"));return}y(""),C(O.key);try{const T=await Fd(e,O.route),F=(T.cells||[]).find(k=>(k==null?void 0:k.cell)===O.cellName&&(k==null?void 0:k.tmuxSession)===O.session);if(!pb(F,T.sessions,T.fresh)){y(f("cell-switcher-not-active"));return}n({session:O.session,...O.node?{node:O.node}:{},cellName:O.cellName}),s()}catch{y(f("cell-switcher-not-active"))}finally{C("")}};return l.jsx("div",{className:"nc-cell-switcher-backdrop",onClick:s,children:l.jsxs("aside",{ref:x,className:"nc-cell-switcher",role:"dialog","aria-label":f("fleet-cells"),tabIndex:-1,onClick:O=>O.stopPropagation(),children:[l.jsxs("div",{className:"nc-cell-switcher-list",children:[!p&&l.jsx("div",{className:"nc-empty",role:"status",children:f("cell-switcher-refreshing")}),p&&J.length===0&&l.jsx("div",{className:"nc-empty",role:"status",children:f("cell-switcher-empty-active")}),J.map(O=>{const T=(t==null?void 0:t.session)===O.session&&((t==null?void 0:t.node)||"")===O.node,F=w===O.key,k=L(O),I=O.node||"local",D=$.get(I)||E.filter(M=>(M.node||"local")===I);return l.jsxs("div",{className:`nc-cell-switcher-row${T?" current":""}${F?" selected":""}${O.selectable?"":" off"}`,"data-roster-key":O.key,"data-position":I,children:[l.jsx(bi,{position:I,itemKey:O.key,label:O.cellName,canMove:V,onMove:(M,W)=>Y(I,M,W,D),onStep:M=>te(I,O.key,M,D)}),l.jsxs("button",{type:"button",className:"nc-cell-switcher-row-select","aria-current":T?"true":void 0,"aria-pressed":F,"aria-disabled":!O.selectable,disabled:S===O.key,onClick:()=>A(O),children:[l.jsx("span",{className:`nc-cell-switcher-dot${O.degraded?" warn":O.live?` on${O.working?" working":""}`:""}`}),l.jsxs("span",{className:"nc-cell-switcher-copy",children:[l.jsx("b",{children:O.cellName}),l.jsx("small",{className:"nc-cell-switcher-state",children:k}),l.jsx("small",{children:[O.nodeLabel,O.subtitle].filter(Boolean).join(" · ")})]})]})]},O.key)})]}),v&&l.jsx("div",{className:"nc-cell-switcher-notice",role:"status",children:v}),l.jsx("div",{className:"nc-cell-switcher-actions",children:l.jsx("button",{type:"button",className:"nc-cell-switcher-open",disabled:!H||!!S,onClick:z,children:H?`${f("cell-switcher-open")}: ${H.cellName}`:f("cell-switcher-select")})}),l.jsxs("div",{className:"nc-cell-switcher-controls",children:[l.jsx("b",{children:f("fleet-cells")}),l.jsx("button",{type:"button",className:"nc-cell-switcher-filter","aria-pressed":u,onClick:()=>{y(""),h(O=>!O)},children:f(u?"cell-switcher-show-active":"cell-switcher-show-all")}),l.jsx("button",{ref:R,type:"button",className:"nc-cell-switcher-close","aria-label":f("cell-switcher-close"),title:f("cell-switcher-close"),onClick:s,children:"×"})]})]})})}const Zj=2e3;function eR(e){if(e.kind==="gap")return`${f("vl-events-gap")} ${e.count||"?"}`;if(e.kind==="truncate")return f("vl-events-truncated");if(e.kind==="turn_end")return f("vl-events-turn-end");if(e.kind==="done")return f("vl-events-done");if(e.kind==="writer_epoch")return f("vl-events-writer-epoch");if(e.kind==="tool_start")return`${f("vl-events-tool")} ${e.name||""}`.trim();if(e.kind==="tool_end"){const t=e.isError?f("vl-events-tool-failed"):f("vl-events-tool-ok");return`${f("vl-events-tool")} ${e.name||""} — ${t}`.trim()}return e.kind==="usage"?e.text||f("vl-events-usage"):e.text||""}function tR({token:e,nodeId:t,route:n=[]}){const[s,o]=N.useState([]),[a,u]=N.useState(!1),h=N.useRef(0),p=N.useRef(!1);return N.useEffect(()=>{let m=!0;h.current=0,p.current=!1,o([]);const v=async()=>{if(!p.current){p.current=!0;try{const b=await A0(e,t,h.current,n);if(!m)return;u(!1);const C=(Array.isArray(b==null?void 0:b.events)?b.events:[]).filter(x=>Number.isSafeInteger(x==null?void 0:x.seq)&&x.seq>h.current);C.length&&(o(x=>x.concat(C).slice(-500)),h.current=C[C.length-1].seq),Number.isSafeInteger(b==null?void 0:b.cursor)&&b.cursor>h.current&&(h.current=b.cursor)}catch{m&&u(!0)}finally{p.current=!1}}},y=()=>{v().catch(()=>{})};y();const w=setInterval(y,Zj);return()=>{m=!1,clearInterval(w)}},[e,t,JSON.stringify(n)]),l.jsxs("div",{className:"nc-vl-events",children:[a&&l.jsx("div",{className:"nc-set-hint nc-vl-events-stale",children:f("vl-events-stale")}),s.length===0&&!a&&l.jsx("small",{className:"nc-set-hint","data-testid":"vl-events-empty",children:f("vl-events-empty")}),s.length>0&&l.jsx("ol",{className:"nc-vl-events-list",children:s.map(m=>l.jsx("li",{"data-testid":`vl-ev-${m.seq}`,className:`nc-vl-ev nc-vl-ev-${m.kind}${m.isError?" error":""}${m.kind==="gap"?" gap":""}`,children:eR(m)},`${m.seq}-${m.kind}`))})]})}function H_({peer:e,token:t,onBack:n}){var s;return En(),e?l.jsxs("section",{className:"nc-vl-session-view",children:[l.jsxs("header",{className:"nc-bar nc-bar-single",children:[l.jsxs("button",{onClick:n,title:f("back"),children:[l.jsx(Ge,{name:"chevronLeft",size:18}),l.jsx("span",{className:"nc-bar-label",children:f("back")})]}),l.jsxs("span",{className:"nc-bar-center",children:[l.jsx("b",{title:e.label,children:e.label}),((s=e.session)==null?void 0:s.profile)&&l.jsxs("small",{className:"nc-bar-sub",children:[e.session.profile," · ",f("vl-events-title")]})]}),l.jsx("span",{className:"nc-bar-right"})]}),l.jsx("div",{className:"nc-vl-session-body",children:l.jsx(tR,{token:t,nodeId:e.nodeId,route:e.route||[]})})]}):null}const Hd=e=>ki(Ys(e)).length===0,Wd=e=>Array.isArray(e)?e.join("/"):"";function nR(e){const t=new Set,n=[];for(const s of Array.isArray(e)?e:[])!s||!Kn.test(String(s.instanceId||""))||!Array.isArray(s.route)||!s.route.length||t.has(s.instanceId)||(t.add(s.instanceId),n.push({instanceId:s.instanceId,route:[...s.route],label:String(s.label||s.name||s.route.join(" › ")),status:s.status||"offline"}));return n.sort((s,o)=>s.label.localeCompare(o.label))}function zo(e){return{instanceId:e.ownerId,route:e.ownerRoute||[],label:e.ownerLabel,status:e.available===!1?"offline":"up"}}function Hs(e,t,n,s=!1,o=!0){const a=t.instanceId;return{...e,id:Lr(s?null:a,e.name),ownerId:a,ownerRoute:s?[]:[...t.route],ownerLabel:s?"Local":t.label,local:s,available:o,ownerTopology:Array.isArray(n)?n:[],layout:Bh(e.layout,a,n)}}function iR(e,t,n,s,o=[]){const[a,u]=N.useState([]),[h,p]=N.useState(!1),[m,v]=N.useState("idle"),[y,w]=N.useState(""),[b,S]=N.useState(""),C=N.useRef([]),x=N.useRef([]),R=N.useRef(""),E=N.useRef(t),$=N.useRef(n),B=N.useRef(!1),K=N.useRef(!0),V=N.useRef(""),Y=N.useMemo(()=>nR(o),[o]),te=Y.map(D=>`${D.instanceId}:${Wd(D.route)}:${D.status}:${D.label}`).join("|");x.current=Y,$.current=n,E.current=t,C.current=a;const Q=N.useCallback(D=>zh(D.layout,R.current,x.current),[]),J=N.useCallback((D,M=!0,W=E.current)=>{const G=Yv(D,xl()),ue=C.current.some(he=>he.id===W);C.current=G,u(G);const le=G.find(he=>he.id===W);if(M&&le){K.current=!0;const he=Q(le);s(he),le.local&&wN(le.name,he)}else ue&&!le&&(K.current=!0,s(Ar()),w("deck non più condiviso dal nodo owner"));gN(G.filter(he=>he.local).map(he=>he.name))},[s,Q]),H=N.useCallback(async D=>{let M=await pl(e);const W=M.decks.find(G=>G.name==="main");if(M.decks.length===1&&W&&W.revision===0&&Hd(W.layout)){const G=mN(),ue=Ys($h("main")||Ar());if(!Hd(ue)){const le=Bh(ue,D,[]);M.decks[0]=await ml(e,"main",le,0,[])}for(const le of G.filter(he=>he!=="main"))try{let he=await Eg(e,le,[]);const we=Ys($h(le)||Ar());Hd(we)||(he=await ml(e,le,Bh(we,D,[]),he.revision,[]))}catch{}M=await pl(e)}return M},[e]),L=N.useCallback(async({migrate:D=!1}={})=>{const M=await ef(e,[]),W=Kn.test(String(M.instanceId||""))?M.instanceId:"";if(!W)throw new Error("instanceId locale non disponibile");R.current=W,S(W);const[G,ue]=await Promise.all([D?H(W):pl(e),Sg(e,[]).catch(()=>({nodes:[]}))]),le={instanceId:W,route:[],label:"Local"},he=G.decks.map(re=>Hs(re,le,ue.nodes,!0,!0)),we=C.current;return await Promise.all(x.current.map(async re=>{if(re.status!=="up"){he.push(...we.filter(_e=>!_e.local&&_e.ownerId===re.instanceId).map(_e=>({..._e,ownerRoute:[...re.route],ownerLabel:re.label,available:!1})));return}try{const[_e,ze]=await Promise.all([pl(e,re.route),Sg(e,re.route).catch(()=>({nodes:[]}))]);he.push(..._e.decks.map(ut=>Hs(ut,re,ze.nodes,!1,!0)))}catch{he.push(...we.filter(ze=>!ze.local&&ze.ownerId===re.instanceId).map(ze=>({...ze,ownerRoute:[...re.route],ownerLabel:re.label,available:!1})))}})),he.sort((re,_e)=>re.local===_e.local?re.ownerLabel.localeCompare(_e.ownerLabel)||(re.name==="main"?-1:_e.name==="main"?1:re.name.localeCompare(_e.name)):re.local?-1:1),he},[e,H,te]);N.useEffect(()=>{if(!e)return;let D=!1;const M=V.current!==e;return V.current=e,L({migrate:M}).then(W=>{if(D)return;const G=C.current.find(he=>he.id===E.current),ue=W.find(he=>he.id===E.current),le=ue&&(!G||ue.revision>G.revision||G.available!==ue.available||Wd(G.ownerRoute)!==Wd(ue.ownerRoute));J(W,M||!!le&&!B.current),p(!0),ue&&w("")}).catch(W=>{D||(p(!0),w(String(W.message||W)))}),()=>{D=!0}},[J,L,te,e]);const A=N.useCallback(async(D=E.current)=>{if(!h||!B.current)return!0;const M=C.current.find(W=>W.id===D);if(!M)return w(`deck inesistente: ${D}`),!1;if(M.available===!1)return w(`nodo owner offline: ${M.ownerLabel}`),!1;v("saving");try{const W=qv(Ys($.current),M.ownerId,M.ownerTopology),G=await ml(e,M.name,W,M.revision,M.ownerRoute),ue=Hs(G,zo(M),M.ownerTopology,M.local,!0);return J(C.current.map(le=>le.id===D?ue:le),!1),B.current=!1,v("saved"),w(""),setTimeout(()=>v("idle"),1500),!0}catch(W){if(v("error"),w(String(W.message||W)),W.status===409&&W.data&&W.data.current){const G=C.current.find(le=>le.id===D),ue=Hs(W.data.current,zo(G),G.ownerTopology,G.local,!0);J(C.current.map(le=>le.id===D?ue:le),!1)}return!1}},[h,e,J]);return N.useEffect(()=>{if(!h)return;if(K.current){K.current=!1;return}B.current=!0,v("saving");const D=setTimeout(A,650);return()=>clearTimeout(D)},[n,h,A]),N.useEffect(()=>{if(!h)return;const D=setInterval(async()=>{try{const M=await L(),W=C.current.find(le=>le.id===E.current),G=M.find(le=>le.id===E.current),ue=G&&(!W||G.revision>W.revision||W.available!==G.available);J(M,ue&&!B.current)}catch{}},5e3);return()=>clearInterval(D)},[h,L,J]),{decks:a,records:a,localNodeId:b,ready:h,saveState:m,error:y,setError:w,saveNow:A,select:async D=>{if(B.current&&!await A(E.current))throw new Error("salvataggio del deck corrente fallito: cambio annullato");const M=C.current.find(W=>W.id===D);if(!M)throw new Error(`deck inesistente: ${D}`);return B.current=!1,K.current=!0,Q(M)},add:async(D,M=null)=>{const W=M===Si?C.current.find(le=>le.local):M?C.current.find(le=>le.ownerId===M):null;if(!W||W.available===!1)throw new Error("nodo owner non disponibile");const G=await Eg(e,D,W.ownerRoute),ue=Hs(G,zo(W),W.ownerTopology,W.local,!0);return J([...C.current,ue],!1),ue},rename:async(D,M)=>{const W=C.current.find(we=>we.id===D);if(!W)throw new Error("deck inesistente");if(D===E.current&&B.current&&!await A(D))throw new Error(`salvataggio di "${W.name}" fallito: rinomina annullata`);const G=C.current.find(we=>we.id===D);if(!G)throw new Error("deck inesistente");const ue=await nx(e,G.name,M,G.revision,G.ownerRoute),le=Hs(ue,zo(G),G.ownerTopology,G.local,!0),he=G.local?Si:G.ownerId;return md(_N(xl(),he,D,le.id)),J(C.current.map(we=>we.id===D?le:we),!1),le},remove:async D=>{const M=C.current.find(G=>G.id===D);if(!M)throw new Error("deck inesistente");D===E.current&&(B.current=!1),await ix(e,M.name,M.revision,M.ownerRoute);const W=M.local?Si:M.ownerId;md(yN(xl(),W,D)),J(C.current.filter(G=>G.id!==D),!1)},reorder:(D,M)=>{const W=C.current.find(re=>re.id===D),G=C.current.find(re=>re.id===M);if(!W||!G)return!1;const ue=W.local?Si:W.ownerId,le=G.local?Si:G.ownerId;if(ue!==le)return!1;const he=C.current.filter(re=>(re.local?Si:re.ownerId)===ue).map(re=>re.id),we=md(vN(xl(),ue,D,M,he));return J(Yv(C.current,we),!1),!0},addTileTo:async(D,M)=>{const W=C.current.find(re=>re.id===D);if(!W)throw new Error("deck inesistente");if(W.available===!1)throw new Error(`nodo owner offline: ${W.ownerLabel}`);const G=Lw(M,R.current,x.current);if(!G)throw new Error("riferimento sessione non valido");const ue=Q(W),le=qv(wy(ue,G),W.ownerId,W.ownerTopology),he=await ml(e,W.name,le,W.revision,W.ownerRoute),we=Hs(he,zo(W),W.ownerTopology,W.local,!0);return J(C.current.map(re=>re.id===D?we:re),!1),we},localMainId:Lr(null,"main"),parseDeckId:rc}}const sR="/sw.js",Uh="nc-sw-update";let Kh=null,qh=!1,Vh=null,mb=Object.freeze({needed:!1,kind:null,version:""}),gb=!1;function vb(){typeof window<"u"&&window.dispatchEvent(new Event(Uh))}function _b(){const e=Vh||(qh?{kind:"reload",version:""}:null);mb=Object.freeze({needed:!!e,kind:(e==null?void 0:e.kind)||null,version:(e==null?void 0:e.version)||""})}function W_(){return mb}function rR(e){return typeof window>"u"?()=>{}:(window.addEventListener(Uh,e),()=>window.removeEventListener(Uh,e))}function Ff(e){qh!==e&&(qh=e,_b(),vb())}const Ud="nc-auto-reload";function oR(){try{return typeof sessionStorage<"u"?sessionStorage:null}catch{return null}}function aR(e,t,n,s={}){let o=null;e&&t&&e!==t?o={kind:"install",version:e}:t&&n&&t!==n&&(o={kind:"reload",version:t});const a=JSON.stringify(o)===JSON.stringify(Vh);Vh=o,_b(),a||vb();const u=s.storage===void 0?oR():s.storage;if(!o){try{u&&u.removeItem(Ud)}catch{}return}if(o.kind!=="reload"||!u)return;const h=`${t}|${n}`;try{if(u.getItem(Ud)===h)return;u.setItem(Ud,h)}catch{return}(s.applyImpl||yb)()}function lR(e){e.addEventListener("statechange",()=>{e.state==="installed"&&navigator.serviceWorker.controller&&Ff(!0)})}function cR(){typeof navigator>"u"||!("serviceWorker"in navigator)||(navigator.serviceWorker.addEventListener("controllerchange",()=>{gb&&location.reload()}),navigator.serviceWorker.register(sR).then(e=>{Kh=e,e.waiting&&Ff(!0),e.addEventListener("updatefound",()=>{const t=e.installing;t&&lR(t)}),setInterval(()=>{e.update().catch(()=>{})},3600*1e3)}).catch(()=>{}))}function yb(){gb=!0,Ff(!1);const e=Kh&&Kh.waiting;e?(e.postMessage({type:"SKIP_WAITING"}),setTimeout(()=>location.reload(),4e3)):location.reload()}function uR({hash:e="",origin:t="",pathname:n="",search:s=""}={}){const o=String(e||"").replace(/^#/,""),a=`${n||""}${s||""}`;if(!o)return{token:"",pair:"",nextUrl:a};const u=new URLSearchParams(o),h=u.get("token")||"",p=u.get("pair")||"",m=p?`${t||""}${n||""}#pair=${p}`:"";return{token:h,pair:m,nextUrl:a}}const wb=9,bb=24,Sb="nc_side_w",U_="nc_side_min",dR=240,K_="(min-width:1024px) and (pointer:fine)";function hR(){const e=Number(localStorage.getItem(Sb));return e>=180&&e<=480?e:dR}function fR(){const e=Number(localStorage.getItem("nc_fontsize"));return e>=wb&&e<=bb?e:13}function pR(){const e={token:"",pair:""};try{const{token:t,pair:n,nextUrl:s}=uR({hash:location.hash,origin:location.origin,pathname:location.pathname,search:location.search});if(t){e.token=t;try{localStorage.setItem("nc_token",t)}catch{}}if(n){e.pair=n;try{sessionStorage.setItem("nc_pair",n)}catch{}}if(location.hash)try{history.replaceState(null,"",s)}catch{}}catch{}if(e.token||(e.token=sessionStorage.getItem("nc_token")||localStorage.getItem("nc_token")||""),!e.pair){const t=sessionStorage.getItem("nc_pair");t&&(e.pair=t)}return e}function mR(e){try{return Ys($h(e))}catch{return Ar()}}function q_(e){if(!e)return"";const t=Math.floor(Date.now()/1e3)-e;return t<0||t<60?"ora":t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}g`}function gR(){const[e,t]=N.useState(()=>window.matchMedia(K_).matches);return N.useEffect(()=>{const n=window.matchMedia(K_),s=o=>t(o.matches);return n.addEventListener("change",s),()=>n.removeEventListener("change",s)},[]),e}function V_({session:e,node:t,ownerId:n,cellName:s,token:o,readonly:a=!1,onBack:u,onCellSwitcher:h,cellSwitcherOpen:p=!1}){En();const[m]=Cf(),[v,y]=N.useState(!1),[w,b]=N.useState(()=>window.matchMedia("(pointer: coarse)").matches),[S,C]=N.useState(null),[x,R]=N.useState(fR),[E,$]=N.useState(s||e),[B,K]=N.useState(""),V=T=>R(F=>{const k=Math.max(wb,Math.min(bb,F+T));return localStorage.setItem("nc_fontsize",String(k)),k}),Y=N.useRef(()=>{}),te=N.useRef(()=>!1),Q=N.useRef(()=>{}),J=N.useRef(!1),[H,L]=N.useState(!1),[A,z]=N.useState(!1),O=()=>{J.current=!J.current,L(J.current)};return N.useEffect(()=>{$(s||e)},[s,e]),N.useEffect(()=>{let T=!0;const F=t?t.split("/"):[],k=t?`/api/route/${t.split("/").map(encodeURIComponent).join("/")}/_`:"/api";async function I(){let M=null,W=null;try{const le=await(await Ut(`${k}/sessions`,o)).json();Array.isArray(le.sessions)&&(M=le.sessions.find(he=>he.name===e))}catch{}try{const ue=await bs(o,F);ue.available&&Array.isArray(ue.cells)&&(W=ue.cells.find(le=>le.tmuxSession===e))}catch{}if(!T)return;$(Ef({session:e,cell:W||(s?{cell:s}:null)}));let G="";W?G=`${W.engine}${W.key?`·${W.key}`:""}`:M&&(G=M.attached?`attached · ${q_(M.activity)}`:M.activity?q_(M.activity):""),K(G)}I();const D=setInterval(I,4e3);return()=>{T=!1,clearInterval(D)}},[e,t,o]),l.jsxs("div",{className:"nc-app",children:[l.jsxs("header",{className:"nc-bar nc-bar-single",children:[l.jsxs("button",{onClick:u,title:f("sessions"),children:[l.jsx(Ge,{name:"chevronLeft",size:18}),l.jsx("span",{className:"nc-bar-label",children:f("sessions")})]}),l.jsxs("span",{className:"nc-bar-center",children:[l.jsx("b",{title:t?`${E} · ${t}`:E,children:E}),B&&l.jsx("small",{className:"nc-bar-sub",children:B})]}),l.jsxs("span",{className:"nc-bar-right",children:[l.jsx("button",{onClick:()=>V(-1),title:f("zoom-out"),children:l.jsx(Ge,{name:"zoomOut",size:18})}),l.jsx("button",{onClick:()=>V(1),title:f("zoom-in"),children:l.jsx(Ge,{name:"zoomIn",size:18})}),l.jsx("button",{onClick:()=>b(T=>!T),title:f("composer"),children:l.jsx(Ge,{name:"keyboard",size:20})}),l.jsx("button",{onClick:()=>y(T=>!T),title:f("files"),children:l.jsx(Ge,{name:"folder",size:20})})]})]}),l.jsx("div",{className:"nc-termwrap",children:l.jsx(vw,{session:e,node:t,token:o,readonly:a,takeSize:!0,sendRef:Y,composerRef:te,actionRef:Q,ctrlRef:J,setCtrlArmed:L,onFiles:C,fontSize:x,selectionMode:A,onSelectionModeChange:z,keyboardGesture:m.terminalKeyboardGesture})}),l.jsx(zE,{onKeyboard:()=>b(T=>!T),onCellSwitcher:h,cellSwitcherOpen:p,send:T=>Y.current(T),action:T=>Q.current(T),ctrlArmed:H,onCtrl:O,selectionMode:A,onSelectionMode:z,keepKeyboardClosed:m.keybarKeepsKeyboardClosed,showEnter:m.showKeybarEnter,keybarLayout:m.keybarLayout}),w&&l.jsx(Nw,{submitText:T=>te.current(T),token:o,session:e,node:t,ownerId:n,keepKeyboardClosedOnVoice:m.voiceKeepsKeyboardClosed}),v&&l.jsx(_w,{session:e,node:t,token:o,filesEvent:S,onClose:()=>y(!1)})]})}function vR(){En();const[e]=N.useState(pR),[t,n]=N.useState(e.token),[s,o]=N.useState(e.pair||""),a=N.useCallback(()=>{o("");try{sessionStorage.removeItem("nc_pair")}catch{}},[]),[u,h]=N.useState(!1),p=gR(),[m]=N.useState(()=>pN(typeof location<"u"?location.pathname:"/")),[v,y]=N.useState(m.id),w=v===Lr(null,qn),[b,S]=N.useState(null),C=de=>{const Re=ws(de);S(Re?{...Re,...typeof(de==null?void 0:de.cellName)=="string"&&de.cellName?{cellName:de.cellName}:{}}:null)},[x,R]=N.useState([]),[E,$]=N.useState([]),[B,K]=N.useState([]),[V,Y]=N.useState(()=>m.ownerId?Ar():mR(m.name)),[te,Q]=N.useState(null),[J,H]=N.useState(null),L=de=>H(ws(de)),[A,z]=N.useState(null),O=sf(t,p),T=N.useMemo(()=>(O||[]).filter(de=>de.instanceId).map(de=>({instanceId:de.instanceId,route:de.route,label:de.label,status:de.status})),[O]),F=iR(t,v,V,Y,T),k=F.decks;N.useEffect(()=>{const de=new Map;for(const Re of O||[]){const $e=(Re.route||[Re.name]).join("/"),rt=new Set((Re.sessions||[]).map(wt=>wt.name));for(const wt of Re.cells||[])!wt.cell||!wt.tmuxSession||wt.cell===wt.tmuxSession||rt.has(wt.cell)||de.set(`${$e}:${wt.cell}`,`${$e}:${wt.tmuxSession}`)}Y(Re=>Lx(Re,de))},[O]),N.useEffect(()=>{F.localNodeId&&Y(de=>{const Re=zh(de,F.localNodeId,T);return JSON.stringify(Re)===JSON.stringify(de)?de:Re})},[T,F.localNodeId]);const[I,D]=N.useState(null),[M,W]=N.useState(null),G=N.useRef(0),[ue,le]=N.useState(!1),[he,we]=N.useState(hR),[re,_e]=N.useState(!w),[ze,ut]=N.useState(()=>w?localStorage.getItem(U_)==="1":!0),[nt,Ne]=N.useState(!1),[jt,tn]=N.useState("nodes"),[De,Tt]=N.useState(!1),[Qe,vt]=N.useState(""),[mt,it]=N.useState(!1),dt=(de="nodes",Re=!1,$e="")=>{tn(de),Tt(Re),vt($e),Ne(!0)},[ot,ht]=N.useState(!1),[st,ft]=N.useState({deviceDefault:"",localNodeId:"",localNameDefault:""}),[be,ce]=N.useState(!1);N.useEffect(()=>{try{localStorage.setItem(Sb,String(he))}catch{}},[he]),N.useEffect(()=>{try{localStorage.setItem(U_,ze?"1":"")}catch{}},[ze]),N.useEffect(()=>{if(!t)return;let de=!1;return Promise.all([ny(t),Ut("/api/config",t).then(Re=>Re.json())]).then(([Re,$e])=>{de||(ft({deviceDefault:Re.deviceName||"",localNodeId:Re.nodeId||"",localNameDefault:Re.localName||""}),ce(!!$e.readonlyDefault),(Re.firstRun===!0&&!$e.readonlyDefault||s)&&ht(!0))}).catch(()=>{}),()=>{de=!0}},[t,s]);const U=N.useCallback(async()=>{try{const Re=await(await Ut("/api/sessions",t)).json();Re.error||R(Re.sessions||[])}catch{}try{const de=await bs(t);$(de.available?de.cells||[]:[]),K(de.available?de.capabilities||[]:[])}catch{$([]),K([])}},[t]);N.useEffect(()=>{if(!p)return;U();const de=setInterval(U,4e3);return()=>clearInterval(de)},[p,U]),N.useEffect(()=>{let de=!1;const Re=()=>{Ut("/api/config",t).then(rt=>rt.json()).then(rt=>{de||aR(rt.version,rt.uiVersion,"0.8.56")}).catch(()=>{})};Re();const $e=setInterval(Re,6e4);return()=>{de=!0,clearInterval($e)}},[t]);const ne=new Set([...x.map(de=>de.name),...O.flatMap(de=>de.sessions.map(Re=>Re.key))]),j=ki(V),X=de=>Y(Re=>{const $e=Lw(de,F.localNodeId,T)||de,rt=wy(Re,$e);return rt===Re&&ki(Re).length>=9&&F.setError(f("grid-full")),rt}),ie=async(de,Re=[])=>{try{await Qh(t,de,Re)}catch{return}const $e=Re.length?`${Re.join("/")}:${de}`:de;Y(rt=>Hl(rt,$e)),U()},pe=async(de,Re,$e=[])=>{try{await ty(t,de,Re,$e)}catch{return}U()},ke=async(de,Re,$e=[])=>{await J_(t,{cell:de,enabled:!!Re},$e),U()},me=async de=>{if(!I)return;const{cell:Re}=I,$e=Array.isArray(I.route)?I.route:[];if(de.action==="up"){const wt=await Xh(t,{cell:Re,boot:!!de.boot,...de.engine?{engine:de.engine}:{},...de.model!==void 0?{model:de.model}:{},...de.permissionPolicy?{permissionPolicy:de.permissionPolicy}:{}},$e),Ss=df(wt);Ss&&F.setError(Ss.text)}else await Il(t,{cell:Re,boot:!!de.boot},$e);const rt=de.action==="up"?!!de.boot:de.boot?!1:!!I.boot;W({id:++G.current,cell:Re,route:$e,enabled:rt}),U()},xe=N.useCallback(de=>{W(Re=>(Re==null?void 0:Re.id)===de?null:Re)},[]),We=async de=>{if(!(!(de!=null&&de.direct)||ue)){le(!0);try{await tf(t,de.name,de.tunnelStatus==="up"?"down":"up")}finally{le(!1)}}},lt=async(de,Re)=>{const $e=String(Re||"").trim();return!(de!=null&&de.direct)||!Ir($e)?!1:(await ry(t,de.name,$e),!0)},Ke=de=>{const Re=k.find($e=>$e.id===de);if(!Re)return!1;try{const $e=window.open(pd(Re,t),"_blank");return $e&&($e.opener=null),!!$e}catch{return!1}},pt=async de=>{if(!de||de===v)return;const Re=await F.select(de),$e=F.records.find(rt=>rt.id===de);y(de),Y(Re),Q(null),H(null);try{history.replaceState(null,"",pd($e||de,null))}catch{}},Xe=async(de,Re)=>{const $e=await F.add(de,Re);await pt($e.id)},je=async(de,Re)=>{const $e=await F.rename(de,Re);if(de===v){y($e.id),Y(zh($e.layout,F.localNodeId,T)),Q(null),H(null);try{history.replaceState(null,"",pd($e,null))}catch{}}},_t=async de=>{await F.remove(de),de===v&&await pt(F.localMainId)},Sn=async(de,Re)=>{!Re||Re===v||(await F.addTileTo(Re,de),Y($e=>Hl($e,de)))};if(!t)return l.jsxs("div",{className:"nc-auth",children:[l.jsx("p",{children:f("auth-prompt")}),l.jsx("input",{onChange:de=>n(de.target.value.trim()),placeholder:"token"}),l.jsxs("label",{children:[l.jsx("input",{type:"checkbox",checked:u,onChange:de=>h(de.target.checked)})," ",f("remember-device")]}),l.jsx("button",{onClick:()=>{(u?localStorage:sessionStorage).setItem("nc_token",t)},children:"ok"})]});const Rn=l.jsxs(l.Fragment,{children:[nt&&l.jsx(zj,{token:t,initialTab:jt,initialLocation:Qe,startNewCell:De,onClose:()=>{Ne(!1),Tt(!1),vt("")}}),ot&&l.jsx($j,{token:t,initialPair:s,...st,onPairDone:a,onDone:()=>ht(!1)}),l.jsx(qj,{token:t})]});if(!p)return A?l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"nc-single-overlay",children:l.jsx(H_,{peer:A,token:t,onBack:()=>z(null)})}),Rn]}):b?l.jsxs(l.Fragment,{children:[l.jsx(V_,{session:b.session,node:b.node,ownerId:b.ownerId,cellName:b.cellName,token:t,readonly:be,onBack:()=>S(null),onCellSwitcher:()=>it(!0),cellSwitcherOpen:mt}),mt&&l.jsx(Jj,{token:t,current:b,onPick:de=>{C(de),it(!1)},onClose:()=>it(!1)}),Rn]}):l.jsxs(l.Fragment,{children:[l.jsx(Xx,{onPick:C,token:t,onSettings:dt,onOpenVlSession:z}),Rn]});const Rt=w||!re;return l.jsxs("div",{className:"nc-workspace",children:[Rt&&l.jsx(nN,{sessions:x,cells:E,activeSessions:j,nodeGroups:O,fleetCapabilities:B,bootSettlement:M,onBootSettlementApplied:xe,localNodeId:F.localNodeId,onPick:L,onAddTile:X,onPower:D,onBoot:ke,onBootError:de=>F.setError(String((de==null?void 0:de.message)||de)),onNodePower:We,onNodeRename:lt,onKill:ie,onVisibility:pe,onNew:()=>dt("fleet",!0),onSettings:dt,onOpenVlSession:z,width:he,collapsed:ze,onResize:we,onToggleCollapse:()=>ut(de=>!de)}),l.jsxs("div",{className:"nc-workspace-main",children:[l.jsx(ON,{decks:k,currentDeck:v,onCreate:Xe,onRename:je,onDelete:_t,onReorder:F.reorder,onOpenWindow:Ke,onNavigate:pt,saveState:F.saveState,error:F.error,sidebarVisible:Rt,onToggleSidebar:w?null:()=>_e(de=>!de)}),l.jsx(cN,{layout:V,onLayoutChange:Y,token:t,readonly:be,sessionsAlive:ne,focusSession:te,onFocus:Q,onOpenSingle:L,decks:k,currentDeck:v,onSendToDeck:Sn,cells:E,nodeGroups:O})]}),A&&l.jsx("div",{className:"nc-single-overlay",children:l.jsx(H_,{peer:A,token:t,onBack:()=>z(null)})}),J&&l.jsx("div",{className:"nc-single-overlay",children:l.jsx(V_,{session:J.session,node:J.node,ownerId:J.ownerId,cellName:Ef({session:J.session,node:J.node,ownerId:J.ownerId,cells:E,nodeGroups:O}),token:t,readonly:be,onBack:()=>H(null)})}),I&&l.jsx(Bl,{cell:I,token:t,route:Array.isArray(I.route)?I.route:[],onConfirm:me,onClose:()=>D(null)}),Rn]})}function _R(){En();const e=N.useSyncExternalStore(rR,W_,W_);if(!e.needed)return null;const t=e.kind==="install"?f("install-version-mismatch").replace("{v}",e.version):f("update-available").replace("{v}",e.version).replace(" "," ").trim();return l.jsxs("div",{className:"nc-update",role:"status","aria-live":"polite",children:[l.jsx("span",{className:"nc-update-msg",children:t}),e.kind==="reload"&&l.jsx("button",{className:"nc-update-btn",onClick:yb,children:f("reload")})]})}cR();g0.createRoot(document.getElementById("root")).render(l.jsxs(c0.StrictMode,{children:[l.jsx(vR,{}),l.jsx(_R,{})]}));
93
+ `],{type:"application/json"}),T=URL.createObjectURL(O),F=document.createElement("a");F.href=T,F.download="nexuscrew-diagnostics.json",F.click(),URL.revokeObjectURL(T)}catch{w(f("diagnostics-export-failed"))}};return l.jsxs("div",{className:"nc-set-tab nc-diagnostics",children:[l.jsxs("label",{className:"nc-field",children:[f("diagnostics-target"),l.jsx("select",{value:u.key,onChange:O=>a(O.target.value),children:s.map(O=>l.jsxs("option",{value:O.key,children:[O.label,O.status!=="up"?` · ${O.status}`:""]},O.key))})]}),l.jsxs("div",{className:"nc-set-form nc-diag-controls",children:[l.jsx("div",{className:"nc-sheet-label",children:f("diagnostics-verbose")}),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("select",{"aria-label":f("diagnostics-duration"),value:R,onChange:O=>E(Number(O.target.value)),disabled:n,children:[300,900,1800,3600].map(O=>l.jsxs("option",{value:O,children:[O/60," min"]},O))}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:n||(h==null?void 0:h.verbose)===!0,onClick:()=>L(()=>Cg(e,!0,R,u.route)),children:f("enable")}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||(h==null?void 0:h.verbose)!==!0,onClick:()=>L(()=>Cg(e,!1,R,u.route)),children:f("stop")})]}),l.jsx("small",{className:"nc-set-hint",children:h!=null&&h.verbose?f("diagnostics-expires").replace("{time}",new Date(h.expiresAt).toLocaleTimeString()):f("diagnostics-off")})]}),l.jsxs("div",{className:"nc-diag-filters",children:[l.jsxs("select",{"aria-label":f("diagnostics-level"),value:$,onChange:O=>B(O.target.value),children:[l.jsx("option",{value:"all",children:f("diagnostics-all-levels")}),["debug","info","warn","error"].map(O=>l.jsx("option",{value:O,children:O},O))]}),l.jsx("input",{"aria-label":f("diagnostics-component"),placeholder:f("diagnostics-component"),value:K,onChange:O=>V(O.target.value)})]}),l.jsxs("div",{className:"nc-set-row",children:[l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:b,onChange:O=>S(O.target.checked)})," ",f("diagnostics-pause")]}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:C,onChange:O=>x(O.target.checked)})," ",f("diagnostics-autoscroll")]})]}),l.jsx("pre",{ref:te,className:"nc-diag-log","aria-label":f("diagnostics-log"),children:H||f("diagnostics-empty")}),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:A,children:f("copy")}),l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:z,children:f("diagnostics-export")}),l.jsx("button",{type:"button",className:"nc-btn danger",disabled:n,onClick:()=>{window.confirm(f("diagnostics-clear-confirm"))&&L(async()=>{const O=await J0(e,u.route);return Y.current=0,v([]),O})},children:f("diagnostics-clear")})]}),y&&l.jsx("div",{className:"nc-err",children:y})]})}function Bj({token:e,settings:t,readonly:n,refresh:s,roster:o,section:a,setSection:u}){const[h,p]=N.useState(null),[m,v]=N.useState(null),[y,w]=N.useState(!1),[b,S]=N.useState(!1),[C,x]=N.useState(null),[R,E]=N.useState(!0),[$,B]=N.useState(!1);N.useEffect(()=>{x(t&&t.update||null),E(!t||t.autoUpdate!==!1),B(!!(t&&t.alternateScreen))},[t]);const K=async()=>{p(null),v(null),S(!0);try{const A=await L0(e);v(A.note||"ok"),w(!1)}catch(A){p(String(A.message||A))}S(!1)},V=async()=>{p(null),v(null),S(!0);try{const A=await V0(e);v(`${A.note||"ok"}${A.target?` (${A.target})`:""}`)}catch(A){p(String(A.message||A))}S(!1)},Y=async A=>{p(null),v(null),S(!0);try{await Kd(e,{autoUpdate:A}),E(A),s&&await s()}catch(z){p(String(z.message||z))}S(!1)},te=async A=>{p(null),v(null),S(!0);try{await Kd(e,{alternateScreen:A}),B(A),s&&await s()}catch(z){p(String(z.message||z))}S(!1)},Q=async()=>{p(null),v(null),S(!0);try{x(await Y0(e))}catch(A){p(String(A.message||A))}S(!1)},J=async()=>{p(null),v(null),S(!0);try{const A=await G0(e);x(A),v(f("npm-update-restarting"))}catch(A){p(String(A.message||A))}S(!1)},H=()=>{window.confirm(f("composer-clear-confirm"))&&(p(null),XE()?(window.dispatchEvent(new Event(Ih)),v(f("composer-clear-done"))):p(f("composer-clear-failed")))},L=t&&t.service;return l.jsxs("div",{className:"nc-set-tab",children:[l.jsx("div",{className:"nc-system-tabs",role:"tablist","aria-label":f("tab-system"),children:["general","diagnostics"].map(A=>l.jsx("button",{type:"button",role:"tab","aria-selected":a===A,className:`nc-set-tabbtn${a===A?" on":""}`,onClick:()=>u(A),children:f(`system-${A}`)},A))}),a==="general"&&l.jsxs(l.Fragment,{children:[l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:f("system-this-node")}),t&&l.jsxs("div",{className:"nc-set-info",children:["v",t.version," · ",t.platform," · :",t.port,l.jsx("br",{}),L&&L.installed?f("service-installed"):f("service-missing"),L&&L.installed?` · ${L.active?f("service-active"):f("service-inactive")}`:"",L?` · boot ${L.boot?"on":"off"}`:""]}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||b,title:n?f("settings-readonly"):"",onClick:V,children:f("service-regenerate")})}),l.jsx(Tj,{token:e,readonly:n}),l.jsx(Mj,{})]}),l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:f("system-updates")}),l.jsxs("div",{className:"nc-set-form nc-update-settings",children:[l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:R,disabled:n||b||C&&!C.supported,onChange:A=>Y(A.target.checked)}),l.jsxs("span",{children:[l.jsx("b",{children:f("npm-auto-update")}),l.jsx("small",{children:f("npm-auto-update-help")})]})]}),C&&l.jsxs("div",{className:"nc-set-info",children:[f("npm-update-current")," v",C.current,C.latest?` · ${f("npm-update-latest")} v${C.latest}`:""," · ",f(`npm-update-${C.supported?C.phase:"unsupported"}`)]}),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||b||!C||!C.supported,onClick:Q,children:f("npm-update-check")}),C&&C.available&&l.jsx("button",{type:"button",className:"nc-btn primary",disabled:n||b||C.phase==="installing",onClick:J,children:f("npm-update-install")})]}),C&&C.lastError&&l.jsx("div",{className:"nc-err",children:C.lastError})]})]}),l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:f("system-security")}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||b,title:n?f("settings-readonly"):"",onClick:()=>{p(null),v(null),w(!0)},children:f("token-rotate")})})]}),l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:f("system-local-data")}),l.jsxs("div",{className:"nc-set-form",children:[l.jsx("div",{className:"nc-sheet-label",children:f("composer-clear-data")}),l.jsx("small",{className:"nc-set-hint",children:f("composer-clear-data-help")}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:H,children:f("composer-clear-data")})})]})]})]}),a==="diagnostics"&&l.jsxs("section",{className:"nc-system-group nc-system-diagnostics",children:[l.jsx("h3",{children:f("system-diagnostics")}),l.jsxs("div",{className:"nc-set-form nc-alternate-screen-settings",children:[l.jsx("div",{className:"nc-sheet-label",children:f("system-terminal")}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox","aria-label":f("alternate-screen"),checked:$,disabled:n||b,onChange:A=>te(A.target.checked)}),l.jsxs("span",{children:[l.jsx("b",{children:f("alternate-screen")}),l.jsx("small",{children:f("alternate-screen-help")})]})]})]}),l.jsx(Oj,{token:e,roster:o,readonly:n})]}),y&&l.jsxs("div",{className:"nc-set-confirm",children:[l.jsx("div",{children:f("token-rotate-explain")}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:b,onClick:()=>w(!1),children:f("cancel")}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:b,onClick:K,children:f("confirm")})]})]}),m&&l.jsx("div",{className:"nc-set-note",children:m}),h&&l.jsx("div",{className:"nc-err",children:h})]})}function zj({token:e,onClose:t,initialTab:n="nodes",initialLocation:s="",startNewCell:o=!1}){En();const a=n==="diagnostics"?"diagnostics":"general",[u,h]=N.useState(n==="diagnostics"?"system":n),p=N.useRef(null),m=N.useRef(null),[v,y]=N.useState({start:!1,end:!1}),[w,b]=N.useState(a),[S,C]=N.useState(null),[x,R]=N.useState([]),[E,$]=N.useState([]),[B,K]=N.useState(!1),[V,Y]=N.useState(null),[te,Q]=N.useState(0),J=sf(e,!0,te),H=N.useCallback(()=>{const A=p.current;if(!A)return;const z=A.scrollWidth>A.clientWidth+1,O={start:z&&A.scrollLeft>1,end:z&&A.scrollLeft+A.clientWidth<A.scrollWidth-1};y(T=>T.start===O.start&&T.end===O.end?T:O)},[]);N.useEffect(()=>{const A=p.current;if(!A)return;const z=typeof ResizeObserver=="function"?new ResizeObserver(H):null;return z==null||z.observe(A),window.addEventListener("resize",H),H(),()=>{z==null||z.disconnect(),window.removeEventListener("resize",H)}},[H]),N.useEffect(()=>{var z,O;(O=(z=m.current)==null?void 0:z.scrollIntoView)==null||O.call(z,{behavior:"smooth",block:"nearest",inline:"nearest"});const A=window.requestAnimationFrame?window.requestAnimationFrame(H):setTimeout(H,0);return()=>{window.cancelAnimationFrame?window.cancelAnimationFrame(A):clearTimeout(A)}},[u,H]);const L=N.useCallback(async()=>{var A;try{const z=await ny(e);C(z),Y(null)}catch(z){Y(String(z.message||z))}try{const O=(await P0(e)).peers||[];let T=[],F=[];try{const[k,I]=await Promise.all([Ut("/api/config",e).then(G=>G.json()).catch(()=>null),sy(e).catch(()=>null)]),D=k&&typeof k.instanceId=="string"?k.instanceId:"",M=[{instanceId:D||null,route:[],label:null},...fy(I,D)],W=await Promise.all(M.map(async G=>{try{return{ok:!0,peers:((await iy(e,G.route)).nodes||[]).map(he=>hy(he,G)).filter(Boolean)}}catch(ue){return{ok:!1,owner:G,error:ue}}}));for(const G of W){if(G.ok){T.push(...G.peers);continue}G.owner.route.length!==0&&F.push({instanceId:G.owner.instanceId,label:G.owner.label,route:G.owner.route,failure:/timeout/i.test(String(((A=G.error)==null?void 0:A.message)||G.error))?"timeout":"unreachable"})}}catch{}$(F),R([...O,...T])}catch(z){Y(String(z.message||z))}},[e]);return N.useEffect(()=>{L();const A=setInterval(L,5e3);return()=>clearInterval(A)},[L]),N.useEffect(()=>{let A=!1;return Ut("/api/config",e).then(z=>z.json()).then(z=>{A||K(!!z.readonlyDefault)}).catch(()=>{}),()=>{A=!0}},[e]),l.jsx("div",{className:"nc-set-overlay",onClick:t,children:l.jsxs("div",{className:"nc-set-panel",onClick:A=>A.stopPropagation(),children:[l.jsxs("div",{className:"nc-set-head",children:[l.jsx(Ge,{name:"gear",size:18}),l.jsx("b",{children:f("settings")}),l.jsx("button",{type:"button",className:"nc-set-close",onClick:t,title:f("close"),children:l.jsx(Ge,{name:"x",size:18})})]}),B&&l.jsx("div",{className:"nc-set-readonly",children:f("settings-readonly")}),V&&l.jsx("div",{className:"nc-err",children:V}),l.jsx("div",{className:`nc-set-tabs-wrap${v.start?" has-start-overflow":""}${v.end?" has-end-overflow":""}`,children:l.jsx("div",{className:"nc-set-tabs",ref:p,onScroll:H,children:["nodes","fleet","audio","input","system"].map(A=>l.jsx("button",{ref:u===A?m:null,type:"button",className:`nc-set-tabbtn${u===A?" on":""}`,onClick:()=>h(A),children:f(`tab-${A}`)},A))})}),l.jsxs("div",{className:"nc-set-body",children:[u==="nodes"&&l.jsx(Lj,{token:e,nodes:x,roster:J,settings:S,readonly:B,vlUnavailable:E,refresh:L,refreshAliases:()=>Q(A=>A+1)}),u==="fleet"&&l.jsx(fj,{token:e,readonly:B,startNewCell:o,initialLocation:s,targets:J.map(A=>({route:A.route,label:A.label||A.name,status:A.status}))}),u==="audio"&&l.jsx(Dj,{token:e,readonly:B,nodes:x,settings:S}),u==="input"&&l.jsx(Ij,{}),u==="system"&&l.jsx(Bj,{token:e,settings:S,readonly:B,refresh:L,roster:J,section:w,setSection:b})]})]})})}function $j({token:e,initialPair:t,deviceDefault:n="",localNodeId:s="",localNameDefault:o="",onPairDone:a,onDone:u}){En();const[h,p]=N.useState(t?"pair":"welcome"),[m,v]=N.useState(!1),[y,w]=N.useState(null),b=async()=>{v(!0),w(null);try{await Kd(e,{wizardDone:!0}),a&&a(),u()}catch(S){w(String(S.message||S)),v(!1)}};return l.jsx("div",{className:"nc-wiz-overlay",children:l.jsxs("div",{className:"nc-wiz",children:[l.jsxs("div",{className:"nc-wiz-head",children:[l.jsx("b",{children:f("wizard-title")}),l.jsx("small",{children:f("hydra-simple")})]}),h==="welcome"&&l.jsxs("div",{className:"nc-wiz-body",children:[l.jsx("div",{className:"nc-wiz-done",children:f("local-ready")}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{className:"nc-btn ghost",disabled:m,onClick:b,children:f("local-only")}),l.jsx("button",{className:"nc-btn primary",disabled:m,onClick:()=>p("pair"),children:f("add-node")})]})]}),h==="pair"&&l.jsxs("div",{className:"nc-wiz-body",children:[l.jsx(Xw,{token:e,initial:t||"",autoStart:!!t,deviceDefault:n,localNodeId:s,localNameDefault:o,onBusyChange:v,onSuccess:async()=>{a&&a(),p("done")}}),l.jsx("div",{className:"nc-sheet-actions",children:l.jsx("button",{className:"nc-btn ghost",disabled:m,onClick:()=>{a&&a(),p("welcome")},children:f("back")})})]}),h==="done"&&l.jsxs("div",{className:"nc-wiz-body",children:[l.jsx("div",{className:"nc-wiz-done",children:f("node-connected")}),l.jsx("div",{className:"nc-sheet-actions",children:l.jsx("button",{className:"nc-btn primary",disabled:m,onClick:b,children:f("finish")})})]}),y&&l.jsx("div",{className:"nc-err",children:y})]})})}function Fj(e,t){if(typeof EventSource>"u"||!e)return()=>{};const n=new EventSource(`/api/events?token=${encodeURIComponent(e)}`);return n.onmessage=s=>{try{const o=JSON.parse(s.data);o&&typeof o=="object"&&typeof o.type=="string"&&t(o)}catch{}},()=>{try{n.close()}catch{}}}const Hj=6e3,Wj=12e3;function Uj({n:e,onClose:t}){return l.jsxs("div",{className:`nc-ntf-toast${e.urgency==="high"?" high":""}`,role:"status","aria-live":"polite",children:[l.jsxs("div",{className:"nc-ntf-toast-txt",children:[l.jsx("b",{children:e.title}),e.body&&l.jsx("small",{children:e.body}),e.session&&l.jsx("span",{className:"nc-ntf-from",children:e.session})]}),l.jsx("button",{type:"button",className:"nc-ntf-x",onClick:t,title:f("close"),children:l.jsx(Ge,{name:"x",size:14})})]})}function Kj({ask:e,token:t,onAnswered:n,onDismiss:s}){const[o,a]=N.useState(""),[u,h]=N.useState(!1),[p,m]=N.useState(null),[v,y]=N.useState(!1),w=async S=>{const C=String(S||"").trim();if(!(!C||u)){m(null),h(!0);try{await ex(t,e.id,C),n(e.id)}catch(x){m(String(x.message||x))}h(!1)}},b=async()=>{if(!v){y(!0);try{await tx(t,e.id),s(e.id)}catch{y(!1)}}};return l.jsxs("div",{className:"nc-ask-card",children:[l.jsxs("div",{className:"nc-ask-head",children:[l.jsx("span",{className:"nc-ntf-from",children:e.session}),l.jsxs("code",{className:"nc-ask-id",children:["#",e.id]}),l.jsx("button",{type:"button",className:"nc-ask-dismiss",title:f("ask-dismiss"),"aria-label":f("ask-dismiss"),disabled:v,onClick:b,children:l.jsx(Ge,{name:"x",size:14})})]}),l.jsx("div",{className:"nc-ask-q",children:e.question}),Array.isArray(e.options)&&e.options.length>0&&l.jsx("div",{className:"nc-ask-opts",children:e.options.map(S=>l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:u,onClick:()=>w(S),children:S},S))}),l.jsxs("div",{className:"nc-ask-reply",children:[l.jsx("textarea",{rows:2,placeholder:f("ask-reply-ph"),value:o,disabled:u,onChange:S=>a(S.target.value)}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:u||!o.trim(),onClick:()=>w(o),children:f("send")})]}),p&&l.jsx("div",{className:"nc-err",children:p})]})}function qj({token:e}){const[t]=En(),[n]=fb(),[s,o]=N.useState([]),[a,u]=N.useState([]),[h,p]=N.useState(()=>{try{return/(?:^|[#&])ask=/.test(location.hash)}catch{return!1}}),m=N.useRef(0),v=N.useRef(null);v.current||(v.current=Rj());const y=N.useRef({enabled:n,lang:t});y.current={enabled:n,lang:t};const w=N.useCallback(x=>{o(R=>R.filter(E=>E.key!==x))},[]),b=N.useCallback(x=>{const R=`t${m.current+=1}`;o($=>[...$.slice(-3),{...x,key:R}]),setTimeout(()=>w(R),x.urgency==="high"?Wj:Hj);const E=y.current;if(E.enabled)try{v.current.enqueue(x,kj(x,E.lang))}catch{}},[w]);N.useEffect(()=>{n||v.current.stop()},[n]),N.useEffect(()=>{const x=()=>{(document.visibilityState!=="visible"||!document.hasFocus())&&v.current.stop()},R=()=>v.current.stop();return document.addEventListener("visibilitychange",x),window.addEventListener("blur",x),window.addEventListener(Hh,R),()=>{document.removeEventListener("visibilitychange",x),window.removeEventListener("blur",x),window.removeEventListener(Hh,R),typeof v.current.dispose=="function"?v.current.dispose():v.current.stop()}},[]),N.useEffect(()=>{if(!e)return;let x=!1;Z0(e).then(E=>{x||u(E.asks||[])}).catch(()=>{});const R=Fj(e,E=>{E.type==="notify"?b(E):E.type==="ask"&&E.ask&&E.ask.id?u($=>$.some(B=>B.id===E.ask.id)?$:[...$,E.ask]):E.type==="ask-answered"&&E.id?u($=>$.filter(B=>B.id!==E.id)):E.type==="ask-dismissed"&&E.id&&u($=>$.filter(B=>B.id!==E.id))});return()=>{x=!0,R()}},[e,b]);const S=x=>u(R=>R.filter(E=>E.id!==x)),C=x=>u(R=>R.filter(E=>E.id!==x));return l.jsxs(l.Fragment,{children:[s.length>0&&l.jsx("div",{className:"nc-ntf-toasts",children:s.map(x=>l.jsx(Uj,{n:x,onClose:()=>w(x.key)},x.key))}),a.length>0&&!h&&l.jsxs("button",{type:"button",className:"nc-ask-badge",onClick:()=>p(!0),title:f("asks-title"),children:["? ",l.jsx("span",{className:"nc-ask-count",children:a.length})]}),a.length>0&&h&&l.jsxs("div",{className:"nc-ask-panel",children:[l.jsxs("div",{className:"nc-ask-panel-head",children:[l.jsx("b",{children:f("asks-title")}),l.jsx("span",{className:"nc-ask-count",children:a.length}),l.jsx("button",{type:"button",className:"nc-ntf-x",onClick:()=>p(!1),title:f("close"),children:l.jsx(Ge,{name:"x",size:16})})]}),l.jsx("div",{className:"nc-ask-panel-body",children:a.map(x=>l.jsx(Kj,{ask:x,token:e,onAnswered:S,onDismiss:C},x.id))})]})]})}const Vj=4e3;async function Yj(e){const t=await Ut("/api/sessions",e);if((t==null?void 0:t.ok)===!1)throw new Error(`HTTP ${t.status}`);const n=await t.json();if(!Array.isArray(n==null?void 0:n.sessions))throw new Error("invalid sessions payload");return n.sessions}async function Fd(e,t=[]){var h;const[n,s]=await Promise.allSettled([t.length?Zh(e,t):Yj(e),bs(e,t)]),o=n.status==="fulfilled"&&Array.isArray((h=n.value)==null?void 0:h.sessions)?n.value.sessions:Array.isArray(n.value)?n.value:null,a=s.status==="fulfilled"?s.value:null,u=(a==null?void 0:a.available)===!0&&Array.isArray(a.cells)?a.cells:null;return{sessions:o,cells:u,fresh:Array.isArray(o)&&Array.isArray(u)}}function pb(e,t,n){return n===!0&&(e==null?void 0:e.degraded)!==!0&&(e==null?void 0:e.active)===!0&&e.tmux!==!1&&!!e.tmuxSession&&(t||[]).some(s=>(s==null?void 0:s.name)===e.tmuxSession)}function Gj(e){const t=new Map((e.sessions||[]).map(o=>[o.name,o])),n=[],s=(o,a,u,h=[],p="")=>{const m=new Map((a||[]).map(v=>[v.name,v]));for(const v of o||[]){const y=m.get(v.tmuxSession)||{},w=af(v,y),b=pb(v,a,u);n.push({key:Go(h,v.tmuxSession||v.cell),session:v.tmuxSession,route:h,cellName:v.cell,label:v.cell,node:h.length?h.join("/"):"",nodeLabel:p,live:b,selectable:b,verified:u===!0,working:w.working,degraded:!!v.degraded,active:v.active===!0,activity:y.activity||v.activity||0,subtitle:w.subtitle})}};s(e.cells,[...t.values()],e.localFresh===!0);for(const o of e.nodeGroups||[]){const a=Array.isArray(o.route)?o.route:[];o.kind==="vl"||!a.length||s(o.cells,o.sessions,o.switcherFresh===!0,a,o.label||o.name||"")}return n}function Xj(e){const t=new Map,n=Array.isArray(e.sessions)?e.sessions:[],s=Array.isArray(e.cells)?e.cells:[],o=new Map(n.map(u=>[u.name,u])),a=new Set(s.map(u=>u.tmuxSession).filter(Boolean));t.set("local",lf(s,n.filter(u=>!a.has(u.name)),o));for(const u of e.nodeGroups||[]){const h=Array.isArray(u.route)?u.route:[];if(u.kind==="vl"||!h.length)continue;const p=Array.isArray(u.cells)?u.cells:[],m=Array.isArray(u.sessions)?u.sessions:[],v=new Set(p.map(y=>y.tmuxSession).filter(Boolean));t.set(h.join("/"),$l({...u,route:h,cells:p,sessions:m,unmanaged:m.filter(y=>!v.has(y.name))}).rawItems)}return t}function Qj(e,t,n,s){return[...new Set(e.map(a=>a.node||"local"))].flatMap(a=>{const u=e.filter(v=>(v.node||"local")===a),h=new Map((t.get(a)||[]).map(v=>[v.key,v])),p=new Map(u.map(v=>[v.key,v])),m=u.map(v=>{const y=h.get(v.key);return{...v,label:(y==null?void 0:y.label)||v.label,live:(y==null?void 0:y.live)??v.live,fresh:(y==null?void 0:y.fresh)===!0,activity:(y==null?void 0:y.activity)??v.activity}});return vs(m,n,"all",$i(s,a)).map(v=>p.get(v.key))})}function Jj({token:e,current:t,onPick:n,onClose:s}){const[o,a]=N.useState(Bg),[u,h]=N.useState(!1),[p,m]=N.useState(!1),[v,y]=N.useState(""),[w,b]=N.useState(""),[S,C]=N.useState(""),x=N.useRef(null),R=N.useRef(null),E=N.useMemo(()=>Gj(o),[o]),$=N.useMemo(()=>Xj(o),[o]),{pins:B,orders:K,canMoveRoster:V,moveRoster:Y,stepRoster:te}=of(),Q=N.useMemo(()=>Qj(E,$,B,K),[E,$,B,K]),J=N.useMemo(()=>u?Q:Q.filter(O=>O.selectable||O.degraded&&O.active),[Q,u]),H=N.useMemo(()=>E.find(O=>O.key===w&&O.selectable),[E,w]);N.useEffect(()=>{var F;const O=document.activeElement;(F=R.current)==null||F.focus();const T=k=>{k.key==="Escape"&&s()};return document.addEventListener("keydown",T),()=>{var k;document.removeEventListener("keydown",T),(k=O==null?void 0:O.focus)==null||k.call(O)}},[s]),N.useEffect(()=>{let O=!0,T=!1;const F=async()=>{if(T)return;T=!0;const I=Bg(),D=Array.isArray(I.nodeGroups)?I.nodeGroups:[],M=Fd(e),W=re=>re.kind!=="vl"&&Array.isArray(re.route)&&re.route.length>0,G=await Promise.all(D.filter(W).map(async re=>({group:re,result:await Fd(e,re.route)}))),ue=await M;if(!O)return;const le=new Map(G.map(({group:re,result:_e})=>[JSON.stringify(re.route||[]),_e])),he=D.map(re=>{if(!W(re))return{...re,switcherFresh:!1};const _e=le.get(JSON.stringify(re.route||[]));return _e?{...re,sessions:_e.sessions||re.sessions||[],cells:_e.cells||re.cells||[],switcherFresh:_e.fresh}:{...re,switcherFresh:!1}}),we=xy({...I,sessions:ue.sessions||I.sessions||[],cells:ue.cells||I.cells||[],localFresh:ue.fresh,nodeGroups:he,refreshedAt:Date.now()});a(we),m(!0),T=!1};F();const k=setInterval(F,Vj);return()=>{O=!1,clearInterval(k)}},[e]);const L=O=>O.degraded?f("cell-degraded"):O.verified?O.selectable?O.working?f("cell-working"):f("cell-idle"):f("cell-off"):f("cell-switcher-not-confirmed"),A=O=>{if(y(""),!O.selectable){y(f("cell-switcher-not-active"));return}b(O.key)},z=async()=>{const O=H;if(!O){y(f("cell-switcher-select"));return}y(""),C(O.key);try{const T=await Fd(e,O.route),F=(T.cells||[]).find(k=>(k==null?void 0:k.cell)===O.cellName&&(k==null?void 0:k.tmuxSession)===O.session);if(!pb(F,T.sessions,T.fresh)){y(f("cell-switcher-not-active"));return}n({session:O.session,...O.node?{node:O.node}:{},cellName:O.cellName}),s()}catch{y(f("cell-switcher-not-active"))}finally{C("")}};return l.jsx("div",{className:"nc-cell-switcher-backdrop",onClick:s,children:l.jsxs("aside",{ref:x,className:"nc-cell-switcher",role:"dialog","aria-label":f("fleet-cells"),tabIndex:-1,onClick:O=>O.stopPropagation(),children:[l.jsxs("div",{className:"nc-cell-switcher-list",children:[!p&&l.jsx("div",{className:"nc-empty",role:"status",children:f("cell-switcher-refreshing")}),p&&J.length===0&&l.jsx("div",{className:"nc-empty",role:"status",children:f("cell-switcher-empty-active")}),J.map(O=>{const T=(t==null?void 0:t.session)===O.session&&((t==null?void 0:t.node)||"")===O.node,F=w===O.key,k=L(O),I=O.node||"local",D=$.get(I)||E.filter(M=>(M.node||"local")===I);return l.jsxs("div",{className:`nc-cell-switcher-row${T?" current":""}${F?" selected":""}${O.selectable?"":" off"}`,"data-roster-key":O.key,"data-position":I,children:[l.jsx(bi,{position:I,itemKey:O.key,label:O.cellName,canMove:V,onMove:(M,W)=>Y(I,M,W,D),onStep:M=>te(I,O.key,M,D)}),l.jsxs("button",{type:"button",className:"nc-cell-switcher-row-select","aria-current":T?"true":void 0,"aria-pressed":F,"aria-disabled":!O.selectable,disabled:S===O.key,onClick:()=>A(O),children:[l.jsx("span",{className:`nc-cell-switcher-dot${O.degraded?" warn":O.live?` on${O.working?" working":""}`:""}`}),l.jsxs("span",{className:"nc-cell-switcher-copy",children:[l.jsx("b",{children:O.cellName}),l.jsx("small",{className:"nc-cell-switcher-state",children:k}),l.jsx("small",{children:[O.nodeLabel,O.subtitle].filter(Boolean).join(" · ")})]})]})]},O.key)})]}),v&&l.jsx("div",{className:"nc-cell-switcher-notice",role:"status",children:v}),l.jsx("div",{className:"nc-cell-switcher-actions",children:l.jsx("button",{type:"button",className:"nc-cell-switcher-open",disabled:!H||!!S,onClick:z,children:H?`${f("cell-switcher-open")}: ${H.cellName}`:f("cell-switcher-select")})}),l.jsxs("div",{className:"nc-cell-switcher-controls",children:[l.jsx("b",{children:f("fleet-cells")}),l.jsx("button",{type:"button",className:"nc-cell-switcher-filter","aria-pressed":u,onClick:()=>{y(""),h(O=>!O)},children:f(u?"cell-switcher-show-active":"cell-switcher-show-all")}),l.jsx("button",{ref:R,type:"button",className:"nc-cell-switcher-close","aria-label":f("cell-switcher-close"),title:f("cell-switcher-close"),onClick:s,children:"×"})]})]})})}const Zj=2e3;function eR(e){if(e.kind==="gap")return`${f("vl-events-gap")} ${e.count||"?"}`;if(e.kind==="truncate")return f("vl-events-truncated");if(e.kind==="turn_end")return f("vl-events-turn-end");if(e.kind==="done")return f("vl-events-done");if(e.kind==="writer_epoch")return f("vl-events-writer-epoch");if(e.kind==="tool_start")return`${f("vl-events-tool")} ${e.name||""}`.trim();if(e.kind==="tool_end"){const t=e.isError?f("vl-events-tool-failed"):f("vl-events-tool-ok");return`${f("vl-events-tool")} ${e.name||""} — ${t}`.trim()}return e.kind==="usage"?e.text||f("vl-events-usage"):e.text||""}function tR({token:e,nodeId:t,route:n=[]}){const[s,o]=N.useState([]),[a,u]=N.useState(!1),h=N.useRef(0),p=N.useRef(!1);return N.useEffect(()=>{let m=!0;h.current=0,p.current=!1,o([]);const v=async()=>{if(!p.current){p.current=!0;try{const b=await A0(e,t,h.current,n);if(!m)return;u(!1);const C=(Array.isArray(b==null?void 0:b.events)?b.events:[]).filter(x=>Number.isSafeInteger(x==null?void 0:x.seq)&&x.seq>h.current);C.length&&(o(x=>x.concat(C).slice(-500)),h.current=C[C.length-1].seq),Number.isSafeInteger(b==null?void 0:b.cursor)&&b.cursor>h.current&&(h.current=b.cursor)}catch{m&&u(!0)}finally{p.current=!1}}},y=()=>{v().catch(()=>{})};y();const w=setInterval(y,Zj);return()=>{m=!1,clearInterval(w)}},[e,t,JSON.stringify(n)]),l.jsxs("div",{className:"nc-vl-events",children:[a&&l.jsx("div",{className:"nc-set-hint nc-vl-events-stale",children:f("vl-events-stale")}),s.length===0&&!a&&l.jsx("small",{className:"nc-set-hint","data-testid":"vl-events-empty",children:f("vl-events-empty")}),s.length>0&&l.jsx("ol",{className:"nc-vl-events-list",children:s.map(m=>l.jsx("li",{"data-testid":`vl-ev-${m.seq}`,className:`nc-vl-ev nc-vl-ev-${m.kind}${m.isError?" error":""}${m.kind==="gap"?" gap":""}`,children:eR(m)},`${m.seq}-${m.kind}`))})]})}function H_({peer:e,token:t,onBack:n}){var s;return En(),e?l.jsxs("section",{className:"nc-vl-session-view",children:[l.jsxs("header",{className:"nc-bar nc-bar-single",children:[l.jsxs("button",{onClick:n,title:f("back"),children:[l.jsx(Ge,{name:"chevronLeft",size:18}),l.jsx("span",{className:"nc-bar-label",children:f("back")})]}),l.jsxs("span",{className:"nc-bar-center",children:[l.jsx("b",{title:e.label,children:e.label}),((s=e.session)==null?void 0:s.profile)&&l.jsxs("small",{className:"nc-bar-sub",children:[e.session.profile," · ",f("vl-events-title")]})]}),l.jsx("span",{className:"nc-bar-right"})]}),l.jsx("div",{className:"nc-vl-session-body",children:l.jsx(tR,{token:t,nodeId:e.nodeId,route:e.route||[]})})]}):null}const Hd=e=>ki(Ys(e)).length===0,Wd=e=>Array.isArray(e)?e.join("/"):"";function nR(e){const t=new Set,n=[];for(const s of Array.isArray(e)?e:[])!s||!Kn.test(String(s.instanceId||""))||!Array.isArray(s.route)||!s.route.length||t.has(s.instanceId)||(t.add(s.instanceId),n.push({instanceId:s.instanceId,route:[...s.route],label:String(s.label||s.name||s.route.join(" › ")),status:s.status||"offline"}));return n.sort((s,o)=>s.label.localeCompare(o.label))}function zo(e){return{instanceId:e.ownerId,route:e.ownerRoute||[],label:e.ownerLabel,status:e.available===!1?"offline":"up"}}function Hs(e,t,n,s=!1,o=!0){const a=t.instanceId;return{...e,id:Lr(s?null:a,e.name),ownerId:a,ownerRoute:s?[]:[...t.route],ownerLabel:s?"Local":t.label,local:s,available:o,ownerTopology:Array.isArray(n)?n:[],layout:Bh(e.layout,a,n)}}function iR(e,t,n,s,o=[]){const[a,u]=N.useState([]),[h,p]=N.useState(!1),[m,v]=N.useState("idle"),[y,w]=N.useState(""),[b,S]=N.useState(""),C=N.useRef([]),x=N.useRef([]),R=N.useRef(""),E=N.useRef(t),$=N.useRef(n),B=N.useRef(!1),K=N.useRef(!0),V=N.useRef(""),Y=N.useMemo(()=>nR(o),[o]),te=Y.map(D=>`${D.instanceId}:${Wd(D.route)}:${D.status}:${D.label}`).join("|");x.current=Y,$.current=n,E.current=t,C.current=a;const Q=N.useCallback(D=>zh(D.layout,R.current,x.current),[]),J=N.useCallback((D,M=!0,W=E.current)=>{const G=Yv(D,xl()),ue=C.current.some(he=>he.id===W);C.current=G,u(G);const le=G.find(he=>he.id===W);if(M&&le){K.current=!0;const he=Q(le);s(he),le.local&&wN(le.name,he)}else ue&&!le&&(K.current=!0,s(Ar()),w("deck non più condiviso dal nodo owner"));gN(G.filter(he=>he.local).map(he=>he.name))},[s,Q]),H=N.useCallback(async D=>{let M=await pl(e);const W=M.decks.find(G=>G.name==="main");if(M.decks.length===1&&W&&W.revision===0&&Hd(W.layout)){const G=mN(),ue=Ys($h("main")||Ar());if(!Hd(ue)){const le=Bh(ue,D,[]);M.decks[0]=await ml(e,"main",le,0,[])}for(const le of G.filter(he=>he!=="main"))try{let he=await Eg(e,le,[]);const we=Ys($h(le)||Ar());Hd(we)||(he=await ml(e,le,Bh(we,D,[]),he.revision,[]))}catch{}M=await pl(e)}return M},[e]),L=N.useCallback(async({migrate:D=!1}={})=>{const M=await ef(e,[]),W=Kn.test(String(M.instanceId||""))?M.instanceId:"";if(!W)throw new Error("instanceId locale non disponibile");R.current=W,S(W);const[G,ue]=await Promise.all([D?H(W):pl(e),Sg(e,[]).catch(()=>({nodes:[]}))]),le={instanceId:W,route:[],label:"Local"},he=G.decks.map(re=>Hs(re,le,ue.nodes,!0,!0)),we=C.current;return await Promise.all(x.current.map(async re=>{if(re.status!=="up"){he.push(...we.filter(_e=>!_e.local&&_e.ownerId===re.instanceId).map(_e=>({..._e,ownerRoute:[...re.route],ownerLabel:re.label,available:!1})));return}try{const[_e,ze]=await Promise.all([pl(e,re.route),Sg(e,re.route).catch(()=>({nodes:[]}))]);he.push(..._e.decks.map(ut=>Hs(ut,re,ze.nodes,!1,!0)))}catch{he.push(...we.filter(ze=>!ze.local&&ze.ownerId===re.instanceId).map(ze=>({...ze,ownerRoute:[...re.route],ownerLabel:re.label,available:!1})))}})),he.sort((re,_e)=>re.local===_e.local?re.ownerLabel.localeCompare(_e.ownerLabel)||(re.name==="main"?-1:_e.name==="main"?1:re.name.localeCompare(_e.name)):re.local?-1:1),he},[e,H,te]);N.useEffect(()=>{if(!e)return;let D=!1;const M=V.current!==e;return V.current=e,L({migrate:M}).then(W=>{if(D)return;const G=C.current.find(he=>he.id===E.current),ue=W.find(he=>he.id===E.current),le=ue&&(!G||ue.revision>G.revision||G.available!==ue.available||Wd(G.ownerRoute)!==Wd(ue.ownerRoute));J(W,M||!!le&&!B.current),p(!0),ue&&w("")}).catch(W=>{D||(p(!0),w(String(W.message||W)))}),()=>{D=!0}},[J,L,te,e]);const A=N.useCallback(async(D=E.current)=>{if(!h||!B.current)return!0;const M=C.current.find(W=>W.id===D);if(!M)return w(`deck inesistente: ${D}`),!1;if(M.available===!1)return w(`nodo owner offline: ${M.ownerLabel}`),!1;v("saving");try{const W=qv(Ys($.current),M.ownerId,M.ownerTopology),G=await ml(e,M.name,W,M.revision,M.ownerRoute),ue=Hs(G,zo(M),M.ownerTopology,M.local,!0);return J(C.current.map(le=>le.id===D?ue:le),!1),B.current=!1,v("saved"),w(""),setTimeout(()=>v("idle"),1500),!0}catch(W){if(v("error"),w(String(W.message||W)),W.status===409&&W.data&&W.data.current){const G=C.current.find(le=>le.id===D),ue=Hs(W.data.current,zo(G),G.ownerTopology,G.local,!0);J(C.current.map(le=>le.id===D?ue:le),!1)}return!1}},[h,e,J]);return N.useEffect(()=>{if(!h)return;if(K.current){K.current=!1;return}B.current=!0,v("saving");const D=setTimeout(A,650);return()=>clearTimeout(D)},[n,h,A]),N.useEffect(()=>{if(!h)return;const D=setInterval(async()=>{try{const M=await L(),W=C.current.find(le=>le.id===E.current),G=M.find(le=>le.id===E.current),ue=G&&(!W||G.revision>W.revision||W.available!==G.available);J(M,ue&&!B.current)}catch{}},5e3);return()=>clearInterval(D)},[h,L,J]),{decks:a,records:a,localNodeId:b,ready:h,saveState:m,error:y,setError:w,saveNow:A,select:async D=>{if(B.current&&!await A(E.current))throw new Error("salvataggio del deck corrente fallito: cambio annullato");const M=C.current.find(W=>W.id===D);if(!M)throw new Error(`deck inesistente: ${D}`);return B.current=!1,K.current=!0,Q(M)},add:async(D,M=null)=>{const W=M===Si?C.current.find(le=>le.local):M?C.current.find(le=>le.ownerId===M):null;if(!W||W.available===!1)throw new Error("nodo owner non disponibile");const G=await Eg(e,D,W.ownerRoute),ue=Hs(G,zo(W),W.ownerTopology,W.local,!0);return J([...C.current,ue],!1),ue},rename:async(D,M)=>{const W=C.current.find(we=>we.id===D);if(!W)throw new Error("deck inesistente");if(D===E.current&&B.current&&!await A(D))throw new Error(`salvataggio di "${W.name}" fallito: rinomina annullata`);const G=C.current.find(we=>we.id===D);if(!G)throw new Error("deck inesistente");const ue=await nx(e,G.name,M,G.revision,G.ownerRoute),le=Hs(ue,zo(G),G.ownerTopology,G.local,!0),he=G.local?Si:G.ownerId;return md(_N(xl(),he,D,le.id)),J(C.current.map(we=>we.id===D?le:we),!1),le},remove:async D=>{const M=C.current.find(G=>G.id===D);if(!M)throw new Error("deck inesistente");D===E.current&&(B.current=!1),await ix(e,M.name,M.revision,M.ownerRoute);const W=M.local?Si:M.ownerId;md(yN(xl(),W,D)),J(C.current.filter(G=>G.id!==D),!1)},reorder:(D,M)=>{const W=C.current.find(re=>re.id===D),G=C.current.find(re=>re.id===M);if(!W||!G)return!1;const ue=W.local?Si:W.ownerId,le=G.local?Si:G.ownerId;if(ue!==le)return!1;const he=C.current.filter(re=>(re.local?Si:re.ownerId)===ue).map(re=>re.id),we=md(vN(xl(),ue,D,M,he));return J(Yv(C.current,we),!1),!0},addTileTo:async(D,M)=>{const W=C.current.find(re=>re.id===D);if(!W)throw new Error("deck inesistente");if(W.available===!1)throw new Error(`nodo owner offline: ${W.ownerLabel}`);const G=Lw(M,R.current,x.current);if(!G)throw new Error("riferimento sessione non valido");const ue=Q(W),le=qv(wy(ue,G),W.ownerId,W.ownerTopology),he=await ml(e,W.name,le,W.revision,W.ownerRoute),we=Hs(he,zo(W),W.ownerTopology,W.local,!0);return J(C.current.map(re=>re.id===D?we:re),!1),we},localMainId:Lr(null,"main"),parseDeckId:rc}}const sR="/sw.js",Uh="nc-sw-update";let Kh=null,qh=!1,Vh=null,mb=Object.freeze({needed:!1,kind:null,version:""}),gb=!1;function vb(){typeof window<"u"&&window.dispatchEvent(new Event(Uh))}function _b(){const e=Vh||(qh?{kind:"reload",version:""}:null);mb=Object.freeze({needed:!!e,kind:(e==null?void 0:e.kind)||null,version:(e==null?void 0:e.version)||""})}function W_(){return mb}function rR(e){return typeof window>"u"?()=>{}:(window.addEventListener(Uh,e),()=>window.removeEventListener(Uh,e))}function Ff(e){qh!==e&&(qh=e,_b(),vb())}const Ud="nc-auto-reload";function oR(){try{return typeof sessionStorage<"u"?sessionStorage:null}catch{return null}}function aR(e,t,n,s={}){let o=null;e&&t&&e!==t?o={kind:"install",version:e}:t&&n&&t!==n&&(o={kind:"reload",version:t});const a=JSON.stringify(o)===JSON.stringify(Vh);Vh=o,_b(),a||vb();const u=s.storage===void 0?oR():s.storage;if(!o){try{u&&u.removeItem(Ud)}catch{}return}if(o.kind!=="reload"||!u)return;const h=`${t}|${n}`;try{if(u.getItem(Ud)===h)return;u.setItem(Ud,h)}catch{return}(s.applyImpl||yb)()}function lR(e){e.addEventListener("statechange",()=>{e.state==="installed"&&navigator.serviceWorker.controller&&Ff(!0)})}function cR(){typeof navigator>"u"||!("serviceWorker"in navigator)||(navigator.serviceWorker.addEventListener("controllerchange",()=>{gb&&location.reload()}),navigator.serviceWorker.register(sR).then(e=>{Kh=e,e.waiting&&Ff(!0),e.addEventListener("updatefound",()=>{const t=e.installing;t&&lR(t)}),setInterval(()=>{e.update().catch(()=>{})},3600*1e3)}).catch(()=>{}))}function yb(){gb=!0,Ff(!1);const e=Kh&&Kh.waiting;e?(e.postMessage({type:"SKIP_WAITING"}),setTimeout(()=>location.reload(),4e3)):location.reload()}function uR({hash:e="",origin:t="",pathname:n="",search:s=""}={}){const o=String(e||"").replace(/^#/,""),a=`${n||""}${s||""}`;if(!o)return{token:"",pair:"",nextUrl:a};const u=new URLSearchParams(o),h=u.get("token")||"",p=u.get("pair")||"",m=p?`${t||""}${n||""}#pair=${p}`:"";return{token:h,pair:m,nextUrl:a}}const wb=9,bb=24,Sb="nc_side_w",U_="nc_side_min",dR=240,K_="(min-width:1024px) and (pointer:fine)";function hR(){const e=Number(localStorage.getItem(Sb));return e>=180&&e<=480?e:dR}function fR(){const e=Number(localStorage.getItem("nc_fontsize"));return e>=wb&&e<=bb?e:13}function pR(){const e={token:"",pair:""};try{const{token:t,pair:n,nextUrl:s}=uR({hash:location.hash,origin:location.origin,pathname:location.pathname,search:location.search});if(t){e.token=t;try{localStorage.setItem("nc_token",t)}catch{}}if(n){e.pair=n;try{sessionStorage.setItem("nc_pair",n)}catch{}}if(location.hash)try{history.replaceState(null,"",s)}catch{}}catch{}if(e.token||(e.token=sessionStorage.getItem("nc_token")||localStorage.getItem("nc_token")||""),!e.pair){const t=sessionStorage.getItem("nc_pair");t&&(e.pair=t)}return e}function mR(e){try{return Ys($h(e))}catch{return Ar()}}function q_(e){if(!e)return"";const t=Math.floor(Date.now()/1e3)-e;return t<0||t<60?"ora":t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}g`}function gR(){const[e,t]=N.useState(()=>window.matchMedia(K_).matches);return N.useEffect(()=>{const n=window.matchMedia(K_),s=o=>t(o.matches);return n.addEventListener("change",s),()=>n.removeEventListener("change",s)},[]),e}function V_({session:e,node:t,ownerId:n,cellName:s,token:o,readonly:a=!1,onBack:u,onCellSwitcher:h,cellSwitcherOpen:p=!1}){En();const[m]=Cf(),[v,y]=N.useState(!1),[w,b]=N.useState(()=>window.matchMedia("(pointer: coarse)").matches),[S,C]=N.useState(null),[x,R]=N.useState(fR),[E,$]=N.useState(s||e),[B,K]=N.useState(""),V=T=>R(F=>{const k=Math.max(wb,Math.min(bb,F+T));return localStorage.setItem("nc_fontsize",String(k)),k}),Y=N.useRef(()=>{}),te=N.useRef(()=>!1),Q=N.useRef(()=>{}),J=N.useRef(!1),[H,L]=N.useState(!1),[A,z]=N.useState(!1),O=()=>{J.current=!J.current,L(J.current)};return N.useEffect(()=>{$(s||e)},[s,e]),N.useEffect(()=>{let T=!0;const F=t?t.split("/"):[],k=t?`/api/route/${t.split("/").map(encodeURIComponent).join("/")}/_`:"/api";async function I(){let M=null,W=null;try{const le=await(await Ut(`${k}/sessions`,o)).json();Array.isArray(le.sessions)&&(M=le.sessions.find(he=>he.name===e))}catch{}try{const ue=await bs(o,F);ue.available&&Array.isArray(ue.cells)&&(W=ue.cells.find(le=>le.tmuxSession===e))}catch{}if(!T)return;$(Ef({session:e,cell:W||(s?{cell:s}:null)}));let G="";W?G=`${W.engine}${W.key?`·${W.key}`:""}`:M&&(G=M.attached?`attached · ${q_(M.activity)}`:M.activity?q_(M.activity):""),K(G)}I();const D=setInterval(I,4e3);return()=>{T=!1,clearInterval(D)}},[e,t,o]),l.jsxs("div",{className:"nc-app",children:[l.jsxs("header",{className:"nc-bar nc-bar-single",children:[l.jsxs("button",{onClick:u,title:f("sessions"),children:[l.jsx(Ge,{name:"chevronLeft",size:18}),l.jsx("span",{className:"nc-bar-label",children:f("sessions")})]}),l.jsxs("span",{className:"nc-bar-center",children:[l.jsx("b",{title:t?`${E} · ${t}`:E,children:E}),B&&l.jsx("small",{className:"nc-bar-sub",children:B})]}),l.jsxs("span",{className:"nc-bar-right",children:[l.jsx("button",{onClick:()=>V(-1),title:f("zoom-out"),children:l.jsx(Ge,{name:"zoomOut",size:18})}),l.jsx("button",{onClick:()=>V(1),title:f("zoom-in"),children:l.jsx(Ge,{name:"zoomIn",size:18})}),l.jsx("button",{onClick:()=>b(T=>!T),title:f("composer"),children:l.jsx(Ge,{name:"keyboard",size:20})}),l.jsx("button",{onClick:()=>y(T=>!T),title:f("files"),children:l.jsx(Ge,{name:"folder",size:20})})]})]}),l.jsx("div",{className:"nc-termwrap",children:l.jsx(vw,{session:e,node:t,token:o,readonly:a,takeSize:!0,sendRef:Y,composerRef:te,actionRef:Q,ctrlRef:J,setCtrlArmed:L,onFiles:C,fontSize:x,selectionMode:A,onSelectionModeChange:z,keyboardGesture:m.terminalKeyboardGesture})}),l.jsx(zE,{onKeyboard:()=>b(T=>!T),onCellSwitcher:h,cellSwitcherOpen:p,send:T=>Y.current(T),action:T=>Q.current(T),ctrlArmed:H,onCtrl:O,selectionMode:A,onSelectionMode:z,keepKeyboardClosed:m.keybarKeepsKeyboardClosed,showEnter:m.showKeybarEnter,keybarLayout:m.keybarLayout}),w&&l.jsx(Nw,{submitText:T=>te.current(T),token:o,session:e,node:t,ownerId:n,keepKeyboardClosedOnVoice:m.voiceKeepsKeyboardClosed}),v&&l.jsx(_w,{session:e,node:t,token:o,filesEvent:S,onClose:()=>y(!1)})]})}function vR(){En();const[e]=N.useState(pR),[t,n]=N.useState(e.token),[s,o]=N.useState(e.pair||""),a=N.useCallback(()=>{o("");try{sessionStorage.removeItem("nc_pair")}catch{}},[]),[u,h]=N.useState(!1),p=gR(),[m]=N.useState(()=>pN(typeof location<"u"?location.pathname:"/")),[v,y]=N.useState(m.id),w=v===Lr(null,qn),[b,S]=N.useState(null),C=de=>{const Re=ws(de);S(Re?{...Re,...typeof(de==null?void 0:de.cellName)=="string"&&de.cellName?{cellName:de.cellName}:{}}:null)},[x,R]=N.useState([]),[E,$]=N.useState([]),[B,K]=N.useState([]),[V,Y]=N.useState(()=>m.ownerId?Ar():mR(m.name)),[te,Q]=N.useState(null),[J,H]=N.useState(null),L=de=>H(ws(de)),[A,z]=N.useState(null),O=sf(t,p),T=N.useMemo(()=>(O||[]).filter(de=>de.instanceId).map(de=>({instanceId:de.instanceId,route:de.route,label:de.label,status:de.status})),[O]),F=iR(t,v,V,Y,T),k=F.decks;N.useEffect(()=>{const de=new Map;for(const Re of O||[]){const $e=(Re.route||[Re.name]).join("/"),rt=new Set((Re.sessions||[]).map(wt=>wt.name));for(const wt of Re.cells||[])!wt.cell||!wt.tmuxSession||wt.cell===wt.tmuxSession||rt.has(wt.cell)||de.set(`${$e}:${wt.cell}`,`${$e}:${wt.tmuxSession}`)}Y(Re=>Lx(Re,de))},[O]),N.useEffect(()=>{F.localNodeId&&Y(de=>{const Re=zh(de,F.localNodeId,T);return JSON.stringify(Re)===JSON.stringify(de)?de:Re})},[T,F.localNodeId]);const[I,D]=N.useState(null),[M,W]=N.useState(null),G=N.useRef(0),[ue,le]=N.useState(!1),[he,we]=N.useState(hR),[re,_e]=N.useState(!w),[ze,ut]=N.useState(()=>w?localStorage.getItem(U_)==="1":!0),[nt,Ne]=N.useState(!1),[jt,tn]=N.useState("nodes"),[De,Tt]=N.useState(!1),[Qe,vt]=N.useState(""),[mt,it]=N.useState(!1),dt=(de="nodes",Re=!1,$e="")=>{tn(de),Tt(Re),vt($e),Ne(!0)},[ot,ht]=N.useState(!1),[st,ft]=N.useState({deviceDefault:"",localNodeId:"",localNameDefault:""}),[be,ce]=N.useState(!1);N.useEffect(()=>{try{localStorage.setItem(Sb,String(he))}catch{}},[he]),N.useEffect(()=>{try{localStorage.setItem(U_,ze?"1":"")}catch{}},[ze]),N.useEffect(()=>{if(!t)return;let de=!1;return Promise.all([ny(t),Ut("/api/config",t).then(Re=>Re.json())]).then(([Re,$e])=>{de||(ft({deviceDefault:Re.deviceName||"",localNodeId:Re.nodeId||"",localNameDefault:Re.localName||""}),ce(!!$e.readonlyDefault),(Re.firstRun===!0&&!$e.readonlyDefault||s)&&ht(!0))}).catch(()=>{}),()=>{de=!0}},[t,s]);const U=N.useCallback(async()=>{try{const Re=await(await Ut("/api/sessions",t)).json();Re.error||R(Re.sessions||[])}catch{}try{const de=await bs(t);$(de.available?de.cells||[]:[]),K(de.available?de.capabilities||[]:[])}catch{$([]),K([])}},[t]);N.useEffect(()=>{if(!p)return;U();const de=setInterval(U,4e3);return()=>clearInterval(de)},[p,U]),N.useEffect(()=>{let de=!1;const Re=()=>{Ut("/api/config",t).then(rt=>rt.json()).then(rt=>{de||aR(rt.version,rt.uiVersion,"0.8.57")}).catch(()=>{})};Re();const $e=setInterval(Re,6e4);return()=>{de=!0,clearInterval($e)}},[t]);const ne=new Set([...x.map(de=>de.name),...O.flatMap(de=>de.sessions.map(Re=>Re.key))]),j=ki(V),X=de=>Y(Re=>{const $e=Lw(de,F.localNodeId,T)||de,rt=wy(Re,$e);return rt===Re&&ki(Re).length>=9&&F.setError(f("grid-full")),rt}),ie=async(de,Re=[])=>{try{await Qh(t,de,Re)}catch{return}const $e=Re.length?`${Re.join("/")}:${de}`:de;Y(rt=>Hl(rt,$e)),U()},pe=async(de,Re,$e=[])=>{try{await ty(t,de,Re,$e)}catch{return}U()},ke=async(de,Re,$e=[])=>{await J_(t,{cell:de,enabled:!!Re},$e),U()},me=async de=>{if(!I)return;const{cell:Re}=I,$e=Array.isArray(I.route)?I.route:[];if(de.action==="up"){const wt=await Xh(t,{cell:Re,boot:!!de.boot,...de.engine?{engine:de.engine}:{},...de.model!==void 0?{model:de.model}:{},...de.permissionPolicy?{permissionPolicy:de.permissionPolicy}:{}},$e),Ss=df(wt);Ss&&F.setError(Ss.text)}else await Il(t,{cell:Re,boot:!!de.boot},$e);const rt=de.action==="up"?!!de.boot:de.boot?!1:!!I.boot;W({id:++G.current,cell:Re,route:$e,enabled:rt}),U()},xe=N.useCallback(de=>{W(Re=>(Re==null?void 0:Re.id)===de?null:Re)},[]),We=async de=>{if(!(!(de!=null&&de.direct)||ue)){le(!0);try{await tf(t,de.name,de.tunnelStatus==="up"?"down":"up")}finally{le(!1)}}},lt=async(de,Re)=>{const $e=String(Re||"").trim();return!(de!=null&&de.direct)||!Ir($e)?!1:(await ry(t,de.name,$e),!0)},Ke=de=>{const Re=k.find($e=>$e.id===de);if(!Re)return!1;try{const $e=window.open(pd(Re,t),"_blank");return $e&&($e.opener=null),!!$e}catch{return!1}},pt=async de=>{if(!de||de===v)return;const Re=await F.select(de),$e=F.records.find(rt=>rt.id===de);y(de),Y(Re),Q(null),H(null);try{history.replaceState(null,"",pd($e||de,null))}catch{}},Xe=async(de,Re)=>{const $e=await F.add(de,Re);await pt($e.id)},je=async(de,Re)=>{const $e=await F.rename(de,Re);if(de===v){y($e.id),Y(zh($e.layout,F.localNodeId,T)),Q(null),H(null);try{history.replaceState(null,"",pd($e,null))}catch{}}},_t=async de=>{await F.remove(de),de===v&&await pt(F.localMainId)},Sn=async(de,Re)=>{!Re||Re===v||(await F.addTileTo(Re,de),Y($e=>Hl($e,de)))};if(!t)return l.jsxs("div",{className:"nc-auth",children:[l.jsx("p",{children:f("auth-prompt")}),l.jsx("input",{onChange:de=>n(de.target.value.trim()),placeholder:"token"}),l.jsxs("label",{children:[l.jsx("input",{type:"checkbox",checked:u,onChange:de=>h(de.target.checked)})," ",f("remember-device")]}),l.jsx("button",{onClick:()=>{(u?localStorage:sessionStorage).setItem("nc_token",t)},children:"ok"})]});const Rn=l.jsxs(l.Fragment,{children:[nt&&l.jsx(zj,{token:t,initialTab:jt,initialLocation:Qe,startNewCell:De,onClose:()=>{Ne(!1),Tt(!1),vt("")}}),ot&&l.jsx($j,{token:t,initialPair:s,...st,onPairDone:a,onDone:()=>ht(!1)}),l.jsx(qj,{token:t})]});if(!p)return A?l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"nc-single-overlay",children:l.jsx(H_,{peer:A,token:t,onBack:()=>z(null)})}),Rn]}):b?l.jsxs(l.Fragment,{children:[l.jsx(V_,{session:b.session,node:b.node,ownerId:b.ownerId,cellName:b.cellName,token:t,readonly:be,onBack:()=>S(null),onCellSwitcher:()=>it(!0),cellSwitcherOpen:mt}),mt&&l.jsx(Jj,{token:t,current:b,onPick:de=>{C(de),it(!1)},onClose:()=>it(!1)}),Rn]}):l.jsxs(l.Fragment,{children:[l.jsx(Xx,{onPick:C,token:t,onSettings:dt,onOpenVlSession:z}),Rn]});const Rt=w||!re;return l.jsxs("div",{className:"nc-workspace",children:[Rt&&l.jsx(nN,{sessions:x,cells:E,activeSessions:j,nodeGroups:O,fleetCapabilities:B,bootSettlement:M,onBootSettlementApplied:xe,localNodeId:F.localNodeId,onPick:L,onAddTile:X,onPower:D,onBoot:ke,onBootError:de=>F.setError(String((de==null?void 0:de.message)||de)),onNodePower:We,onNodeRename:lt,onKill:ie,onVisibility:pe,onNew:()=>dt("fleet",!0),onSettings:dt,onOpenVlSession:z,width:he,collapsed:ze,onResize:we,onToggleCollapse:()=>ut(de=>!de)}),l.jsxs("div",{className:"nc-workspace-main",children:[l.jsx(ON,{decks:k,currentDeck:v,onCreate:Xe,onRename:je,onDelete:_t,onReorder:F.reorder,onOpenWindow:Ke,onNavigate:pt,saveState:F.saveState,error:F.error,sidebarVisible:Rt,onToggleSidebar:w?null:()=>_e(de=>!de)}),l.jsx(cN,{layout:V,onLayoutChange:Y,token:t,readonly:be,sessionsAlive:ne,focusSession:te,onFocus:Q,onOpenSingle:L,decks:k,currentDeck:v,onSendToDeck:Sn,cells:E,nodeGroups:O})]}),A&&l.jsx("div",{className:"nc-single-overlay",children:l.jsx(H_,{peer:A,token:t,onBack:()=>z(null)})}),J&&l.jsx("div",{className:"nc-single-overlay",children:l.jsx(V_,{session:J.session,node:J.node,ownerId:J.ownerId,cellName:Ef({session:J.session,node:J.node,ownerId:J.ownerId,cells:E,nodeGroups:O}),token:t,readonly:be,onBack:()=>H(null)})}),I&&l.jsx(Bl,{cell:I,token:t,route:Array.isArray(I.route)?I.route:[],onConfirm:me,onClose:()=>D(null)}),Rn]})}function _R(){En();const e=N.useSyncExternalStore(rR,W_,W_);if(!e.needed)return null;const t=e.kind==="install"?f("install-version-mismatch").replace("{v}",e.version):f("update-available").replace("{v}",e.version).replace(" "," ").trim();return l.jsxs("div",{className:"nc-update",role:"status","aria-live":"polite",children:[l.jsx("span",{className:"nc-update-msg",children:t}),e.kind==="reload"&&l.jsx("button",{className:"nc-update-btn",onClick:yb,children:f("reload")})]})}cR();g0.createRoot(document.getElementById("root")).render(l.jsxs(c0.StrictMode,{children:[l.jsx(vR,{}),l.jsx(_R,{})]}));
@@ -11,7 +11,7 @@
11
11
  <meta name="apple-mobile-web-app-title" content="NexusCrew" />
12
12
  <link rel="manifest" href="/manifest.json" />
13
13
  <title>NexusCrew</title>
14
- <script type="module" crossorigin src="/assets/index-D3OKSnsr.js"></script>
14
+ <script type="module" crossorigin src="/assets/index-_c-1_3iR.js"></script>
15
15
  <link rel="stylesheet" crossorigin href="/assets/index-CYi_lhCg.css">
16
16
  </head>
17
17
  <body>
@@ -1 +1 @@
1
- {"version":"0.8.56"}
1
+ {"version":"0.8.57"}
@@ -112,6 +112,41 @@ const ALIBABA_PI_MODELS = Object.freeze([
112
112
  }),
113
113
  ]);
114
114
 
115
+ // OpenCode Go: un abbonamento unico dietro TRE wire, non un provider uniforme.
116
+ //
117
+ // La documentazione ufficiale assegna a ciascun modello un solo endpoint, ma il
118
+ // gateway traduce: gli elenchi qui sotto sono MISURATI coppia per coppia il
119
+ // 2026-08-11 (25 ID live x 3 wire, piu' una seconda passata sulle celle fallite
120
+ // per distinguere il rifiuto di wire dal payload perso in traduzione).
121
+ //
122
+ // Cosa NON e' in elenco, e perche' non e' una svista:
123
+ // - kimi-*, deepseek-v4-pro, mimo-v2.5*, hy3 fuori da Messages/Responses: il
124
+ // gateway inoltra un payload vuoto e l'upstream risponde "messages must not
125
+ // be empty". E' un difetto loro, reversibile senza preavviso: se un giorno
126
+ // rispondono, l'id si dichiara per quell'engine senza toccare il codice.
127
+ // - mimo-v2-pro e mimo-v2-omni: deprecati dall'upstream ("migrate to
128
+ // xiaomi/mimo-v2.5*"). hy3-preview: "Model is unavailable".
129
+ // Il catalogo live li pubblicizza comunque; qui non entrano.
130
+ // - grok-4.5 solo su Responses: su Chat risponde 503 e Messages lo rifiuta
131
+ // esplicitamente ("not supported for format anthropic").
132
+ const OPENCODE_GO_MESSAGES_MODELS = Object.freeze([
133
+ 'deepseek-v4-flash', 'glm-5.2', 'glm-5.1', 'glm-5',
134
+ 'minimax-m3', 'minimax-m2.7', 'minimax-m2.5',
135
+ 'qwen3.8-max', 'qwen3.7-max', 'qwen3.7-plus', 'qwen3.6-plus', 'qwen3.5-plus',
136
+ ]);
137
+ const OPENCODE_GO_RESPONSES_MODELS = Object.freeze([
138
+ 'deepseek-v4-flash', 'gpt-5.6-luna', 'grok-4.5', 'glm-5.2', 'glm-5.1', 'glm-5',
139
+ ]);
140
+ const OPENCODE_GO_CHAT_MODELS = Object.freeze([
141
+ 'deepseek-v4-flash', 'deepseek-v4-pro', 'glm-5.2', 'glm-5.1', 'glm-5',
142
+ 'kimi-k3', 'kimi-k2.7-code', 'kimi-k2.6', 'kimi-k2.5',
143
+ 'minimax-m3', 'minimax-m2.7', 'minimax-m2.5',
144
+ 'qwen3.8-max', 'qwen3.7-max', 'qwen3.7-plus', 'qwen3.6-plus', 'qwen3.5-plus',
145
+ 'mimo-v2.5', 'mimo-v2.5-pro', 'hy3', 'gpt-5.6-luna',
146
+ ]);
147
+ const OPENCODE_GO_ANTHROPIC_ROOT = 'https://opencode.ai/zen/go';
148
+ const OPENCODE_GO_API_BASE = 'https://opencode.ai/zen/go/v1';
149
+
115
150
  const CUSTOM_KEYS = ['displayName', 'protocol', 'baseUrl', 'envKey', 'providerId'];
116
151
  const MANAGED_KEYS = new Set(['client', 'provider', 'credentialProfile', 'model', 'permissionPolicy', 'credentialSourcePolicy', ...CUSTOM_KEYS]);
117
152
  // Explicit credential source policy. Default 'auto' preserves the legacy
@@ -145,6 +180,11 @@ const CATALOG = Object.freeze([
145
180
  { id: 'claude.alibaba-token-plan', client: 'claude', provider: 'alibaba-token-plan', label: 'Alibaba Token Plan Personal', auth: 'ALIBABA_CODE_API_KEY', endpoint: 'https://token-plan.ap-southeast-1.maas.aliyuncs.com/apps/anthropic', protocol: 'anthropic_messages', model: 'qwen3.8-max', models: ALIBABA_TOKEN_PLAN_MODELS, strictModels: true, core: true, notice: 'alibaba-token-plan' },
146
181
  { id: 'claude.kimi-code', client: 'claude', provider: 'kimi-code', label: 'Kimi Code', auth: 'KIMI_API_KEY', endpoint: 'https://api.kimi.com/coding/', protocol: 'anthropic_messages', model: 'k3[1m]', models: ['k3', 'k3[1m]', 'kimi-for-coding', 'kimi-for-coding-highspeed'], strictModels: true, core: true, notice: 'claude-kimi-code' },
147
182
  { id: 'claude.zai', client: 'claude', provider: 'zai', label: 'Z.AI', auth: 'dynamic', credentialEnv: true, defaultEnvKey: 'ZAI_API_KEY', endpoint: 'https://api.z.ai/api/anthropic', protocol: 'anthropic_messages', model: 'glm-5.2[1m]', models: ['glm-5.2[1m]'], core: true },
183
+ // OpenCode Go su Claude parla Anthropic Messages, e la wire accetta SOLO
184
+ // `x-api-key`: con `Authorization: Bearer` risponde 401 AuthError. Per questo
185
+ // l'endpoint e' la root senza `/v1` (il client aggiunge `/v1/messages`) e il
186
+ // launch valorizza ANTHROPIC_API_KEY, non ANTHROPIC_AUTH_TOKEN come Z.AI.
187
+ { id: 'claude.opencode-go', client: 'claude', provider: 'opencode-go', label: 'OpenCode Go', auth: 'OPENCODE_API_KEY', endpoint: OPENCODE_GO_ANTHROPIC_ROOT, protocol: 'anthropic_messages', model: 'deepseek-v4-flash', models: OPENCODE_GO_MESSAGES_MODELS, strictModels: true, core: true },
148
188
  { id: 'claude.openrouter', client: 'claude', provider: 'openrouter', label: 'OpenRouter', auth: 'OPENROUTER_API_KEY', endpoint: 'https://openrouter.ai/api', protocol: 'anthropic_messages', requiresModel: true, core: true, notice: 'claude-openrouter' },
149
189
  { id: 'claude.ollama-cloud', client: 'claude', provider: 'ollama-cloud', label: 'Ollama Cloud', auth: 'OLLAMA_API_KEY', endpoint: 'https://ollama.com', protocol: 'anthropic_messages', model: 'glm-5.2', models: OLLAMA_CLOUD_MODELS, legacySecrets: true, core: true },
150
190
  { id: 'claude.bedrock', client: 'claude', provider: 'bedrock', label: 'Amazon Bedrock', auth: 'login', endpoint: 'AWS Bedrock', protocol: 'anthropic_messages', core: true, providerEnv: { CLAUDE_CODE_USE_BEDROCK: '1' } },
@@ -158,6 +198,7 @@ const CATALOG = Object.freeze([
158
198
  // apparizione: il seed cambia ordine (non insieme) rispetto a 0.8.55.
159
199
  { id: 'codex-vl.native', client: 'codex-vl', provider: 'native', label: 'OpenAI / ChatGPT account', auth: 'login', endpoint: 'OpenAI account', protocol: 'openai_responses', default: true, core: true },
160
200
  { id: 'codex-vl.alibaba-token-plan', client: 'codex-vl', provider: 'alibaba-token-plan', label: 'Alibaba Token Plan Personal', auth: 'ALIBABA_CODE_API_KEY', endpoint: 'https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1', protocol: 'openai_responses', model: 'qwen3.8-max', models: ALIBABA_CODEX_MODELS, strictModels: true, core: true, notice: 'alibaba-token-plan' },
201
+ { id: 'codex-vl.opencode-go', client: 'codex-vl', provider: 'opencode-go', label: 'OpenCode Go', auth: 'OPENCODE_API_KEY', endpoint: OPENCODE_GO_API_BASE, protocol: 'openai_responses', model: 'deepseek-v4-flash', models: OPENCODE_GO_RESPONSES_MODELS, strictModels: true, core: true },
161
202
  { id: 'codex-vl.openrouter', client: 'codex-vl', provider: 'openrouter', label: 'OpenRouter', auth: 'OPENROUTER_API_KEY', endpoint: 'https://openrouter.ai/api/v1', protocol: 'openai_responses', requiresModel: true, core: true, notice: 'codex-openrouter' },
162
203
  { id: 'codex-vl.ollama-cloud', client: 'codex-vl', provider: 'ollama-cloud', label: 'Ollama Cloud', auth: 'OLLAMA_API_KEY', endpoint: 'https://ollama.com/v1', protocol: 'openai_responses', model: 'glm-5.2', models: OLLAMA_CLOUD_MODELS, legacySecrets: true, core: true },
163
204
  { id: 'codex-vl.openai-api', client: 'codex-vl', provider: 'openai-api', label: 'OpenAI API', auth: 'OPENAI_API_KEY', endpoint: 'https://api.openai.com/v1', protocol: 'openai_responses', core: true },
@@ -197,6 +238,19 @@ const CATALOG = Object.freeze([
197
238
  { id: 'pi.native', client: 'pi', provider: 'native', label: 'Pi configured default', auth: 'login', protocol: 'pi_native', default: true, core: true },
198
239
  { id: 'pi.alibaba-token-plan', client: 'pi', provider: 'alibaba-token-plan', label: 'Alibaba Token Plan Personal', auth: 'ALIBABA_CODE_API_KEY', endpoint: 'https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1', protocol: 'openai-completions', model: 'qwen3.8-max', models: ALIBABA_TOKEN_PLAN_MODELS, strictModels: true, piProvider: 'alibaba-token-plan', piExtension: { baseUrl: 'https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1', models: ALIBABA_PI_MODELS }, delegatePiAuth: false, core: true, notice: 'alibaba-token-plan' },
199
240
  { id: 'pi.zai', client: 'pi', provider: 'zai', label: 'Z.AI', auth: 'ZAI_API_KEY', protocol: 'pi_native', piProvider: 'zai', core: true },
241
+ // Su Pi la wire e' Chat Completions, la piu' ampia delle tre: e' l'unico
242
+ // percorso verso Kimi, DeepSeek Pro, MiMo e Hy3, che da Claude e Codex-VL
243
+ // oggi non sono raggiungibili. Il contextWindow dei modelli non e' misurato:
244
+ // l'estensione generata usa il default conservativo finche' non esiste lo
245
+ // snapshot models.dev.
246
+ //
247
+ // `delegatePiAuth: false` come per alibaba-token-plan, e per la stessa
248
+ // ragione: la delega vale per i provider che Pi conosce nativamente e
249
+ // risolve dal proprio store di login. OpenCode Go non e' fra quelli — esiste
250
+ // solo come estensione generata il cui apiKey e' `$OPENCODE_API_KEY`, che
251
+ // senza NexusCrew non e' valorizzato. Delegando, la cella risulterebbe
252
+ // configurata senza chiave e fallirebbe al primo uso.
253
+ { id: 'pi.opencode-go', client: 'pi', provider: 'opencode-go', label: 'OpenCode Go', auth: 'OPENCODE_API_KEY', endpoint: OPENCODE_GO_API_BASE, protocol: 'openai-completions', model: 'deepseek-v4-flash', models: OPENCODE_GO_CHAT_MODELS, strictModels: true, piProvider: 'opencode-go', piExtension: { baseUrl: OPENCODE_GO_API_BASE }, delegatePiAuth: false, core: true },
200
254
  { id: 'pi.anthropic', client: 'pi', provider: 'anthropic', label: 'Anthropic', auth: 'ANTHROPIC_API_KEY', protocol: 'pi_native', piProvider: 'anthropic', core: true },
201
255
  { id: 'pi.openai', client: 'pi', provider: 'openai', label: 'OpenAI API', auth: 'OPENAI_API_KEY', protocol: 'pi_native', piProvider: 'openai', core: true },
202
256
  { id: 'pi.openai-codex', client: 'pi', provider: 'openai-codex', label: 'OpenAI Codex OAuth', auth: 'login', protocol: 'pi_native', piProvider: 'openai-codex', core: true },
@@ -1101,6 +1155,26 @@ function resolveManagedEngine(engine, cell, cfg = {}) {
1101
1155
  env.CLAUDE_CODE_EFFORT_LEVEL = 'max';
1102
1156
  env.CLAUDE_CODE_ALWAYS_ENABLE_EFFORT = '1';
1103
1157
  }
1158
+ } else if (spec.provider === 'opencode-go') {
1159
+ // Misurato il 2026-08-11: `POST /v1/messages` con `Authorization: Bearer`
1160
+ // risponde `401 AuthError: Missing API key`, con `x-api-key` risponde 200.
1161
+ // ANTHROPIC_API_KEY e' cio' che Claude Code manda come `x-api-key`, quindi
1162
+ // qui NON si usa la forma a token degli altri gateway.
1163
+ //
1164
+ // Nessun CLAUDE_CODE_MAX_CONTEXT_TOKENS: il context window reale di questi
1165
+ // modelli su OpenCode Go non e' misurato, e un numero inventato qui
1166
+ // diventerebbe la configurazione con cui le celle compattano.
1167
+ Object.assign(env, {
1168
+ ANTHROPIC_BASE_URL: profile.endpoint,
1169
+ ANTHROPIC_API_KEY: cred.value,
1170
+ ANTHROPIC_MODEL: model,
1171
+ ANTHROPIC_DEFAULT_FABLE_MODEL: model,
1172
+ ANTHROPIC_DEFAULT_OPUS_MODEL: model,
1173
+ ANTHROPIC_DEFAULT_SONNET_MODEL: model,
1174
+ ANTHROPIC_DEFAULT_HAIKU_MODEL: model,
1175
+ CLAUDE_CODE_SUBAGENT_MODEL: model,
1176
+ API_TIMEOUT_MS: '3000000',
1177
+ });
1104
1178
  } else if (spec.provider === 'alibaba-token-plan') {
1105
1179
  privateProfile = true;
1106
1180
  const qwen38 = model === 'qwen3.8-max';
@@ -1180,6 +1254,14 @@ function resolveManagedEngine(engine, cell, cfg = {}) {
1180
1254
  args.push('-c', `model_catalog_json=${JSON.stringify(localCatalog)}`);
1181
1255
  args.push('-c', `model_context_window=${ALIBABA_TOKEN_PLAN_CONTEXT}`);
1182
1256
  }
1257
+ } else if (spec.provider === 'opencode-go') {
1258
+ // Wire Responses nativa: il gateway espone `/v1/responses` e Codex-VL vi
1259
+ // aggiunge il path, quindi qui l'endpoint include gia' `/v1`. Nessun
1260
+ // model_context_window: non e' misurato, e il default del client e' piu'
1261
+ // onesto di una costante inventata.
1262
+ env.OPENCODE_API_KEY = cred.value;
1263
+ args.push(...codexProviderArgs('opencode_go', 'OpenCode Go', profile.endpoint, 'OPENCODE_API_KEY'));
1264
+ args.push('-c', 'model_providers.opencode_go.stream_idle_timeout_ms=600000');
1183
1265
  } else if (spec.provider === 'custom') {
1184
1266
  env[spec.envKey] = cred.value;
1185
1267
  args.push(...codexProviderArgs(spec.providerId, spec.displayName, spec.baseUrl, spec.envKey));
@@ -1273,6 +1355,8 @@ module.exports = {
1273
1355
  knownMcpServerNames,
1274
1356
  CATALOG, OLLAMA_CLOUD_MODELS, OLLAMA_CONTEXT, ALIBABA_TOKEN_PLAN_MODELS,
1275
1357
  ALIBABA_CODEX_MODELS, ALIBABA_TOKEN_PLAN_CONTEXT, ALIBABA_PI_MODELS,
1358
+ OPENCODE_GO_MESSAGES_MODELS, OPENCODE_GO_RESPONSES_MODELS, OPENCODE_GO_CHAT_MODELS,
1359
+ OPENCODE_GO_ANTHROPIC_ROOT, OPENCODE_GO_API_BASE,
1276
1360
  CLIENT_LABELS, normalizeManagedSpec, profileFor,
1277
1361
  defaultDefinitions, defaultShellEngine, defaultAgyEngine, defaultKimiEngine, defaultGrokEngine, defaultVlEngine, describeManaged, describeCatalogCredential, discoverOllamaModels, resolveManagedEngine, needsExplicitNode,
1278
1362
  discoverPiModels, EXTERNAL_DISCOVERY_TIMEOUT_MS, parseEnvFile, parseProviderShellFile, findBinary, publicCatalog, writePiProviderExtension,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmmbuto/nexuscrew",
3
- "version": "0.8.56",
3
+ "version": "0.8.57",
4
4
  "description": "Faithful browser tmux client — attach to live sessions over a real PTY, localhost-only, mobile-easy",
5
5
  "main": "lib/server.js",
6
6
  "bin": {