agent-nuvira 3.5.7 → 3.5.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/dist/agents/agents/package-agent.d.ts +22 -0
  2. package/dist/agents/agents/package-agent.d.ts.map +1 -1
  3. package/dist/agents/agents/package-agent.js +92 -4
  4. package/dist/agents/agents/package-agent.js.map +1 -1
  5. package/dist/agents/release-preflight.d.ts +42 -5
  6. package/dist/agents/release-preflight.d.ts.map +1 -1
  7. package/dist/agents/release-preflight.js +82 -5
  8. package/dist/agents/release-preflight.js.map +1 -1
  9. package/dist/cli/chat.d.ts.map +1 -1
  10. package/dist/cli/chat.js +99 -9
  11. package/dist/cli/chat.js.map +1 -1
  12. package/dist/cli/code-map.d.ts +51 -0
  13. package/dist/cli/code-map.d.ts.map +1 -1
  14. package/dist/cli/code-map.js +174 -2
  15. package/dist/cli/code-map.js.map +1 -1
  16. package/dist/cli/credentials.d.ts.map +1 -1
  17. package/dist/cli/credentials.js +4 -1
  18. package/dist/cli/credentials.js.map +1 -1
  19. package/dist/cli/execute.js +5 -5
  20. package/dist/cli/execute.js.map +1 -1
  21. package/dist/cli/loop-executor.d.ts.map +1 -1
  22. package/dist/cli/loop-executor.js +76 -13
  23. package/dist/cli/loop-executor.js.map +1 -1
  24. package/dist/config/process-env.d.ts.map +1 -1
  25. package/dist/config/process-env.js +2 -2
  26. package/dist/config/process-env.js.map +1 -1
  27. package/dist/editing/types.d.ts +23 -1
  28. package/dist/editing/types.d.ts.map +1 -1
  29. package/dist/editing/types.js +51 -7
  30. package/dist/editing/types.js.map +1 -1
  31. package/dist/inference/route-resolver.d.ts +39 -0
  32. package/dist/inference/route-resolver.d.ts.map +1 -1
  33. package/dist/inference/route-resolver.js +51 -2
  34. package/dist/inference/route-resolver.js.map +1 -1
  35. package/dist/inference/thinking-replay.d.ts +86 -0
  36. package/dist/inference/thinking-replay.d.ts.map +1 -0
  37. package/dist/inference/thinking-replay.js +110 -0
  38. package/dist/inference/thinking-replay.js.map +1 -0
  39. package/dist/inference/tools.d.ts +9 -0
  40. package/dist/inference/tools.d.ts.map +1 -1
  41. package/dist/inference/tools.js +12 -1
  42. package/dist/inference/tools.js.map +1 -1
  43. package/dist/learning/assessment-protocol.d.ts +120 -0
  44. package/dist/learning/assessment-protocol.d.ts.map +1 -0
  45. package/dist/learning/assessment-protocol.js +236 -0
  46. package/dist/learning/assessment-protocol.js.map +1 -0
  47. package/dist/learning/assessment-turn-context.d.ts +54 -0
  48. package/dist/learning/assessment-turn-context.d.ts.map +1 -0
  49. package/dist/learning/assessment-turn-context.js +71 -0
  50. package/dist/learning/assessment-turn-context.js.map +1 -0
  51. package/dist/learning/exhaustion-report.d.ts +24 -1
  52. package/dist/learning/exhaustion-report.d.ts.map +1 -1
  53. package/dist/learning/exhaustion-report.js +18 -6
  54. package/dist/learning/exhaustion-report.js.map +1 -1
  55. package/dist/learning/perf-probe.d.ts +140 -0
  56. package/dist/learning/perf-probe.d.ts.map +1 -0
  57. package/dist/learning/perf-probe.js +316 -0
  58. package/dist/learning/perf-probe.js.map +1 -0
  59. package/dist/learning/self-check-discovery.d.ts +117 -0
  60. package/dist/learning/self-check-discovery.d.ts.map +1 -0
  61. package/dist/learning/self-check-discovery.js +334 -0
  62. package/dist/learning/self-check-discovery.js.map +1 -0
  63. package/dist/tools/child-agent-runtime.js +19 -1
  64. package/dist/tools/child-agent-runtime.js.map +1 -1
  65. package/dist/tools/credentials-tool.d.ts.map +1 -1
  66. package/dist/tools/credentials-tool.js +4 -1
  67. package/dist/tools/credentials-tool.js.map +1 -1
  68. package/dist/tools/loop-project-context.d.ts +7 -0
  69. package/dist/tools/loop-project-context.d.ts.map +1 -1
  70. package/dist/tools/loop-project-context.js +44 -0
  71. package/dist/tools/loop-project-context.js.map +1 -1
  72. package/dist/tools/pipeline-tool.d.ts.map +1 -1
  73. package/dist/tools/pipeline-tool.js +19 -1
  74. package/dist/tools/pipeline-tool.js.map +1 -1
  75. package/dist/tools/plan-store.d.ts +90 -6
  76. package/dist/tools/plan-store.d.ts.map +1 -1
  77. package/dist/tools/plan-store.js +140 -13
  78. package/dist/tools/plan-store.js.map +1 -1
  79. package/dist/tools/publish-tool.d.ts.map +1 -1
  80. package/dist/tools/publish-tool.js +9 -0
  81. package/dist/tools/publish-tool.js.map +1 -1
  82. package/dist/tools/registry.d.ts.map +1 -1
  83. package/dist/tools/registry.js +25 -3
  84. package/dist/tools/registry.js.map +1 -1
  85. package/dist/tools/tool-loop.d.ts +17 -0
  86. package/dist/tools/tool-loop.d.ts.map +1 -1
  87. package/dist/tools/tool-loop.js +4 -1
  88. package/dist/tools/tool-loop.js.map +1 -1
  89. package/dist/web-dashboard/chat-console.d.ts.map +1 -1
  90. package/dist/web-dashboard/chat-console.js +11 -1
  91. package/dist/web-dashboard/chat-console.js.map +1 -1
  92. package/dist/web-dashboard/project-context.js +6 -0
  93. package/dist/web-dashboard/project-context.js.map +1 -1
  94. package/dist/web-dashboard/server.d.ts.map +1 -1
  95. package/dist/web-dashboard/server.js +25 -3
  96. package/dist/web-dashboard/server.js.map +1 -1
  97. package/package.json +1 -1
  98. package/src/web-dashboard/public/assets/{index-V0rIqVbg.js → index-CGYIlLpO.js} +3 -3
  99. package/src/web-dashboard/public/assets/index-CGYIlLpO.js.map +1 -0
  100. package/src/web-dashboard/public/index.html +1 -1
  101. package/src/web-dashboard/public/assets/index-V0rIqVbg.js.map +0 -1
@@ -64,7 +64,7 @@ Error generating stack: `+s.message+`
64
64
  * LICENSE.md file in the root directory of this source tree.
65
65
  *
66
66
  * @license MIT
67
- */function lh(){return lh=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},lh.apply(null,arguments)}function RT(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function q2(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function K2(e,t){return e.button===0&&(!t||t==="_self")&&!q2(e)}const V2=["onClick","relative","reloadDocument","replace","state","target","to","preventScrollReset","viewTransition"],Y2=["aria-current","caseSensitive","className","end","style","to","viewTransition","children"],X2="6";try{window.__reactRouterVersion=X2}catch{}const Q2=b.createContext({isTransitioning:!1}),Z2="startTransition",sS=H$[Z2];function J2(e){let{basename:t,children:n,future:r,window:a}=e,s=b.useRef();s.current==null&&(s.current=n2({window:a,v5Compat:!0}));let o=s.current,[l,c]=b.useState({action:o.action,location:o.location}),{v7_startTransition:u}=r||{},d=b.useCallback(f=>{u&&sS?sS(()=>c(f)):c(f)},[c,u]);return b.useLayoutEffect(()=>o.listen(d),[o,d]),b.useEffect(()=>W2(r),[r]),b.createElement(H2,{basename:t,children:n,location:l.location,navigationType:l.action,navigator:o,future:r})}const eB=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u",tB=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,Jt=b.forwardRef(function(t,n){let{onClick:r,relative:a,reloadDocument:s,replace:o,state:l,target:c,to:u,preventScrollReset:d,viewTransition:f}=t,h=RT(t,V2),{basename:p}=b.useContext(qa),m,g=!1;if(typeof u=="string"&&tB.test(u)&&(m=u,eB))try{let w=new URL(window.location.href),j=u.startsWith("//")?new URL(w.protocol+u):new URL(u),S=Qo(j.pathname,p);j.origin===w.origin&&S!=null?u=S+j.search+j.hash:g=!0}catch{}let y=C2(u,{relative:a}),v=rB(u,{replace:o,state:l,target:c,preventScrollReset:d,relative:a,viewTransition:f});function k(w){r&&r(w),w.defaultPrevented||v(w)}return b.createElement("a",lh({},h,{href:m||y,onClick:g||s?r:k,ref:n,target:c}))}),oS=b.forwardRef(function(t,n){let{"aria-current":r="page",caseSensitive:a=!1,className:s="",end:o=!1,style:l,to:c,viewTransition:u,children:d}=t,f=RT(t,Y2),h=Dp(c,{relative:f.relative}),p=Li(),m=b.useContext(_T),{navigator:g,basename:y}=b.useContext(qa),v=m!=null&&aB(h)&&u===!0,k=g.encodeLocation?g.encodeLocation(h).pathname:h.pathname,w=p.pathname,j=m&&m.navigation&&m.navigation.location?m.navigation.location.pathname:null;a||(w=w.toLowerCase(),j=j?j.toLowerCase():null,k=k.toLowerCase()),j&&y&&(j=Qo(j,y)||j);const S=k!=="/"&&k.endsWith("/")?k.length-1:k.length;let x=w===k||!o&&w.startsWith(k)&&w.charAt(S)==="/",N=j!=null&&(j===k||!o&&j.startsWith(k)&&j.charAt(k.length)==="/"),E={isActive:x,isPending:N,isTransitioning:v},P=x?r:void 0,_;typeof s=="function"?_=s(E):_=[s,x?"active":null,N?"pending":null,v?"transitioning":null].filter(Boolean).join(" ");let R=typeof l=="function"?l(E):l;return b.createElement(Jt,lh({},f,{"aria-current":P,className:_,ref:n,style:R,to:c,viewTransition:u}),typeof d=="function"?d(E):d)});var gy;(function(e){e.UseScrollRestoration="useScrollRestoration",e.UseSubmit="useSubmit",e.UseSubmitFetcher="useSubmitFetcher",e.UseFetcher="useFetcher",e.useViewTransitionState="useViewTransitionState"})(gy||(gy={}));var lS;(function(e){e.UseFetcher="useFetcher",e.UseFetchers="useFetchers",e.UseScrollRestoration="useScrollRestoration"})(lS||(lS={}));function nB(e){let t=b.useContext($p);return t||_t(!1),t}function rB(e,t){let{target:n,replace:r,state:a,preventScrollReset:s,relative:o,viewTransition:l}=t===void 0?{}:t,c=rw(),u=Li(),d=Dp(e,{relative:o});return b.useCallback(f=>{if(K2(f,n)){f.preventDefault();let h=r!==void 0?r:oh(u)===oh(d);c(e,{replace:h,state:a,preventScrollReset:s,relative:o,viewTransition:l})}},[u,c,d,r,a,n,e,s,o,l])}function aB(e,t){t===void 0&&(t={});let n=b.useContext(Q2);n==null&&_t(!1);let{basename:r}=nB(gy.useViewTransitionState),a=Dp(e,{relative:t.relative});if(!n.isTransitioning)return!1;let s=Qo(n.currentLocation.pathname,r)||n.currentLocation.pathname,o=Qo(n.nextLocation.pathname,r)||n.nextLocation.pathname;return py(a.pathname,o)!=null||py(a.pathname,s)!=null}async function it(e){if(!e.ok)return null;const t=e.headers.get("content-type")||"";if(!t.includes("application/json")&&!t.includes("text/json"))return t.includes("text/html")&&console.warn(`[dashboard] GET ${e.url||"/api/*"} returned HTML (${e.status}) instead of JSON — the dashboard server may be an older version. Stop it and start it again (agent-nuvira dashboard stop, or Ctrl+C in its terminal).`),null;try{return await e.json()}catch{return null}}const Ao="buff-dashboard-admin-token";function MT(){try{if(typeof window<"u"&&window.localStorage)return window.localStorage}catch{}return null}function iB(e){if(!e||typeof e!="object")return!1;const t=e,n=t.diff;return typeof t.dir=="string"&&typeof t.base=="string"&&typeof t.removed=="boolean"&&!!n&&typeof n=="object"&&Array.isArray(n.files)&&n.files.every(r=>typeof r=="string")&&typeof n.summary=="string"&&!!n.payload&&typeof n.payload=="object"&&typeof n.payload.summary=="string"&&Array.isArray(n.payload.files)&&n.payload.files.every(r=>!!r&&typeof r.path=="string"&&typeof r.body=="string")}function sB(e){if(!e||typeof e!="object")return!1;const t=e;return typeof t.id=="string"&&typeof t.replayed=="number"&&typeof t.modelCalls=="number"&&typeof t.saved=="boolean"&&typeof t.notice=="string"&&(t.callsAvoided===void 0||typeof t.callsAvoided=="number")}function oB(e){if(!e||typeof e!="object")return!1;const t=e;return typeof t.goal=="string"&&typeof t.planned=="boolean"&&Array.isArray(t.steps)&&!!t.stepCounts&&typeof t.stepCounts=="object"&&typeof t.stepCounts.total=="number"&&typeof t.verification=="string"&&["verified","unverified","blocked","not-applicable","delivered-and-read-back"].includes(t.verification)&&(t.summary===null||typeof t.summary=="string")&&Array.isArray(t.changedPaths)&&!!t.flags&&typeof t.flags=="object"}const vy=new Map;function lB(){const e=MT();if(e)try{const t=e.getItem(Ao);if(t)return t}catch{}return vy.get(Ao)??null}function cB(e){const t=MT();if(t)try{e?t.setItem(Ao,e):t.removeItem(Ao);return}catch{}e?vy.set(Ao,e):vy.delete(Ao)}function Xt(){return lB()}let yy=0;const by=new Set;function uB(){return yy}function dB(e){return by.add(e),()=>{by.delete(e)}}function fB(){yy+=1;for(const e of by)try{e(yy)}catch{}}function dg(e){cB(e),fB()}function mt(){const e=Xt();return e?{Authorization:`Bearer ${e}`}:{}}class hB{constructor(t=""){ea(this,"sse",null);ea(this,"listeners",new Set);ea(this,"connectionListeners",new Set);ea(this,"dagListeners",new Set);ea(this,"typingListeners",new Set);ea(this,"chatRetryListeners",new Set);ea(this,"reconnectTimer",null);ea(this,"baseUrl");ea(this,"lastData",null);this.baseUrl=t}subscribe(t){return this.listeners.add(t),()=>this.listeners.delete(t)}onConnectionChange(t){return this.connectionListeners.add(t),()=>this.connectionListeners.delete(t)}onDAGEvent(t){return this.dagListeners.add(t),()=>this.dagListeners.delete(t)}onTypingEvent(t){return this.typingListeners.add(t),()=>this.typingListeners.delete(t)}onChatRetryEvent(t){return this.chatRetryListeners.add(t),()=>this.chatRetryListeners.delete(t)}connect(){this.sse||(this.sse=new EventSource(`${this.baseUrl}/api/sse`),this.sse.addEventListener("init",t=>{try{const n=JSON.parse(t.data);this.lastData=n,this.notify(n),this.notifyConnection(!0)}catch(n){console.error("Failed to parse SSE init data:",n)}}),this.sse.addEventListener("refresh",t=>{try{const n=JSON.parse(t.data);this.lastData=n,this.notify(n),this.notifyConnection(!0)}catch(n){console.error("Failed to parse SSE refresh data:",n)}}),this.sse.addEventListener("dag",t=>{try{const n=JSON.parse(t.data);if(this.notifyDAG(n),this.lastData){const r={...this.lastData,dag:n};this.lastData=r,this.notify(r)}}catch(n){console.error("Failed to parse SSE dag event:",n)}}),this.sse.addEventListener("quota",t=>{try{const n=JSON.parse(t.data);if(this.lastData&&n.quota){const r={...this.lastData,routing:{...this.lastData.routing||{},quota:n.quota},serverTime:n.serverTime||this.lastData.serverTime};this.lastData=r,this.notify(r)}}catch(n){console.error("Failed to parse SSE quota event:",n)}}),this.sse.addEventListener("conversation",t=>{try{const n=JSON.parse(t.data);if(this.lastData&&n.conversations){const r={...this.lastData,conversations:{total:n.total??n.conversations.length,recent:n.conversations},serverTime:n.serverTime||this.lastData.serverTime};this.lastData=r,this.notify(r)}}catch(n){console.error("Failed to parse SSE conversation event:",n)}}),this.sse.addEventListener("typing",t=>{try{const n=JSON.parse(t.data);for(const r of this.typingListeners)try{r(n)}catch{}}catch(n){console.error("Failed to parse SSE typing event:",n)}}),this.sse.addEventListener("chat-retry",t=>{try{const n=JSON.parse(t.data);if(!n||typeof n.sessionId!="string"||typeof n.content!="string")return;for(const r of this.chatRetryListeners)try{r(n)}catch{}}catch(n){console.error("Failed to parse SSE chat-retry event:",n)}}),this.sse.onerror=()=>{this.notifyConnection(!1),this.disconnect(),this.reconnect()},this.sse.onopen=()=>{this.notifyConnection(!0)})}disconnect(){this.sse&&(this.sse.close(),this.sse=null),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null)}reconnect(){this.reconnectTimer=setTimeout(()=>{this.connect()},3e3)}notify(t){this.listeners.forEach(n=>n(t))}notifyDAG(t){this.dagListeners.forEach(n=>n(t))}notifyConnection(t){this.connectionListeners.forEach(n=>n(t))}async fetchAll(){try{const t=await fetch(`${this.baseUrl}/api/all`),n=await it(t);return n?(this.lastData=n,n):null}catch{return null}}async fetchExecutionAudit(t){try{const n=new URLSearchParams;t!=null&&t.skillName&&n.set("skillName",t.skillName),t!=null&&t.status&&n.set("status",t.status),t!=null&&t.limit&&n.set("limit",String(t.limit));const r=n.toString(),a=await fetch(`${this.baseUrl}/api/executions${r?`?${r}`:""}`,{signal:AbortSignal.timeout(8e3)}),s=await it(a);return(s==null?void 0:s.entries)??[]}catch{return[]}}async fetchTraces(){try{const t=await fetch(`${this.baseUrl}/api/traces`,{signal:AbortSignal.timeout(8e3)}),n=await it(t);return n!=null&&n.traces?n.traces:null}catch{return null}}async fetchAcceptance(){try{const t=await fetch(`${this.baseUrl}/api/acceptance`,{signal:AbortSignal.timeout(8e3)}),n=await it(t);return!n||typeof n.labelled!="number"?null:n}catch{return null}}acceptanceExportUrl(t="json"){return`${this.baseUrl}/api/acceptance/export?format=${t}`}async importAcceptance(t,n){try{const r=await fetch(`${this.baseUrl}/api/acceptance/import`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({text:t,...n?{format:n}:{}})}),a=await it(r);return!a||typeof a.ok!="boolean"?null:a}catch{return null}}async fetchDecisions(t,n){try{const r=new URLSearchParams;t&&r.set("dir",t),n&&n.trim()&&r.set("for",n.trim());const a=await fetch(`${this.baseUrl}/api/decisions?${r.toString()}`,{signal:AbortSignal.timeout(8e3)}),s=await it(a);return!s||!Array.isArray(s.decisions)?null:s}catch{return null}}async reviseDecision(t,n,r,a){try{const s=await fetch(`${this.baseUrl}/api/decisions/revise`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({dir:t,id:n,answer:r,...a?{note:a}:{}})}),o=await it(s);return!o||o.ok!==!0||!o.decision?null:o.decision}catch{return null}}async fetchGates(){try{const t=await fetch(`${this.baseUrl}/api/gates`,{signal:AbortSignal.timeout(8e3)}),n=await it(t);return!n||typeof n.events!="number"?null:n}catch{return null}}async fetchConsent(){try{const t=await fetch(`${this.baseUrl}/api/consent`,{signal:AbortSignal.timeout(8e3)}),n=await it(t);return!n||n.ok!==!0||!n.picture||!n.picture.denied?null:n.picture}catch{return null}}async fetchCapabilities(){try{const t=await fetch(`${this.baseUrl}/api/capabilities`,{signal:AbortSignal.timeout(8e3)}),n=await it(t);return!n||n.ok!==!0||!Array.isArray(n.verbs)?null:n}catch{return null}}async saveLearnedCommand(t,n,r){try{const a=await fetch(`${this.baseUrl}/api/capabilities/commands`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({verb:t,command:n,...r?{note:r}:{}})}),s=await it(a);return{ok:(s==null?void 0:s.ok)===!0,commands:s==null?void 0:s.commands,error:s==null?void 0:s.error}}catch{return{ok:!1,error:"Could not reach the server."}}}async forgetLearnedCommand(t){try{const n=await fetch(`${this.baseUrl}/api/capabilities/commands/forget`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({verb:t})}),r=await it(n);return{ok:(r==null?void 0:r.ok)===!0,commands:r==null?void 0:r.commands,error:r==null?void 0:r.error}}catch{return{ok:!1,error:"Could not reach the server."}}}async fetchSessionGrants(){try{const t=await fetch(`${this.baseUrl}/api/session-grants`,{signal:AbortSignal.timeout(8e3)}),n=await it(t);return!n||!Array.isArray(n.grants)?null:n.grants}catch{return null}}async revokeSessionGrant(t){try{const n=await fetch(`${this.baseUrl}/api/session-grants/clear`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sessionId:t})}),r=await it(n);return(r==null?void 0:r.ok)===!0}catch{return!1}}async fetchAdminChecks(){try{const t=await fetch(`${this.baseUrl}/api/admin/checks`,{signal:AbortSignal.timeout(15e3)}),n=await it(t);return!n||!Array.isArray(n.system)||!Array.isArray(n.enterprise)||!Array.isArray(n.providers)?null:n}catch{return null}}async fetchHub(){var t;try{const n=await fetch(`${this.baseUrl}/api/hub`,{signal:AbortSignal.timeout(8e3)}),r=await it(n);return!r||!Array.isArray((t=r.toolsets)==null?void 0:t.toolsets)?null:r}catch{return null}}async rateTrace(t,n){try{const r=await fetch(`${this.baseUrl}/api/traces/${encodeURIComponent(t)}/verdict`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({verdict:n}),signal:AbortSignal.timeout(8e3)}),a=await it(r);return a!=null&&a.ok&&a.rated?{traceId:a.rated.traceId,corpusLabeled:!!a.rated.corpusLabeled}:null}catch{return null}}async fetchTraceDetail(t){try{const n=await fetch(`${this.baseUrl}/api/traces/${encodeURIComponent(t)}`,{signal:AbortSignal.timeout(8e3)}),r=await it(n);return r&&Array.isArray(r.steps)?r:null}catch{return null}}async sendAdminRequest(t,n,r){try{const a=Xt(),s=await fetch(`${this.baseUrl}${t}`,{method:n,headers:{"Content-Type":"application/json",...a?{Authorization:`Bearer ${a}`}:{}},body:r!==void 0?JSON.stringify(r):void 0,signal:AbortSignal.timeout(15e3)}),o=s.headers.get("content-type")||"";let l=null;if(o.includes("application/json")||o.includes("text/json"))try{l=await s.json()}catch{l=null}return{status:s.status,data:l}}catch{return null}}async fetchAdminAuthStatus(){const t=await this.sendAdminRequest("/api/admin/auth-status","GET");if(!t||typeof t.data!="object"||t.data===null)return null;const n=t.data;return typeof n.configured!="boolean"||typeof n.authenticated!="boolean"?null:{configured:n.configured,authenticated:n.authenticated,user:typeof n.user=="string"?n.user:null,role:typeof n.role=="string"?n.role:null,mustChangePassword:n.mustChangePassword===!0}}async changeAdminPassword(t,n){const r=await this.sendAdminRequest("/api/admin/change-password","POST",{currentPassword:t,newPassword:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&a.ok?{ok:!0}:{ok:!1,error:a.error||"Could not change the password."}}async fetchAdminUsers(){const t=await this.sendAdminRequest("/api/admin/users","GET");if(!t)return{ok:!1,error:"Could not reach the dashboard server."};const n=t.data??{};return t.status===200&&n.ok&&Array.isArray(n.users)?n:{ok:!1,error:n.error||"Failed to load users.",forbidden:t.status===403,unauthorized:t.status===401}}async addAdminUser(t,n,r){const a=await this.sendAdminRequest("/api/admin/users","POST",{user:t,password:n,role:r});if(!a)return{ok:!1,error:"Could not reach the dashboard server."};const s=a.data??{};return a.status===200&&s.ok?s:{ok:!1,error:s.error||"Failed to add user.",forbidden:a.status===403,unauthorized:a.status===401}}async removeAdminUser(t){const n=await this.sendAdminRequest(`/api/admin/users/${encodeURIComponent(t)}`,"DELETE");if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?r:{ok:!1,error:r.error||"Failed to remove user.",forbidden:n.status===403,unauthorized:n.status===401}}async fetchAdminCatalog(){const t=await this.sendAdminRequest("/api/admin/catalog","GET"),n=t==null?void 0:t.data;return!n||!Array.isArray(n.providers)?null:n.providers}async adminSetup(t,n){const r=await this.sendAdminRequest("/api/admin/setup","POST",{user:t,password:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&typeof a.token=="string"?(dg(a.token),{ok:!0,user:a.user,token:a.token}):{ok:!1,error:a.error||"Setup failed.",unauthorized:r.status===401}}async adminLogin(t,n){const r=await this.sendAdminRequest("/api/admin/login","POST",{user:t,password:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&typeof a.token=="string"?(dg(a.token),{ok:!0,user:a.user,token:a.token}):{ok:!1,error:a.error||"Login failed.",unauthorized:r.status===401}}async adminLogout(){await this.sendAdminRequest("/api/admin/logout","POST"),dg(null)}async shutdown(t){const n=await this.sendAdminRequest("/api/admin/shutdown","POST",{target:t});if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?r:{ok:!1,error:r.error||"Shutdown failed.",unauthorized:n.status===401,forbidden:n.status===403}}async saveProvider(t,n){const r=await this.sendAdminRequest(`/api/admin/providers/${encodeURIComponent(t)}`,"PUT",n);if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&a.ok?a:{ok:!1,error:a.error||"Save failed.",unauthorized:r.status===401}}async deleteProvider(t){const n=await this.sendAdminRequest(`/api/admin/providers/${encodeURIComponent(t)}`,"DELETE");if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?r:{ok:!1,error:r.error||"Remove failed.",unauthorized:n.status===401}}async testProvider(t){const n=await this.sendAdminRequest(`/api/admin/providers/${encodeURIComponent(t)}/test`,"POST");if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200?r:{ok:!1,error:r.error||"Test failed.",unauthorized:n.status===401}}async fetchOmniRouteStatus(){const t=await this.sendAdminRequest("/api/admin/omniroute","GET");if(!t)return null;const n=t.data??{};return t.status!==200||!n.status?null:n.status}async controlOmniRoute(t){const n=await this.sendAdminRequest("/api/admin/omniroute","POST",{action:t});if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200?r:{ok:!1,error:r.error||"OmniRoute control failed.",unauthorized:n.status===401,forbidden:n.status===403}}async fetchAdminWorkspace(){const t=await this.sendAdminRequest("/api/admin/workspace","GET");if(!t)return null;const n=t.data??{};return t.status!==200||n.ok!==!0?null:{configured:typeof n.configured=="string"?n.configured:null,effective:typeof n.effective=="string"?n.effective:null,processCwd:typeof n.processCwd=="string"?n.processCwd:"",configuredValid:n.configuredValid===!0}}async saveAdminWorkspace(t){const n=await this.sendAdminRequest("/api/admin/workspace","PUT",{cwd:t});if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok===!0?{ok:!0,workspace:{configured:typeof r.configured=="string"?r.configured:null,effective:typeof r.effective=="string"?r.effective:null,processCwd:typeof r.processCwd=="string"?r.processCwd:"",configuredValid:r.configuredValid===!0}}:{ok:!1,error:r.error||"Save failed.",unauthorized:n.status===401,forbidden:n.status===403}}async fetchAdminCache(){const t=await this.sendAdminRequest("/api/admin/cache","GET");if(!t)return null;const n=t.data;return!n||n.ok!==!0||!Array.isArray(n.workspaces)?null:n}async clearAdminCache(t){const n=await this.sendAdminRequest("/api/admin/cache/clear","POST",{scope:t});if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?{ok:!0,removed:r.removed??0}:{ok:!1,error:r.error||"Could not clear the cache.",unauthorized:n.status===401,forbidden:n.status===403}}async fetchAdminServices(){const t=await this.sendAdminRequest("/api/admin/services","GET");if(!t)return null;const n=t.data;return!n||n.ok!==!0||!Array.isArray(n.services)?null:n}async saveService(t,n){const r=await this.sendAdminRequest(`/api/admin/services/${encodeURIComponent(t)}`,"PUT",{values:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&a.ok?a:{ok:!1,error:a.error||"Save failed.",unauthorized:r.status===401,forbidden:r.status===403}}async testService(t){const n=await this.sendAdminRequest(`/api/admin/services/${encodeURIComponent(t)}/test`,"POST");if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200?r:{ok:!1,error:r.error||"Test failed."}}async removeService(t){const n=await this.sendAdminRequest(`/api/admin/services/${encodeURIComponent(t)}`,"DELETE");if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?r:{ok:!1,error:r.error||"Remove failed.",unauthorized:n.status===401,forbidden:n.status===403}}async fetchAdminQuota(){const t=await this.sendAdminRequest("/api/admin/quota","GET");if(!t)return null;const n=t.data;return!n||!n.ok||typeof n.quota!="object"?null:n}async setToolsetEnabled(t,n){const r=await this.sendAdminRequest(`/api/admin/hub/toolsets/${encodeURIComponent(t)}`,"PUT",{enabled:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&a.ok?a:{ok:!1,error:a.error||"Toggle failed.",unauthorized:r.status===401,forbidden:r.status===403}}async setSkillEnabled(t,n){const r=await this.sendAdminRequest(`/api/admin/hub/skills/${encodeURIComponent(t)}`,"PUT",{enabled:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&a.ok?a:{ok:!1,error:a.error||"Toggle failed.",unauthorized:r.status===401,forbidden:r.status===403}}async fetchKnowledge(){try{const n=await(await fetch(`${this.baseUrl}/api/knowledge`,{headers:mt(),signal:AbortSignal.timeout(8e3)})).json();return Array.isArray(n.tags)?n.tags:null}catch{return null}}async knowledgeIngest(t,n){try{const r=await fetch(`${this.baseUrl}/api/knowledge/ingest`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({tag:t,paths:n})}),a=await r.json();return r.status===200&&a.ok?{...a,ok:!0}:{ok:!1,error:a.error||"Ingest failed."}}catch(r){return{ok:!1,error:r instanceof Error?r.message:String(r)}}}async knowledgeQuery(t,n,r){try{const a=await fetch(`${this.baseUrl}/api/knowledge/query`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({tag:t,question:n,topK:r})}),s=await a.json();return a.status===200&&s.ok?{...s,ok:!0}:{ok:!1,error:s.error||"Query failed."}}catch(a){return{ok:!1,error:a instanceof Error?a.message:String(a)}}}async knowledgeForget(t){try{const n=await fetch(`${this.baseUrl}/api/knowledge/forget`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({tag:t})}),r=await n.json();return n.status===200&&r.ok?{...r,ok:!0}:{ok:!1,error:r.error||"Forget failed."}}catch(n){return{ok:!1,error:n instanceof Error?n.message:String(n)}}}async marketplaceSearch(t){try{const r=await(await fetch(`${this.baseUrl}/api/skills/marketplace?q=${encodeURIComponent(t)}`,{headers:mt()})).json();return Array.isArray(r.results)?r.results:[]}catch{return[]}}async marketplaceInstall(t){try{const n=await fetch(`${this.baseUrl}/api/skills/marketplace/install`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({name:t})}),r=await n.json();return n.status===200&&r.ok?{ok:!0}:{ok:!1,error:r.error||"Install failed.",quarantined:r.quarantined===!0}}catch(n){return{ok:!1,error:n instanceof Error?n.message:String(n)}}}async marketplaceUninstall(t){try{const n=await fetch(`${this.baseUrl}/api/skills/marketplace/uninstall`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({name:t})}),r=await n.json();return n.status===200&&r.ok?{ok:!0}:{ok:!1,error:r.error||"Uninstall failed."}}catch(n){return{ok:!1,error:n instanceof Error?n.message:String(n)}}}async sendChannelMessage(t,n){const r=await this.sendAdminRequest("/api/admin/hub/channels/send","POST",{target:t,text:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&a.ok?a:{ok:!1,error:a.error||"Send failed.",unauthorized:r.status===401,forbidden:r.status===403}}async gatewayPolicies(){const t=await this.sendAdminRequest("/api/admin/gateway/policies","GET");if(!t)return{ok:!1,error:"Could not reach the dashboard server."};const n=t.data??{};return t.status===200&&n.ok?{ok:!0,policies:n.policies,statusRecipients:n.statusRecipients,contacts:n.contacts,askUserWait:n.askUserWait,askUserTimeoutMs:n.askUserTimeoutMs}:{ok:!1,error:n.error||"Failed to read policies.",unauthorized:t.status===401,forbidden:t.status===403}}async saveGatewayPolicies(t,n,r,a){const s={policies:t};Array.isArray(n)&&(s.statusRecipients=n),Array.isArray(r)&&(s.contacts=r),a&&(s.askUserWait=a.wait,typeof a.timeoutMs=="number"&&(s.askUserTimeoutMs=a.timeoutMs));const o=await this.sendAdminRequest("/api/admin/gateway/policies","PUT",s);if(!o)return{ok:!1,error:"Could not reach the dashboard server."};const l=o.data??{};return o.status===200&&l.ok?l:{ok:!1,error:l.error||"Failed to save policies.",unauthorized:o.status===401,forbidden:o.status===403}}async fetchGatewayConversations(t={}){const n=new URLSearchParams;t.offset&&n.set("offset",String(t.offset)),t.limit&&n.set("limit",String(t.limit)),t.q&&n.set("q",t.q);const r=n.toString(),a=await this.sendAdminRequest(`/api/admin/gateway/conversations${r?`?${r}`:""}`,"GET");if(!a)return{ok:!1,error:"Could not reach the dashboard server."};const s=a.data??{};return a.status===200&&s.ok?{ok:!0,conversations:s.conversations,total:s.total,hasMore:s.hasMore}:{ok:!1,error:s.error||"Failed to load conversations.",unauthorized:a.status===401,forbidden:a.status===403}}async clearGatewayConversation(t){const n=await this.sendAdminRequest("/api/admin/gateway/conversations","DELETE",{key:t});if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?{ok:!0}:{ok:!1,error:r.error||"Failed to clear conversation.",unauthorized:n.status===401,forbidden:n.status===403}}async addConversationTag(t,n){const r=await this.sendAdminRequest("/api/admin/gateway/conversations/tags","PUT",{action:"add",key:t,tag:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&a.ok?{ok:!0}:{ok:!1,error:a.error||"Failed to add tag.",unauthorized:r.status===401,forbidden:r.status===403}}async removeConversationTag(t,n){const r=await this.sendAdminRequest("/api/admin/gateway/conversations/tags","PUT",{action:"remove",key:t,tag:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&a.ok?{ok:!0}:{ok:!1,error:a.error||"Failed to remove tag.",unauthorized:r.status===401,forbidden:r.status===403}}async getAllConversationTags(){const t=await this.sendAdminRequest("/api/admin/gateway/conversations/tags","PUT",{action:"getAllTags"});if(!t)return{ok:!1,error:"Could not reach the dashboard server."};const n=t.data??{};return t.status===200&&n.ok?{ok:!0,tags:n.tags}:{ok:!1,error:n.error||"Failed to load tags.",unauthorized:t.status===401,forbidden:t.status===403}}async exportGatewayConversations(t){var n,r,a;try{const s=Xt(),o=await fetch(`${this.baseUrl}/api/admin/gateway/conversations/export`,{method:"POST",headers:{"Content-Type":"application/json",...s?{Authorization:`Bearer ${s}`}:{}},body:JSON.stringify({keys:t}),signal:AbortSignal.timeout(3e4)});if(o.status===200&&((n=o.headers.get("content-type"))!=null&&n.includes("application/zip"))){const c=await o.blob(),u=URL.createObjectURL(c),d=document.createElement("a");return d.href=u,d.download=((a=(r=o.headers.get("content-disposition"))==null?void 0:r.match(/filename="(.+)"/))==null?void 0:a[1])||"conversations.zip",document.body.appendChild(d),d.click(),document.body.removeChild(d),URL.revokeObjectURL(u),{ok:!0}}return{ok:!1,error:(await o.json().catch(()=>({}))).error||"Export failed."}}catch(s){return{ok:!1,error:s instanceof Error?s.message:String(s)}}}async getContacts(){const t=await this.sendAdminRequest("/api/admin/contacts","GET");if(!t)return{ok:!1,error:"Could not reach the dashboard server."};const n=t.data??{};return t.status===200&&n.ok?{ok:!0,contacts:n.contacts}:{ok:!1,error:n.error||"Failed to read contacts."}}async approveContact(t,n){return this.contactAction("approve",t,n)}async rejectContact(t,n){return this.contactAction("reject",t,n)}async deleteContact(t,n){return this.contactAction("delete",t,n)}async updateContact(t,n,r){const a=await this.sendAdminRequest("/api/admin/contacts","PUT",{action:"update",platform:t,id:n,...r});if(!a)return{ok:!1,error:"Could not reach the dashboard server."};const s=a.data??{};return a.status===200&&s.ok?s:{ok:!1,error:s.error||"Update failed."}}async contactAction(t,n,r){const a=await this.sendAdminRequest("/api/admin/contacts","PUT",{action:t,platform:n,nameOrId:r});if(!a)return{ok:!1,error:"Could not reach the dashboard server."};const s=a.data??{};return a.status===200&&s.ok?s:{ok:!1,error:s.error||`${t} failed.`}}async getPlatformConfigs(){const t=await this.sendAdminRequest("/api/config/platforms","GET");if(!t)return[];const n=t.data??{};return Array.isArray(n.platforms)?n.platforms:[]}async setPlatformConfig(t,n){const r=await this.sendAdminRequest(`/api/config/platforms/${encodeURIComponent(t)}`,"POST",{values:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&a.ok?a:{ok:!1,error:a.error||"Save failed.",unauthorized:r.status===401,forbidden:r.status===403}}async removePlatformConfig(t){const n=await this.sendAdminRequest(`/api/config/platforms/${encodeURIComponent(t)}`,"DELETE");if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?r:{ok:!1,error:r.error||"Remove failed.",unauthorized:n.status===401,forbidden:n.status===403}}async verifyPlatformConfig(t,n){const r=await this.sendAdminRequest(`/api/config/platforms/${encodeURIComponent(t)}/verify`,"POST",{values:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return{ok:a.ok??!1,info:a.info,error:a.error}}async saveAdminQuota(t){const n=await this.sendAdminRequest("/api/admin/quota","PUT",t);if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?r:{ok:!1,error:r.error||"Save failed.",unauthorized:n.status===401}}async getBedrockStatus(){const t=await this.sendAdminRequest("/api/bedrock/status","GET");return!t||t.status!==200?{configured:!1,region:"us-east-1",authMethod:"none",apiKeySet:!1,iamKeySet:!1}:t.data??{}}async setupBedrock(t){const n=await this.sendAdminRequest("/api/bedrock/setup","POST",{envVars:t});if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?{ok:!0,envVarsWritten:r.envVarsWritten}:{ok:!1,error:r.error||"Save failed."}}async probeBedrock(t){const n=await this.sendAdminRequest("/api/bedrock/probe","POST",{region:t});if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?{ok:!0,models:r.models}:{ok:!1,error:r.error||"Probe failed."}}async listTasks(){const t=await this.sendAdminRequest("/api/tasks","GET");if(!t)return null;const n=t.data??{};return{status:t.status,tasks:Array.isArray(n.tasks)?n.tasks:[]}}async startTask(t,n){const r=await this.sendAdminRequest("/api/tasks","POST",{args:t,timeoutMs:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&a.ok&&a.task?a:{ok:!1,error:a.error||"Start failed.",unauthorized:r.status===401,forbidden:r.status===403}}async getTask(t){const n=await this.sendAdminRequest(`/api/tasks/${encodeURIComponent(t)}`,"GET");if(!n)return null;const r=n.data??{};return{status:n.status,task:r.task??null}}async cancelTask(t){const n=await this.sendAdminRequest(`/api/tasks/${encodeURIComponent(t)}/cancel`,"POST");if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?r:{ok:!1,error:r.error||"Cancel failed.",unauthorized:n.status===401,forbidden:n.status===403}}subscribeTask(t,n){const r=Xt(),a=new EventSource(`${this.baseUrl}/api/tasks/${encodeURIComponent(t)}/events?token=${encodeURIComponent(r??"")}`);return a.addEventListener("log",s=>{var o;try{(o=n.onLog)==null||o.call(n,JSON.parse(s.data))}catch{}}),a.addEventListener("status",s=>{var o;try{const l=JSON.parse(s.data);l.status&&((o=n.onStatus)==null||o.call(n,l.status))}catch{}}),()=>a.close()}async getWhatsAppStatus(){const t=await this.sendAdminRequest("/api/whatsapp","GET");if(!t)return null;const n=t.data??{};return t.status===200&&n.ok&&n.status?{status:n.status,contacts:n.contacts??{}}:null}async startWhatsAppPair(t){const n=await this.sendAdminRequest("/api/whatsapp/pair","POST",{phone:t||void 0});if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?r:{ok:!1,error:r.error||"Pairing failed to start.",unauthorized:n.status===401,forbidden:n.status===403}}async cancelWhatsAppPair(){const t=await this.sendAdminRequest("/api/whatsapp/cancel","POST");if(!t)return{ok:!1,error:"Could not reach the dashboard server."};const n=t.data??{};return t.status===200&&n.ok?n:{ok:!1,error:n.error||"Cancel failed.",unauthorized:t.status===401,forbidden:t.status===403}}async unpairWhatsApp(){const t=await this.sendAdminRequest("/api/whatsapp/unpair","POST");if(!t)return{ok:!1,error:"Could not reach the dashboard server."};const n=t.data??{};return t.status===200&&n.ok?n:{ok:!1,error:n.error||"Unpair failed.",unauthorized:t.status===401,forbidden:t.status===403}}subscribeWhatsApp(t){const n=Xt(),r=new EventSource(`${this.baseUrl}/api/whatsapp/events?token=${encodeURIComponent(n??"")}`);return r.addEventListener("qr",a=>{var s;try{const o=JSON.parse(a.data);o.qr&&((s=t.onQr)==null||s.call(t,o.qr))}catch{}}),r.addEventListener("code",a=>{var s;try{const o=JSON.parse(a.data);o.code&&((s=t.onCode)==null||s.call(t,o.code))}catch{}}),r.addEventListener("status",a=>{var s;try{(s=t.onStatus)==null||s.call(t,JSON.parse(a.data))}catch{}}),()=>r.close()}async chatResolve(t){const n=Xt();try{const r=await fetch(`${this.baseUrl}/api/chat/resolve`,{method:"POST",headers:{"Content-Type":"application/json",...n?{Authorization:`Bearer ${n}`}:{}},body:JSON.stringify({message:t}),signal:AbortSignal.timeout(1e4)}),a=await r.json();return r.status===200&&a.ok&&Array.isArray(a.matches)?{ok:!0,matches:a.matches}:{ok:!1,matches:[],error:typeof a.error=="string"?a.error:"Resolve failed."}}catch{return{ok:!1,matches:[],error:"Could not reach the dashboard server."}}}async listRoutableModels(){const t=Xt();try{const n=await fetch(`${this.baseUrl}/api/chat/routable-models`,{headers:t?{Authorization:`Bearer ${t}`}:{},signal:AbortSignal.timeout(1e4)}),r=await n.json();return n.status===200&&r.ok&&Array.isArray(r.models)?r.models:[]}catch{return[]}}async listProjects(){const t=Xt();try{const n=await fetch(`${this.baseUrl}/api/projects`,{headers:t?{Authorization:`Bearer ${t}`}:{},signal:AbortSignal.timeout(1e4)}),r=await n.json();return n.status===200&&r.ok&&Array.isArray(r.projects)?r.projects:[]}catch{return[]}}async attachProject(t){const n=Xt();try{const r=await fetch(`${this.baseUrl}/api/projects/attach`,{method:"POST",headers:{"Content-Type":"application/json",...n?{Authorization:`Bearer ${n}`}:{}},body:JSON.stringify({path:t}),signal:AbortSignal.timeout(3e4)}),a=await r.json();return r.status===200&&a.ok&&a.project?{ok:!0,project:a.project}:{ok:!1,error:typeof a.error=="string"?a.error:"Attach failed."}}catch{return{ok:!1,error:"Could not reach the dashboard server."}}}async browseDirectories(t,n){const r=Xt();try{const a=new URLSearchParams;t&&a.set("path",t),n!=null&&n.showDrives&&a.set("showDrives","1");const s=a.toString()?`?${a.toString()}`:"",o=await fetch(`${this.baseUrl}/api/browse${s}`,{headers:r?{Authorization:`Bearer ${r}`}:{},signal:AbortSignal.timeout(1e4)}),l=await o.json();return o.status===200&&l.ok&&Array.isArray(l.entries)?{ok:!0,path:l.path??"",entries:l.entries,parent:l.parent??null,isProject:l.isProject??!1,drives:l.drives,breadcrumbs:l.breadcrumbs}:{ok:!1,path:"",entries:[],parent:null,isProject:!1,error:typeof l.error=="string"?l.error:"Browse failed."}}catch{return{ok:!1,path:"",entries:[],parent:null,isProject:!1,error:"Could not reach the dashboard server."}}}async resolveFolder(t,n){const r=Xt();try{const a=await fetch(this.baseUrl+"/api/browse/resolve-folder",{method:"POST",headers:{"Content-Type":"application/json",...r?{Authorization:"Bearer "+r}:{}},body:JSON.stringify({name:t,subPath:n||""}),signal:AbortSignal.timeout(1e4)}),s=await a.json();return a.status===200&&s.ok&&s.path?{ok:!0,path:s.path}:{ok:!1,path:"",error:typeof s.error=="string"?s.error:"Could not resolve folder."}}catch{return{ok:!1,path:"",error:"Could not reach the dashboard server."}}}async listChatSessions(){const t=Xt();try{const n=await fetch(`${this.baseUrl}/api/sessions`,{headers:t?{Authorization:`Bearer ${t}`}:{},signal:AbortSignal.timeout(1e4)}),r=await n.json();return n.status===200&&r.ok&&Array.isArray(r.sessions)?r.sessions:[]}catch{return[]}}async deleteChatSession(t){const n=Xt();try{const r=await fetch(`${this.baseUrl}/api/sessions/${encodeURIComponent(t)}`,{method:"DELETE",headers:n?{Authorization:`Bearer ${n}`}:{},signal:AbortSignal.timeout(1e4)}),a=await r.json();return r.status===200&&a.ok?{ok:!0}:{ok:!1,error:a.error||"Could not delete the session."}}catch{return{ok:!1,error:"Network error — could not delete the session."}}}async renameChatSession(t,n){const r=Xt();try{const a=await fetch(`${this.baseUrl}/api/sessions/${encodeURIComponent(t)}/rename`,{method:"POST",headers:{"Content-Type":"application/json",...r?{Authorization:`Bearer ${r}`}:{}},body:JSON.stringify({title:n}),signal:AbortSignal.timeout(1e4)}),s=await a.json();return a.status===200&&s.ok?{ok:!0}:{ok:!1,error:s.error||"Could not rename the session."}}catch{return{ok:!1,error:"Network error — could not rename the session."}}}async getChatSession(t){const n=Xt();try{const r=await fetch(`${this.baseUrl}/api/sessions/${encodeURIComponent(t)}`,{headers:n?{Authorization:`Bearer ${n}`}:{},signal:AbortSignal.timeout(1e4)}),a=await r.json();return r.status===200&&a.ok&&a.session?a.session:null}catch{return null}}async chatSend(t,n,r,a){const s=Xt();try{const o=await fetch(`${this.baseUrl}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json",...s?{Authorization:`Bearer ${s}`}:{}},body:JSON.stringify({sessionId:t,message:n,provider:r==null?void 0:r.provider,model:r==null?void 0:r.model,...(r==null?void 0:r.strict)===!0?{strict:!0}:{},projectPath:r==null?void 0:r.projectPath,attachments:r==null?void 0:r.attachments,...(r==null?void 0:r.worktree)===void 0?{}:{worktree:r.worktree},...(r==null?void 0:r.keepWorktree)===void 0?{}:{keepWorktree:r.keepWorktree},...(r==null?void 0:r.resume)===void 0?{}:{resume:r.resume}}),signal:a?AbortSignal.any([AbortSignal.timeout(3e5),a]):AbortSignal.timeout(3e5)}),l=await o.json();return o.status===200&&l.ok?{ok:!0,content:typeof l.content=="string"?l.content:"",followups:Array.isArray(l.followups)?l.followups:[],provider:typeof l.provider=="string"?l.provider:null,model:typeof l.model=="string"?l.model:null,...typeof l.routingNotice=="string"&&l.routingNotice?{routingNotice:l.routingNotice}:{},...typeof l.workspaceNotice=="string"&&l.workspaceNotice?{workspaceNotice:l.workspaceNotice}:{},...typeof l.workspacePath=="string"&&l.workspacePath?{workspacePath:l.workspacePath}:{},...typeof l.workspaceSource=="string"&&l.workspaceSource?{workspaceSource:l.workspaceSource}:{},generationFailed:l.generationFailed===!0,retryQueued:l.retryQueued===!0,...l.needsProject===!0?{needsProject:!0}:{},...l.refused===!0?{refused:!0}:{},...iB(l.worktree)?{worktree:l.worktree}:{},...sB(l.resume)?{resume:l.resume}:{},...Array.isArray(l.findings)?{findings:l.findings}:{},...oB(l.turnReport)?{turnReport:l.turnReport}:{}}:{ok:!1,error:typeof l.error=="string"?l.error:"The agent could not answer.",unauthorized:o.status===401,forbidden:o.status===403}}catch(o){const l=o==null?void 0:o.name;return l==="TimeoutError"?{ok:!1,turnStillRunning:!0,error:"The dashboard stopped waiting after 5 minutes — the turn is STILL RUNNING on the server. Its answer will appear here when it lands (nothing was lost — the turn keeps running)."}:l==="AbortError"?{ok:!1,error:"Cancelled."}:{ok:!1,error:"Could not reach the dashboard server."}}}async chatCancel(t){const n=await this.sendAdminRequest("/api/chat/cancel","POST",{sessionId:t});if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?{ok:!0,cancelled:r.cancelled===!0}:{ok:!1,error:r.error||"Cancel failed."}}async chatReset(t){const n=await this.sendAdminRequest("/api/chat/reset","POST",{sessionId:t});if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?{ok:!0}:{ok:!1,error:r.error||"Reset failed."}}async chatSupportBundle(t){var r,a,s;const n=Xt();try{const o=await fetch(`${this.baseUrl}/api/chat/${encodeURIComponent(t)}/support-bundle`,{method:"GET",headers:{...n?{Authorization:`Bearer ${n}`}:{}},signal:AbortSignal.timeout(3e4)});if(o.status===200&&((r=o.headers.get("content-type"))!=null&&r.includes("application/zip"))){const c=await o.blob(),u=URL.createObjectURL(c),d=document.createElement("a");return d.href=u,d.download=((s=(a=o.headers.get("content-disposition"))==null?void 0:a.match(/filename="(.+)"/))==null?void 0:s[1])||"nuvira-support.zip",document.body.appendChild(d),d.click(),document.body.removeChild(d),URL.revokeObjectURL(u),{ok:!0}}return{ok:!1,error:(await o.json().catch(()=>({}))).error||"Could not build the support bundle."}}catch(o){return{ok:!1,error:o instanceof Error?o.message:"Could not reach the dashboard server."}}}subscribeChat(t,n){const r=Xt(),a=new EventSource(`${this.baseUrl}/api/chat/${encodeURIComponent(t)}/events?token=${encodeURIComponent(r??"")}`);return a.addEventListener("progress",s=>{var o;try{const l=JSON.parse(s.data);l.line&&((o=n.onProgress)==null||o.call(n,l.line))}catch{}}),a.addEventListener("status",s=>{var o,l;try{const c=JSON.parse(s.data);c.status&&((o=n.onStatus)==null||o.call(n,c.status)),c.status==="done"&&c.answer&&typeof c.answer.content=="string"&&((l=n.onTurnDone)==null||l.call(n,{content:c.answer.content,followups:Array.isArray(c.answer.followups)?c.answer.followups:[],generationFailed:c.answer.generationFailed===!0,...c.answer.bounded===void 0?{}:{bounded:c.answer.bounded},...c.answer.provider===void 0?{}:{provider:c.answer.provider},...c.answer.model===void 0?{}:{model:c.answer.model}}))}catch{}}),a.addEventListener("token",s=>{var o;try{const l=JSON.parse(s.data);typeof l.text=="string"&&l.text.length>0&&((o=n.onToken)==null||o.call(n,l.text))}catch{}}),a.addEventListener("tool",s=>{var o;try{const l=JSON.parse(s.data);l.tool&&(l.phase==="started"||l.phase==="called")&&((o=n.onTool)==null||o.call(n,{id:l.id||`call_${Math.random().toString(36).slice(2,8)}`,tool:l.tool,phase:l.phase,args:l.args,ok:l.ok,result:l.result,error:l.error,durationMs:l.durationMs}))}catch{}}),a.addEventListener("plan",s=>{var o;try{const l=JSON.parse(s.data);l.goal&&Array.isArray(l.steps)&&((o=n.onPlan)==null||o.call(n,{goal:l.goal,steps:l.steps,revision:l.revision??0}))}catch{}}),a.addEventListener("diff",s=>{var o;try{const l=JSON.parse(s.data);Array.isArray(l.files)&&((o=n.onDiff)==null||o.call(n,{files:l.files,summary:l.summary??""}))}catch{}}),a.addEventListener("finding",s=>{var o;try{const c=JSON.parse(s.data).finding;c&&typeof c.claim=="string"&&(c.verdict==="CONFIRMED"||c.verdict==="PLAUSIBLE")&&((o=n.onFinding)==null||o.call(n,{claim:c.claim,verdict:c.verdict,outcome:typeof c.outcome=="string"?c.outcome:"",evidence:Array.isArray(c.evidence)?c.evidence:[],source:typeof c.source=="string"?c.source:""}))}catch{}}),a.addEventListener("skill_draft",s=>{var o;try{const l=JSON.parse(s.data);l.name&&l.markdown&&((o=n.onSkillDraft)==null||o.call(n,{name:l.name,description:l.description??"",markdown:l.markdown,updatedAt:l.updatedAt??0}))}catch{}}),a.addEventListener("secret_request",s=>{var o;try{const l=JSON.parse(s.data);l.skillName&&Array.isArray(l.missing)&&((o=n.onSecretRequest)==null||o.call(n,{skillName:l.skillName,missing:l.missing,persisted:l.persisted??{}}))}catch{}}),a.addEventListener("execution_result",s=>{var o;try{const l=JSON.parse(s.data);l.skillName&&l.runtime!==void 0&&((o=n.onExecutionResult)==null||o.call(n,{skillName:l.skillName,runtime:l.runtime,success:l.success??!1,durationMs:l.durationMs??0,exitCode:l.exitCode??0,stdout:l.stdout??"",stderr:l.stderr??"",timestamp:l.timestamp??Date.now()}))}catch{}}),a.addEventListener("question",s=>{var o;try{const l=JSON.parse(s.data);l.questionId&&l.question&&((o=n.onQuestion)==null||o.call(n,{questionId:l.questionId,question:l.question,choices:l.choices??[],multiSelect:l.multiSelect===!0}))}catch{}}),()=>a.close()}async chatRespond(t,n,r={}){try{const s=await(await fetch(`${this.baseUrl}/api/chat/${encodeURIComponent(t)}/respond`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({questionId:n,...r})})).json();return{ok:s.ok===!0,error:s.error}}catch(a){return{ok:!1,error:a instanceof Error?a.message:String(a)}}}async skillDraftAccept(t){try{const r=await(await fetch(`${this.baseUrl}/api/skills/drafts/${encodeURIComponent(t)}/accept`,{method:"POST",headers:{...mt()}})).json();return{ok:r.ok===!0,error:r.error}}catch(n){return{ok:!1,error:n instanceof Error?n.message:String(n)}}}async skillDraftReject(t){try{const r=await(await fetch(`${this.baseUrl}/api/skills/drafts/${encodeURIComponent(t)}`,{method:"DELETE",headers:{...mt()}})).json();return{ok:r.ok===!0,error:r.error}}catch(n){return{ok:!1,error:n instanceof Error?n.message:String(n)}}}async saveSecrets(t){try{const r=await(await fetch(`${this.baseUrl}/api/skills/secrets`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({vars:t})})).json();return{ok:r.ok===!0,error:r.error,saved:r.saved,refused:r.refused}}catch(n){return{ok:!1,error:n instanceof Error?n.message:String(n)}}}async fetchSkillEnv(){try{const t=await fetch(`${this.baseUrl}/api/skills/env`,{headers:{...mt()}}),n=await it(t);return(n==null?void 0:n.vars)??[]}catch{return[]}}async deleteSkillEnvVar(t){try{const r=await(await fetch(`${this.baseUrl}/api/skills/env/delete`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({name:t})})).json();return{ok:r.ok===!0,removed:r.removed,error:r.error}}catch(n){return{ok:!1,error:n instanceof Error?n.message:String(n)}}}async testSkillEnvVar(t){try{const r=await(await fetch(`${this.baseUrl}/api/skills/env/test`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({name:t})})).json();return{ok:r.ok===!0,usable:r.usable,detail:r.detail,error:r.error}}catch(n){return{ok:!1,error:n instanceof Error?n.message:String(n)}}}async fetchProcessEnv(){try{const t=await fetch(`${this.baseUrl}/api/process-env`,{headers:{...mt()}}),n=await it(t);return(n==null?void 0:n.vars)??[]}catch{return[]}}async fetchLimits(){try{const t=await fetch(`${this.baseUrl}/api/limits`),n=await it(t);return!n||typeof n.attachmentMaxBytes!="number"||n.attachmentMaxBytes<=0?null:{attachmentMaxBytes:n.attachmentMaxBytes,extractMaxChars:typeof n.extractMaxChars=="number"?n.extractMaxChars:0}}catch{return null}}async fetchContinuity(){try{const t=await fetch(`${this.baseUrl}/api/continuity`,{headers:{...mt()}}),n=await it(t);return!n||n.ok!==!0?null:{sessions:n.sessions??[],recall:n.recall??[],toggles:n.toggles??{sessionStore:!1,sessionRecall:!1}}}catch{return null}}async clearContinuity(t,n,r){try{const s=await(await fetch(`${this.baseUrl}/api/continuity/clear`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({target:t,...n?{id:n}:{},...r?{olderThanMs:r}:{}})})).json();return{ok:s.ok===!0,removed:s.removed,error:s.error}}catch(a){return{ok:!1,error:a instanceof Error?a.message:String(a)}}}async fetchHistory(){try{const t=await fetch(`${this.baseUrl}/api/history`,{headers:{...mt()}});return await it(t)}catch{return null}}async clearHistory(t,n={}){try{const a=await(await fetch(`${this.baseUrl}/api/history/clear`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({target:t,...n.id?{id:n.id}:{},...n.olderThanMs?{olderThanMs:n.olderThanMs}:{}})})).json();return{ok:a.ok===!0,removed:a.removed,error:a.error}}catch(r){return{ok:!1,error:r instanceof Error?r.message:String(r)}}}async fetchVerifyBacklog(){try{const t=await fetch(`${this.baseUrl}/api/models/verify-next`,{headers:{...mt()}});return await it(t)}catch{return null}}async startVerifyBacklog(t){try{const n=await fetch(`${this.baseUrl}/api/models/verify-next`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({count:t})}),r=await it(n);return r?{ok:r.ok===!0,error:r.error,refusal:r.refusal,state:r.state}:{ok:!1,error:"The dashboard server did not respond."}}catch(n){return{ok:!1,error:n instanceof Error?n.message:"Could not start the run."}}}async saveProcessEnvVar(t,n){try{const a=await(await fetch(`${this.baseUrl}/api/process-env`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({name:t,value:n})})).json();return{ok:a.ok===!0,row:a.row,error:a.error,reason:a.reason}}catch(r){return{ok:!1,error:r instanceof Error?r.message:String(r)}}}async deleteProcessEnvVar(t){try{const r=await(await fetch(`${this.baseUrl}/api/process-env/delete`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({name:t})})).json();return{ok:r.ok===!0,removed:r.removed,row:r.row,error:r.error}}catch(n){return{ok:!1,error:n instanceof Error?n.message:String(n)}}}async fetchHooks(){try{const t=await fetch(`${this.baseUrl}/api/hooks`,{headers:{...mt()}}),n=await it(t);return!n||!Array.isArray(n.hooks)?null:n}catch{return null}}async saveHooks(t){try{const n=await fetch(`${this.baseUrl}/api/hooks`,{method:"PUT",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({hooks:t})}),r=await n.json();return{ok:r.ok===!0,hooks:r.hooks,error:r.error,forbidden:n.status===403}}catch(n){return{ok:!1,error:n instanceof Error?n.message:String(n)}}}}const K=new hB;async function pB(e=!1){const t=await K.sendAdminRequest(`/api/mcp${e?"?deep=1":""}`,"GET");return!t||t.status!==200?null:t.data}async function mB(e){const t=await K.sendAdminRequest("/api/mcp/settings","POST",{patch:e}),n=(t==null?void 0:t.data)??null;return t?n??{ok:t.status===200,error:`Server returned HTTP ${t.status}`}:{ok:!1,error:"Could not reach the dashboard server."}}async function gB(e){const t=await K.sendAdminRequest("/api/mcp/install","POST",e);return t?t.data??{ok:!1,error:`Server returned HTTP ${t.status}`}:{ok:!1,error:"Could not reach the dashboard server."}}async function vB(e){const t=await K.sendAdminRequest("/api/mcp/servers","POST",e);return t?t.data??{ok:!1,error:`Server returned HTTP ${t.status}`}:{ok:!1,error:"Could not reach the dashboard server."}}async function yB(e){const t=await K.sendAdminRequest("/api/mcp/uninstall","POST",{name:e});return t?t.data??{ok:!1,reason:`Server returned HTTP ${t.status}`}:{ok:!1,reason:"Could not reach the dashboard server."}}const du=["enterprise","neutral","pastel","executive","contrast","premium","premium-amoled"],Bp=["light","dark"],aw=[100,112,125,150],ch={enterprise:"Enterprise",neutral:"Neutral",pastel:"Pastel",executive:"Executive",contrast:"High contrast",premium:"Premium","premium-amoled":"Premium AMOLED"},IT="nuvira.dashboard.theme",cS={palette:"enterprise",mode:"dark",a11y:!1,fontScale:100};function Bo(e,t){return e.includes(t)}function bB(){return typeof window>"u"||typeof window.matchMedia!="function"?null:window.matchMedia("(prefers-color-scheme: dark)").matches}function $T(){const e=bB();return e===null?{...cS}:{...cS,mode:e?"dark":"light"}}function LT(){const e=$T();if(typeof localStorage>"u")return e;let t;try{const a=localStorage.getItem(IT);if(!a)return e;t=JSON.parse(a)}catch{return e}if(typeof t!="object"||t===null)return e;const n=t,r=Bo(aw,n.fontScale)?n.fontScale:e.fontScale;return{palette:Bo(du,n.palette)?n.palette:e.palette,mode:Bo(Bp,n.mode)?n.mode:e.mode,a11y:typeof n.a11y=="boolean"?n.a11y:e.a11y,fontScale:r}}function DT(e){if(!(typeof localStorage>"u"))try{localStorage.setItem(IT,JSON.stringify(e))}catch{}}function iw(e,t){const n=typeof document<"u"?document.documentElement:void 0;n&&(n.setAttribute("data-palette",e.palette),n.setAttribute("data-mode",e.mode),n.setAttribute("data-a11y",e.a11y?"on":"off"),n.setAttribute("data-font-scale",String(e.fontScale)),n.style.colorScheme=e.mode)}function xB(e,t){const n={palette:Bo(du,t.palette)?t.palette:e.palette,mode:Bo(Bp,t.mode)?t.mode:e.mode,a11y:t.a11y??e.a11y,fontScale:Bo(aw,t.fontScale)?t.fontScale:e.fontScale};return n.a11y||(n.fontScale=100),n}let pr=LT();const xy=new Set;function BT(){for(const e of xy)e()}function wB(e){return xy.add(e),()=>{xy.delete(e)}}function uS(){return pr}function Hd(e){const t=xB(pr,e);t.palette===pr.palette&&t.mode===pr.mode&&t.a11y===pr.a11y&&t.fontScale===pr.fontScale||(pr=t,iw(pr),DT(pr),BT())}function kB(){pr=$T(),iw(pr),DT(pr),BT()}function SB(){return b.useSyncExternalStore(wB,uS,uS)}const dS={light:"Light",dark:"Dark"},fS={100:"100%",112:"112%",125:"125%",150:"150%"};function jB(){const e=SB(),[t,n]=b.useState(!1),r=b.useRef(null),a=b.useRef(null),s=b.useRef(null),o=b.useId(),l=`${o}-panel`;b.useEffect(()=>{if(!t)return;function u(f){var h;f.key==="Escape"&&(n(!1),(h=r.current)==null||h.focus())}function d(f){var p;const h=f.target;h&&((p=s.current)!=null&&p.contains(h))||n(!1)}return document.addEventListener("keydown",u),document.addEventListener("pointerdown",d),()=>{document.removeEventListener("keydown",u),document.removeEventListener("pointerdown",d)}},[t]),b.useEffect(()=>{var d,f,h;if(!t)return;(h=((d=a.current)==null?void 0:d.querySelector("input:checked"))??((f=a.current)==null?void 0:f.querySelector("input")))==null||h.focus()},[t]);const c=`${ch[e.palette]} palette, ${dS[e.mode].toLowerCase()} mode, text size ${fS[e.fontScale]}`+(e.a11y?", accessibility mode on":"");return i.jsxs("div",{className:"theme-switcher",ref:s,onBlur:u=>{const d=u.relatedTarget;d&&!u.currentTarget.contains(d)&&n(!1)},children:[i.jsxs("button",{type:"button",ref:r,className:"theme-trigger","aria-expanded":t,"aria-controls":t?l:void 0,onClick:()=>n(u=>!u),children:[i.jsx("span",{"aria-hidden":"true",children:"🎨"}),i.jsx("span",{children:"Appearance"})]}),t&&i.jsxs("div",{className:"theme-panel",id:l,ref:a,children:[i.jsxs("fieldset",{className:"theme-group",children:[i.jsx("legend",{className:"theme-group-label",children:"Palette"}),du.map(u=>i.jsxs("label",{className:"theme-option",children:[i.jsx("input",{type:"radio",name:`${o}-palette`,value:u,checked:e.palette===u,onChange:()=>Hd({palette:u})}),i.jsx("span",{className:"theme-swatch","data-swatch":u,"aria-hidden":"true"}),i.jsx("span",{className:"theme-option-label",children:ch[u]})]},u))]}),i.jsxs("fieldset",{className:"theme-group",children:[i.jsx("legend",{className:"theme-group-label",children:"Mode"}),Bp.map(u=>i.jsxs("label",{className:"theme-option",children:[i.jsx("input",{type:"radio",name:`${o}-mode`,value:u,checked:e.mode===u,onChange:()=>Hd({mode:u})}),i.jsx("span",{className:"theme-option-label",children:dS[u]})]},u))]}),i.jsxs("fieldset",{className:"theme-group",children:[i.jsx("legend",{className:"theme-group-label",children:"Text size"}),aw.map(u=>i.jsxs("label",{className:"theme-option",children:[i.jsx("input",{type:"radio",name:`${o}-scale`,value:u,checked:e.fontScale===u,onChange:()=>Hd({fontScale:u,a11y:e.a11y||u!==100})}),i.jsx("span",{className:"theme-option-label",children:fS[u]})]},u)),!e.a11y&&i.jsx("p",{className:"theme-hint",children:"A larger size turns on accessibility mode, which is what defines it."})]}),i.jsxs("div",{className:"theme-group",children:[i.jsxs("label",{className:"theme-switch",children:[i.jsx("input",{type:"checkbox",checked:e.a11y,onChange:u=>Hd({a11y:u.target.checked})}),i.jsx("span",{className:"theme-switch-track","aria-hidden":"true"}),i.jsx("span",{className:"theme-option-label",children:"Accessibility mode"})]}),i.jsx("p",{className:"theme-hint",children:"Larger targets, stronger borders and no motion. Off by default so it never changes the look for anyone who does not need it."})]}),i.jsx("button",{type:"button",className:"theme-reset",onClick:kB,children:"Reset to system default"}),i.jsx("p",{className:"sr-only",role:"status",children:c})]})]})}function NB(){const[e,t]=b.useState(null),[n,r]=b.useState(!1),[a,s]=b.useState(""),[o,l]=b.useState(""),[c,u]=b.useState(!1),[d,f]=b.useState(null),h=b.useRef(null),p=b.useCallback(()=>{K.fetchAdminAuthStatus().then(w=>t(w))},[]);b.useEffect(()=>{p()},[p]),b.useEffect(()=>{if(!n)return;function w(S){h.current&&!h.current.contains(S.target)&&r(!1)}function j(S){S.key==="Escape"&&r(!1)}return document.addEventListener("mousedown",w),document.addEventListener("keydown",j),()=>{document.removeEventListener("mousedown",w),document.removeEventListener("keydown",j)}},[n]);const m=(e==null?void 0:e.authenticated)===!0,g=(e==null?void 0:e.configured)===!0,y=async w=>{w.preventDefault(),u(!0),f(null);const j=g?await K.adminLogin(a,o):await K.adminSetup(a,o);j.ok?(s(""),l(""),r(!1),p()):f(j.error||(g?"Login failed.":"Setup failed.")),u(!1)},v=async()=>{r(!1),await K.adminLogout(),p()},k=e?m?`👤 ${e.user||"account"}${e.role?` · ${e.role}`:""}`:"👤 Sign in":"👤 Account";return i.jsxs("div",{className:"topbar-account",ref:h,children:[i.jsx("button",{type:"button",className:"topbar-action","aria-haspopup":"menu","aria-expanded":n,onClick:()=>r(w=>!w),children:k}),n?i.jsx("div",{className:"topbar-account-menu",role:"menu",children:m?i.jsxs(i.Fragment,{children:[i.jsxs("div",{className:"topbar-account-user",children:[i.jsx("span",{children:(e==null?void 0:e.user)||"account"}),e!=null&&e.role?i.jsx("span",{className:`admin-role-badge admin-role-${e.role}`,children:e.role}):null]}),e!=null&&e.mustChangePassword?i.jsx("p",{className:"topbar-account-hint",children:"Still on the first-run password — change it on the Admin page before writes will work."}):null,i.jsx("button",{type:"button",className:"topbar-account-item",onClick:()=>void v(),children:"🚪 Log out"})]}):i.jsxs("form",{className:"topbar-account-form",onSubmit:y,children:[i.jsx("p",{className:"topbar-account-title",children:g?"Sign in":"Create the first admin"}),i.jsxs("label",{children:[i.jsx("span",{children:"Username"}),i.jsx("input",{type:"text",value:a,onChange:w=>s(w.target.value),autoComplete:"username",placeholder:"admin"})]}),i.jsxs("label",{children:[i.jsx("span",{children:"Password"}),i.jsx("input",{type:"password",value:o,onChange:w=>l(w.target.value),autoComplete:g?"current-password":"new-password",placeholder:"••••••••"})]}),d?i.jsx("div",{className:"admin-error",children:d}):null,i.jsx("button",{type:"submit",className:"admin-refresh-btn",disabled:c||!a||!o,children:c?"⏳ …":g?"🔐 Sign in":"🔐 Create admin"}),g?null:i.jsx("p",{className:"topbar-account-hint",children:"The first user is always an admin."})]})}):null]})}const zT=[{group:"General",items:[{keys:["?"],description:"Show the shortcut cheatsheet"},{keys:["F1"],description:"Open the Help page"},{keys:["Esc"],description:"Close a dialog or panel"},{keys:["g","c"],description:"Go to Chat"},{keys:["g","o"],description:"Go to Overview"},{keys:["g","t"],description:"Go to Tasks"},{keys:["g","m"],description:"Go to Models"},{keys:["g","s"],description:"Go to System"},{keys:["g","h"],description:"Go to Agent Hub"}]},{group:"Navigation",items:[{keys:["/"],description:"Focus the navigation filter"},{keys:["["],description:"Collapse / expand the navigation drawer"}]}],EB={c:"/chat",o:"/overview",t:"/tasks",m:"/models",s:"/system",h:"/hub"};function _B(e){var a;const t=e;if(!t||typeof t.tagName!="string")return!1;if(t.isContentEditable)return!0;const n=(a=t.getAttribute)==null?void 0:a.call(t,"contenteditable");if(n!=null&&n!=="false")return!0;const r=t.tagName.toLowerCase();return r==="input"||r==="textarea"||r==="select"}function CB({open:e,onClose:t}){const n=b.useId(),r=b.useRef(null),a=b.useRef(null);return b.useEffect(()=>{var l;if(!e)return;a.current=document.activeElement;const s=()=>{var c;return Array.from(((c=r.current)==null?void 0:c.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'))??[])};(l=s()[0])==null||l.focus();function o(c){if(c.key==="Escape"){c.stopPropagation(),t();return}if(c.key!=="Tab")return;const u=s();if(u.length===0)return;const d=u[0],f=u[u.length-1];c.shiftKey&&document.activeElement===d?(c.preventDefault(),f.focus()):!c.shiftKey&&document.activeElement===f&&(c.preventDefault(),d.focus())}return document.addEventListener("keydown",o),()=>{var c;document.removeEventListener("keydown",o),(c=a.current)==null||c.focus()}},[e,t]),e?i.jsx("div",{className:"modal-scrim",onClick:t,children:i.jsxs("div",{className:"shortcuts-dialog",role:"dialog","aria-modal":"true","aria-labelledby":n,ref:r,onClick:s=>s.stopPropagation(),children:[i.jsxs("div",{className:"shortcuts-head",children:[i.jsx("h2",{className:"shortcuts-title",id:n,children:"⌨️ Keyboard shortcuts"}),i.jsx("button",{type:"button",className:"btn-secondary",onClick:t,"aria-label":"Close keyboard shortcuts",children:"✕ Close"})]}),zT.map(s=>i.jsxs("section",{className:"shortcuts-group",children:[i.jsx("h3",{className:"shortcuts-group-title",children:s.group}),i.jsx("dl",{className:"shortcuts-list",children:s.items.map(o=>i.jsxs("div",{className:"shortcuts-row",children:[i.jsx("dt",{className:"shortcuts-keys",children:o.keys.map(l=>i.jsx("kbd",{className:"shortcuts-key",children:l},l))}),i.jsx("dd",{className:"shortcuts-description",children:o.description})]},o.description))})]},s.group)),i.jsxs("p",{className:"shortcuts-note",children:["Shortcuts are ignored while you are typing, so ",i.jsx("kbd",{className:"shortcuts-key",children:"?"})," in a question stays a question mark."]})]})}):null}const FT=[{path:"/overview",label:"Overview",icon:"📊"},{path:"/tasks",label:"Tasks",icon:"🚀"},{path:"/models",label:"Models",icon:"🧠"},{path:"/system",label:"System",icon:"⚙️"},{path:"/help",label:"Help",icon:"❓"}],wy=[{label:"Agent Management",items:[{path:"/chat",label:"Chat",icon:"💬"},{path:"/hub",label:"Agent Hub",icon:"🧰"},{path:"/capabilities",label:"Capabilities",icon:"📋"},{path:"/dag",label:"Execution",icon:"🔀"},{path:"/routing",label:"Routing",icon:"🤖"},{path:"/requests",label:"Requests",icon:"📨"},{path:"/hooks",label:"Hooks",icon:"🪝"}]},{label:"Analysis & Monitoring",items:[{path:"/traces",label:"Traces",icon:"🔍"},{path:"/evals",label:"Evals",icon:"🏆"},{path:"/benchmarks",label:"Benchmarks",icon:"📈"},{path:"/costs",label:"Costs",icon:"💰"}]},{label:"Resources",items:[{path:"/memory",label:"Memory",icon:"💾"},{path:"/knowledge",label:"Knowledge",icon:"📚"},{path:"/history",label:"History",icon:"📝"},{path:"/decisions",label:"Decisions",icon:"🧭"},{path:"/env",label:"Env Config",icon:"🔐"},{path:"/process-env",label:"Process Env",icon:"🌱"}]},{label:"Integrations",items:[{path:"/platforms",label:"Platforms",icon:"🌐"},{path:"/mcp",label:"MCP",icon:"🔌"},{path:"/gateway",label:"Gateway",icon:"📡"},{path:"/contacts",label:"Contacts",icon:"📇"},{path:"/bedrock",label:"Bedrock",icon:"🪨"}]},{label:"Runtime",items:[{path:"/models/timeline",label:"Timeline",icon:"📅"},{path:"/executions",label:"Executions",icon:"📜"},{path:"/admin",label:"Admin",icon:"🛠️"}]}];function AB(e){const t=e.trim().toLowerCase();return t?wy.map(n=>n.label.toLowerCase().includes(t)?n:{...n,items:n.items.filter(r=>r.label.toLowerCase().includes(t))}).filter(n=>n.items.length>0):wy}function TB({children:e,connected:t,lastUpdated:n,onRefresh:r,refreshing:a=!1}){const[s,o]=b.useState(!1),[l,c]=b.useState(""),[u,d]=b.useState(!1),f=b.useRef(null),h=b.useRef(null),p=b.useRef(0),m=b.useId(),g=Li(),y=rw(),v=t?"connected":"reconnecting",k=t?"Connected":"Reconnecting...",w=AB(l),j=()=>o(!1);return b.useEffect(()=>{function S(x){var N,E;if(!(x.metaKey||x.ctrlKey||x.altKey)&&!_B(x.target)){if(x.key==="Escape"){if(u)return;s&&(o(!1),(N=f.current)==null||N.focus());return}if(x.key==="?"){x.preventDefault(),d(!0);return}if(x.key==="F1"){x.preventDefault(),y("/help");return}if(x.key==="/"){x.preventDefault(),(E=h.current)==null||E.focus();return}if(x.key==="["){x.preventDefault(),o(P=>!P);return}if(x.key==="g"){p.current=Date.now();return}if(Date.now()-p.current<1500){const P=EB[x.key.toLowerCase()];p.current=0,P&&(x.preventDefault(),y(P))}}}return document.addEventListener("keydown",S),()=>document.removeEventListener("keydown",S)},[s,u,y]),b.useEffect(()=>{var S;s&&((S=h.current)==null||S.focus())},[s]),b.useEffect(()=>{j()},[g.pathname]),i.jsxs("div",{className:"layout",children:[i.jsxs("header",{className:"topbar",children:[i.jsx("button",{type:"button",ref:f,className:"topbar-menu","aria-label":"Toggle navigation","aria-controls":"app-nav","aria-expanded":s,onClick:()=>o(S=>!S),children:i.jsx("span",{"aria-hidden":"true",children:"☰"})}),i.jsxs("div",{className:"topbar-brand",children:[i.jsx("span",{className:"topbar-logo","aria-hidden":"true",children:"🤖"}),i.jsx("span",{className:"topbar-title",children:"Agent-Nuvira"})]}),i.jsx("nav",{className:"primary-nav","aria-label":"Primary",children:FT.map(S=>i.jsxs(oS,{to:S.path,end:!0,className:({isActive:x})=>`primary-link${x?" active":""}`,children:[i.jsx("span",{"aria-hidden":"true",children:S.icon})," ",S.label]},S.path))}),i.jsxs("div",{className:"topbar-actions",children:[i.jsxs("button",{type:"button",className:"topbar-action",onClick:r,disabled:a,"aria-busy":a,children:[i.jsx("span",{"aria-hidden":"true",children:"⟳"})," ",a?"Refreshing…":"Refresh"]}),i.jsxs("button",{type:"button",className:"topbar-action","aria-haspopup":"dialog","aria-expanded":u,onClick:()=>d(!0),children:[i.jsx("span",{"aria-hidden":"true",children:"⌨️"})," Shortcuts"]}),i.jsx(jB,{}),i.jsxs("a",{className:"topbar-action",href:"https://www.agent-nuvira.com",target:"_blank",rel:"noopener noreferrer",title:"Agent-Nuvira website — capabilities, commands, docs, setup",children:[i.jsx("span",{"aria-hidden":"true",children:"🌐"})," Website"]}),i.jsx(NB,{})]})]}),i.jsxs("div",{className:"layout-body",children:[s&&i.jsx("div",{className:"nav-scrim",onClick:j,"aria-hidden":"true"}),i.jsxs("nav",{className:`nav${s?" open":""}`,id:"app-nav","aria-label":"Sections",children:[i.jsxs("div",{className:"nav-search",children:[i.jsx("label",{className:"sr-only",htmlFor:m,children:"Filter navigation"}),i.jsx("input",{id:m,ref:h,type:"search",className:"nav-search-input",placeholder:"Search",value:l,onChange:S=>c(S.target.value)})]}),i.jsxs("div",{className:"nav-links",children:[w.map(S=>i.jsxs("section",{className:"nav-group",children:[i.jsx("h2",{className:"nav-group-title",children:S.label}),S.items.map(x=>i.jsxs(oS,{to:x.path,end:x.path==="/",className:({isActive:N})=>`nav-link${N?" active":""}`,children:[i.jsx("span",{className:"nav-icon","aria-hidden":"true",children:x.icon}),x.label]},x.path))]},S.label)),w.length===0&&i.jsxs("p",{className:"nav-empty",children:["No sections match “",l,"”."]})]}),i.jsxs("div",{className:"nav-footer",children:[i.jsx("span",{className:`status-dot ${v}`}),i.jsx("span",{className:"status-text",children:k}),i.jsx("span",{className:"last-updated",children:n})]})]}),i.jsx("main",{className:"main",children:e})]}),i.jsx(CB,{open:u,onClose:()=>d(!1)})]})}function UT(e){var t,n,r="";if(typeof e=="string"||typeof e=="number")r+=e;else if(typeof e=="object")if(Array.isArray(e)){var a=e.length;for(t=0;t<a;t++)e[t]&&(n=UT(e[t]))&&(r&&(r+=" "),r+=n)}else for(n in e)e[n]&&(r&&(r+=" "),r+=n);return r}function Ye(){for(var e,t,n=0,r="",a=arguments.length;n<a;n++)(e=arguments[n])&&(t=UT(e))&&(r&&(r+=" "),r+=t);return r}var OB=Array.isArray,Wn=OB,PB=typeof fi=="object"&&fi&&fi.Object===Object&&fi,WT=PB,RB=WT,MB=typeof self=="object"&&self&&self.Object===Object&&self,IB=RB||MB||Function("return this")(),ga=IB,$B=ga,LB=$B.Symbol,rd=LB,hS=rd,HT=Object.prototype,DB=HT.hasOwnProperty,BB=HT.toString,lc=hS?hS.toStringTag:void 0;function zB(e){var t=DB.call(e,lc),n=e[lc];try{e[lc]=void 0;var r=!0}catch{}var a=BB.call(e);return r&&(t?e[lc]=n:delete e[lc]),a}var FB=zB,UB=Object.prototype,WB=UB.toString;function HB(e){return WB.call(e)}var GB=HB,pS=rd,qB=FB,KB=GB,VB="[object Null]",YB="[object Undefined]",mS=pS?pS.toStringTag:void 0;function XB(e){return e==null?e===void 0?YB:VB:mS&&mS in Object(e)?qB(e):KB(e)}var Ka=XB;function QB(e){return e!=null&&typeof e=="object"}var Va=QB,ZB=Ka,JB=Va,ez="[object Symbol]";function tz(e){return typeof e=="symbol"||JB(e)&&ZB(e)==ez}var El=tz,nz=Wn,rz=El,az=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,iz=/^\w*$/;function sz(e,t){if(nz(e))return!1;var n=typeof e;return n=="number"||n=="symbol"||n=="boolean"||e==null||rz(e)?!0:iz.test(e)||!az.test(e)||t!=null&&e in Object(t)}var sw=sz;function oz(e){var t=typeof e;return e!=null&&(t=="object"||t=="function")}var Di=oz;const _l=Je(Di);var lz=Ka,cz=Di,uz="[object AsyncFunction]",dz="[object Function]",fz="[object GeneratorFunction]",hz="[object Proxy]";function pz(e){if(!cz(e))return!1;var t=lz(e);return t==dz||t==fz||t==uz||t==hz}var ow=pz;const Be=Je(ow);var mz=ga,gz=mz["__core-js_shared__"],vz=gz,fg=vz,gS=function(){var e=/[^.]+$/.exec(fg&&fg.keys&&fg.keys.IE_PROTO||"");return e?"Symbol(src)_1."+e:""}();function yz(e){return!!gS&&gS in e}var bz=yz,xz=Function.prototype,wz=xz.toString;function kz(e){if(e!=null){try{return wz.call(e)}catch{}try{return e+""}catch{}}return""}var GT=kz,Sz=ow,jz=bz,Nz=Di,Ez=GT,_z=/[\\^$.*+?()[\]{}|]/g,Cz=/^\[object .+?Constructor\]$/,Az=Function.prototype,Tz=Object.prototype,Oz=Az.toString,Pz=Tz.hasOwnProperty,Rz=RegExp("^"+Oz.call(Pz).replace(_z,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function Mz(e){if(!Nz(e)||jz(e))return!1;var t=Sz(e)?Rz:Cz;return t.test(Ez(e))}var Iz=Mz;function $z(e,t){return e==null?void 0:e[t]}var Lz=$z,Dz=Iz,Bz=Lz;function zz(e,t){var n=Bz(e,t);return Dz(n)?n:void 0}var Ws=zz,Fz=Ws,Uz=Fz(Object,"create"),zp=Uz,vS=zp;function Wz(){this.__data__=vS?vS(null):{},this.size=0}var Hz=Wz;function Gz(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=t?1:0,t}var qz=Gz,Kz=zp,Vz="__lodash_hash_undefined__",Yz=Object.prototype,Xz=Yz.hasOwnProperty;function Qz(e){var t=this.__data__;if(Kz){var n=t[e];return n===Vz?void 0:n}return Xz.call(t,e)?t[e]:void 0}var Zz=Qz,Jz=zp,eF=Object.prototype,tF=eF.hasOwnProperty;function nF(e){var t=this.__data__;return Jz?t[e]!==void 0:tF.call(t,e)}var rF=nF,aF=zp,iF="__lodash_hash_undefined__";function sF(e,t){var n=this.__data__;return this.size+=this.has(e)?0:1,n[e]=aF&&t===void 0?iF:t,this}var oF=sF,lF=Hz,cF=qz,uF=Zz,dF=rF,fF=oF;function Cl(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}Cl.prototype.clear=lF;Cl.prototype.delete=cF;Cl.prototype.get=uF;Cl.prototype.has=dF;Cl.prototype.set=fF;var hF=Cl;function pF(){this.__data__=[],this.size=0}var mF=pF;function gF(e,t){return e===t||e!==e&&t!==t}var lw=gF,vF=lw;function yF(e,t){for(var n=e.length;n--;)if(vF(e[n][0],t))return n;return-1}var Fp=yF,bF=Fp,xF=Array.prototype,wF=xF.splice;function kF(e){var t=this.__data__,n=bF(t,e);if(n<0)return!1;var r=t.length-1;return n==r?t.pop():wF.call(t,n,1),--this.size,!0}var SF=kF,jF=Fp;function NF(e){var t=this.__data__,n=jF(t,e);return n<0?void 0:t[n][1]}var EF=NF,_F=Fp;function CF(e){return _F(this.__data__,e)>-1}var AF=CF,TF=Fp;function OF(e,t){var n=this.__data__,r=TF(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this}var PF=OF,RF=mF,MF=SF,IF=EF,$F=AF,LF=PF;function Al(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}Al.prototype.clear=RF;Al.prototype.delete=MF;Al.prototype.get=IF;Al.prototype.has=$F;Al.prototype.set=LF;var Up=Al,DF=Ws,BF=ga,zF=DF(BF,"Map"),cw=zF,yS=hF,FF=Up,UF=cw;function WF(){this.size=0,this.__data__={hash:new yS,map:new(UF||FF),string:new yS}}var HF=WF;function GF(e){var t=typeof e;return t=="string"||t=="number"||t=="symbol"||t=="boolean"?e!=="__proto__":e===null}var qF=GF,KF=qF;function VF(e,t){var n=e.__data__;return KF(t)?n[typeof t=="string"?"string":"hash"]:n.map}var Wp=VF,YF=Wp;function XF(e){var t=YF(this,e).delete(e);return this.size-=t?1:0,t}var QF=XF,ZF=Wp;function JF(e){return ZF(this,e).get(e)}var eU=JF,tU=Wp;function nU(e){return tU(this,e).has(e)}var rU=nU,aU=Wp;function iU(e,t){var n=aU(this,e),r=n.size;return n.set(e,t),this.size+=n.size==r?0:1,this}var sU=iU,oU=HF,lU=QF,cU=eU,uU=rU,dU=sU;function Tl(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}Tl.prototype.clear=oU;Tl.prototype.delete=lU;Tl.prototype.get=cU;Tl.prototype.has=uU;Tl.prototype.set=dU;var uw=Tl,qT=uw,fU="Expected a function";function dw(e,t){if(typeof e!="function"||t!=null&&typeof t!="function")throw new TypeError(fU);var n=function(){var r=arguments,a=t?t.apply(this,r):r[0],s=n.cache;if(s.has(a))return s.get(a);var o=e.apply(this,r);return n.cache=s.set(a,o)||s,o};return n.cache=new(dw.Cache||qT),n}dw.Cache=qT;var KT=dw;const hU=Je(KT);var pU=KT,mU=500;function gU(e){var t=pU(e,function(r){return n.size===mU&&n.clear(),r}),n=t.cache;return t}var vU=gU,yU=vU,bU=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,xU=/\\(\\)?/g,wU=yU(function(e){var t=[];return e.charCodeAt(0)===46&&t.push(""),e.replace(bU,function(n,r,a,s){t.push(a?s.replace(xU,"$1"):r||n)}),t}),kU=wU;function SU(e,t){for(var n=-1,r=e==null?0:e.length,a=Array(r);++n<r;)a[n]=t(e[n],n,e);return a}var fw=SU,bS=rd,jU=fw,NU=Wn,EU=El,xS=bS?bS.prototype:void 0,wS=xS?xS.toString:void 0;function VT(e){if(typeof e=="string")return e;if(NU(e))return jU(e,VT)+"";if(EU(e))return wS?wS.call(e):"";var t=e+"";return t=="0"&&1/e==-1/0?"-0":t}var _U=VT,CU=_U;function AU(e){return e==null?"":CU(e)}var YT=AU,TU=Wn,OU=sw,PU=kU,RU=YT;function MU(e,t){return TU(e)?e:OU(e,t)?[e]:PU(RU(e))}var XT=MU,IU=El;function $U(e){if(typeof e=="string"||IU(e))return e;var t=e+"";return t=="0"&&1/e==-1/0?"-0":t}var Hp=$U,LU=XT,DU=Hp;function BU(e,t){t=LU(t,e);for(var n=0,r=t.length;e!=null&&n<r;)e=e[DU(t[n++])];return n&&n==r?e:void 0}var hw=BU,zU=hw;function FU(e,t,n){var r=e==null?void 0:zU(e,t);return r===void 0?n:r}var QT=FU;const wr=Je(QT);function UU(e){return e==null}var WU=UU;const Xe=Je(WU);var HU=Ka,GU=Wn,qU=Va,KU="[object String]";function VU(e){return typeof e=="string"||!GU(e)&&qU(e)&&HU(e)==KU}var YU=VU;const Is=Je(YU);var ZT={exports:{}},rt={};/**
67
+ */function lh(){return lh=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},lh.apply(null,arguments)}function RT(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function q2(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function K2(e,t){return e.button===0&&(!t||t==="_self")&&!q2(e)}const V2=["onClick","relative","reloadDocument","replace","state","target","to","preventScrollReset","viewTransition"],Y2=["aria-current","caseSensitive","className","end","style","to","viewTransition","children"],X2="6";try{window.__reactRouterVersion=X2}catch{}const Q2=b.createContext({isTransitioning:!1}),Z2="startTransition",sS=H$[Z2];function J2(e){let{basename:t,children:n,future:r,window:a}=e,s=b.useRef();s.current==null&&(s.current=n2({window:a,v5Compat:!0}));let o=s.current,[l,c]=b.useState({action:o.action,location:o.location}),{v7_startTransition:u}=r||{},d=b.useCallback(f=>{u&&sS?sS(()=>c(f)):c(f)},[c,u]);return b.useLayoutEffect(()=>o.listen(d),[o,d]),b.useEffect(()=>W2(r),[r]),b.createElement(H2,{basename:t,children:n,location:l.location,navigationType:l.action,navigator:o,future:r})}const eB=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u",tB=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,Jt=b.forwardRef(function(t,n){let{onClick:r,relative:a,reloadDocument:s,replace:o,state:l,target:c,to:u,preventScrollReset:d,viewTransition:f}=t,h=RT(t,V2),{basename:p}=b.useContext(qa),m,g=!1;if(typeof u=="string"&&tB.test(u)&&(m=u,eB))try{let w=new URL(window.location.href),j=u.startsWith("//")?new URL(w.protocol+u):new URL(u),S=Qo(j.pathname,p);j.origin===w.origin&&S!=null?u=S+j.search+j.hash:g=!0}catch{}let y=C2(u,{relative:a}),v=rB(u,{replace:o,state:l,target:c,preventScrollReset:d,relative:a,viewTransition:f});function k(w){r&&r(w),w.defaultPrevented||v(w)}return b.createElement("a",lh({},h,{href:m||y,onClick:g||s?r:k,ref:n,target:c}))}),oS=b.forwardRef(function(t,n){let{"aria-current":r="page",caseSensitive:a=!1,className:s="",end:o=!1,style:l,to:c,viewTransition:u,children:d}=t,f=RT(t,Y2),h=Dp(c,{relative:f.relative}),p=Li(),m=b.useContext(_T),{navigator:g,basename:y}=b.useContext(qa),v=m!=null&&aB(h)&&u===!0,k=g.encodeLocation?g.encodeLocation(h).pathname:h.pathname,w=p.pathname,j=m&&m.navigation&&m.navigation.location?m.navigation.location.pathname:null;a||(w=w.toLowerCase(),j=j?j.toLowerCase():null,k=k.toLowerCase()),j&&y&&(j=Qo(j,y)||j);const S=k!=="/"&&k.endsWith("/")?k.length-1:k.length;let x=w===k||!o&&w.startsWith(k)&&w.charAt(S)==="/",N=j!=null&&(j===k||!o&&j.startsWith(k)&&j.charAt(k.length)==="/"),E={isActive:x,isPending:N,isTransitioning:v},P=x?r:void 0,_;typeof s=="function"?_=s(E):_=[s,x?"active":null,N?"pending":null,v?"transitioning":null].filter(Boolean).join(" ");let R=typeof l=="function"?l(E):l;return b.createElement(Jt,lh({},f,{"aria-current":P,className:_,ref:n,style:R,to:c,viewTransition:u}),typeof d=="function"?d(E):d)});var gy;(function(e){e.UseScrollRestoration="useScrollRestoration",e.UseSubmit="useSubmit",e.UseSubmitFetcher="useSubmitFetcher",e.UseFetcher="useFetcher",e.useViewTransitionState="useViewTransitionState"})(gy||(gy={}));var lS;(function(e){e.UseFetcher="useFetcher",e.UseFetchers="useFetchers",e.UseScrollRestoration="useScrollRestoration"})(lS||(lS={}));function nB(e){let t=b.useContext($p);return t||_t(!1),t}function rB(e,t){let{target:n,replace:r,state:a,preventScrollReset:s,relative:o,viewTransition:l}=t===void 0?{}:t,c=rw(),u=Li(),d=Dp(e,{relative:o});return b.useCallback(f=>{if(K2(f,n)){f.preventDefault();let h=r!==void 0?r:oh(u)===oh(d);c(e,{replace:h,state:a,preventScrollReset:s,relative:o,viewTransition:l})}},[u,c,d,r,a,n,e,s,o,l])}function aB(e,t){t===void 0&&(t={});let n=b.useContext(Q2);n==null&&_t(!1);let{basename:r}=nB(gy.useViewTransitionState),a=Dp(e,{relative:t.relative});if(!n.isTransitioning)return!1;let s=Qo(n.currentLocation.pathname,r)||n.currentLocation.pathname,o=Qo(n.nextLocation.pathname,r)||n.nextLocation.pathname;return py(a.pathname,o)!=null||py(a.pathname,s)!=null}async function it(e){if(!e.ok)return null;const t=e.headers.get("content-type")||"";if(!t.includes("application/json")&&!t.includes("text/json"))return t.includes("text/html")&&console.warn(`[dashboard] GET ${e.url||"/api/*"} returned HTML (${e.status}) instead of JSON — the dashboard server may be an older version. Stop it and start it again (agent-nuvira dashboard stop, or Ctrl+C in its terminal).`),null;try{return await e.json()}catch{return null}}const Ao="buff-dashboard-admin-token";function MT(){try{if(typeof window<"u"&&window.localStorage)return window.localStorage}catch{}return null}function iB(e){if(!e||typeof e!="object")return!1;const t=e,n=t.diff;return typeof t.dir=="string"&&typeof t.base=="string"&&typeof t.removed=="boolean"&&!!n&&typeof n=="object"&&Array.isArray(n.files)&&n.files.every(r=>typeof r=="string")&&typeof n.summary=="string"&&!!n.payload&&typeof n.payload=="object"&&typeof n.payload.summary=="string"&&Array.isArray(n.payload.files)&&n.payload.files.every(r=>!!r&&typeof r.path=="string"&&typeof r.body=="string")}function sB(e){if(!e||typeof e!="object")return!1;const t=e;return typeof t.id=="string"&&typeof t.replayed=="number"&&typeof t.modelCalls=="number"&&typeof t.saved=="boolean"&&typeof t.notice=="string"&&(t.callsAvoided===void 0||typeof t.callsAvoided=="number")}function oB(e){if(!e||typeof e!="object")return!1;const t=e;return typeof t.goal=="string"&&typeof t.planned=="boolean"&&Array.isArray(t.steps)&&!!t.stepCounts&&typeof t.stepCounts=="object"&&typeof t.stepCounts.total=="number"&&typeof t.verification=="string"&&["verified","unverified","blocked","not-applicable","delivered-and-read-back"].includes(t.verification)&&(t.summary===null||typeof t.summary=="string")&&Array.isArray(t.changedPaths)&&!!t.flags&&typeof t.flags=="object"}const vy=new Map;function lB(){const e=MT();if(e)try{const t=e.getItem(Ao);if(t)return t}catch{}return vy.get(Ao)??null}function cB(e){const t=MT();if(t)try{e?t.setItem(Ao,e):t.removeItem(Ao);return}catch{}e?vy.set(Ao,e):vy.delete(Ao)}function Xt(){return lB()}let yy=0;const by=new Set;function uB(){return yy}function dB(e){return by.add(e),()=>{by.delete(e)}}function fB(){yy+=1;for(const e of by)try{e(yy)}catch{}}function dg(e){cB(e),fB()}function mt(){const e=Xt();return e?{Authorization:`Bearer ${e}`}:{}}class hB{constructor(t=""){ea(this,"sse",null);ea(this,"listeners",new Set);ea(this,"connectionListeners",new Set);ea(this,"dagListeners",new Set);ea(this,"typingListeners",new Set);ea(this,"chatRetryListeners",new Set);ea(this,"reconnectTimer",null);ea(this,"baseUrl");ea(this,"lastData",null);this.baseUrl=t}subscribe(t){return this.listeners.add(t),()=>this.listeners.delete(t)}onConnectionChange(t){return this.connectionListeners.add(t),()=>this.connectionListeners.delete(t)}onDAGEvent(t){return this.dagListeners.add(t),()=>this.dagListeners.delete(t)}onTypingEvent(t){return this.typingListeners.add(t),()=>this.typingListeners.delete(t)}onChatRetryEvent(t){return this.chatRetryListeners.add(t),()=>this.chatRetryListeners.delete(t)}connect(){this.sse||(this.sse=new EventSource(`${this.baseUrl}/api/sse`),this.sse.addEventListener("init",t=>{try{const n=JSON.parse(t.data);this.lastData=n,this.notify(n),this.notifyConnection(!0)}catch(n){console.error("Failed to parse SSE init data:",n)}}),this.sse.addEventListener("refresh",t=>{try{const n=JSON.parse(t.data);this.lastData=n,this.notify(n),this.notifyConnection(!0)}catch(n){console.error("Failed to parse SSE refresh data:",n)}}),this.sse.addEventListener("dag",t=>{try{const n=JSON.parse(t.data);if(this.notifyDAG(n),this.lastData){const r={...this.lastData,dag:n};this.lastData=r,this.notify(r)}}catch(n){console.error("Failed to parse SSE dag event:",n)}}),this.sse.addEventListener("quota",t=>{try{const n=JSON.parse(t.data);if(this.lastData&&n.quota){const r={...this.lastData,routing:{...this.lastData.routing||{},quota:n.quota},serverTime:n.serverTime||this.lastData.serverTime};this.lastData=r,this.notify(r)}}catch(n){console.error("Failed to parse SSE quota event:",n)}}),this.sse.addEventListener("conversation",t=>{try{const n=JSON.parse(t.data);if(this.lastData&&n.conversations){const r={...this.lastData,conversations:{total:n.total??n.conversations.length,recent:n.conversations},serverTime:n.serverTime||this.lastData.serverTime};this.lastData=r,this.notify(r)}}catch(n){console.error("Failed to parse SSE conversation event:",n)}}),this.sse.addEventListener("typing",t=>{try{const n=JSON.parse(t.data);for(const r of this.typingListeners)try{r(n)}catch{}}catch(n){console.error("Failed to parse SSE typing event:",n)}}),this.sse.addEventListener("chat-retry",t=>{try{const n=JSON.parse(t.data);if(!n||typeof n.sessionId!="string"||typeof n.content!="string")return;for(const r of this.chatRetryListeners)try{r(n)}catch{}}catch(n){console.error("Failed to parse SSE chat-retry event:",n)}}),this.sse.onerror=()=>{this.notifyConnection(!1),this.disconnect(),this.reconnect()},this.sse.onopen=()=>{this.notifyConnection(!0)})}disconnect(){this.sse&&(this.sse.close(),this.sse=null),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null)}reconnect(){this.reconnectTimer=setTimeout(()=>{this.connect()},3e3)}notify(t){this.listeners.forEach(n=>n(t))}notifyDAG(t){this.dagListeners.forEach(n=>n(t))}notifyConnection(t){this.connectionListeners.forEach(n=>n(t))}async fetchAll(){try{const t=await fetch(`${this.baseUrl}/api/all`),n=await it(t);return n?(this.lastData=n,n):null}catch{return null}}async fetchExecutionAudit(t){try{const n=new URLSearchParams;t!=null&&t.skillName&&n.set("skillName",t.skillName),t!=null&&t.status&&n.set("status",t.status),t!=null&&t.limit&&n.set("limit",String(t.limit));const r=n.toString(),a=await fetch(`${this.baseUrl}/api/executions${r?`?${r}`:""}`,{signal:AbortSignal.timeout(8e3)}),s=await it(a);return(s==null?void 0:s.entries)??[]}catch{return[]}}async fetchTraces(){try{const t=await fetch(`${this.baseUrl}/api/traces`,{signal:AbortSignal.timeout(8e3)}),n=await it(t);return n!=null&&n.traces?n.traces:null}catch{return null}}async fetchAcceptance(){try{const t=await fetch(`${this.baseUrl}/api/acceptance`,{signal:AbortSignal.timeout(8e3)}),n=await it(t);return!n||typeof n.labelled!="number"?null:n}catch{return null}}acceptanceExportUrl(t="json"){return`${this.baseUrl}/api/acceptance/export?format=${t}`}async importAcceptance(t,n){try{const r=await fetch(`${this.baseUrl}/api/acceptance/import`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({text:t,...n?{format:n}:{}})}),a=await it(r);return!a||typeof a.ok!="boolean"?null:a}catch{return null}}async fetchDecisions(t,n){try{const r=new URLSearchParams;t&&r.set("dir",t),n&&n.trim()&&r.set("for",n.trim());const a=await fetch(`${this.baseUrl}/api/decisions?${r.toString()}`,{signal:AbortSignal.timeout(8e3)}),s=await it(a);return!s||!Array.isArray(s.decisions)?null:s}catch{return null}}async reviseDecision(t,n,r,a){try{const s=await fetch(`${this.baseUrl}/api/decisions/revise`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({dir:t,id:n,answer:r,...a?{note:a}:{}})}),o=await it(s);return!o||o.ok!==!0||!o.decision?null:o.decision}catch{return null}}async fetchGates(){try{const t=await fetch(`${this.baseUrl}/api/gates`,{signal:AbortSignal.timeout(8e3)}),n=await it(t);return!n||typeof n.events!="number"?null:n}catch{return null}}async fetchConsent(){try{const t=await fetch(`${this.baseUrl}/api/consent`,{signal:AbortSignal.timeout(8e3)}),n=await it(t);return!n||n.ok!==!0||!n.picture||!n.picture.denied?null:n.picture}catch{return null}}async fetchCapabilities(){try{const t=await fetch(`${this.baseUrl}/api/capabilities`,{signal:AbortSignal.timeout(8e3)}),n=await it(t);return!n||n.ok!==!0||!Array.isArray(n.verbs)?null:n}catch{return null}}async saveLearnedCommand(t,n,r){try{const a=await fetch(`${this.baseUrl}/api/capabilities/commands`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({verb:t,command:n,...r?{note:r}:{}})}),s=await it(a);return{ok:(s==null?void 0:s.ok)===!0,commands:s==null?void 0:s.commands,error:s==null?void 0:s.error}}catch{return{ok:!1,error:"Could not reach the server."}}}async forgetLearnedCommand(t){try{const n=await fetch(`${this.baseUrl}/api/capabilities/commands/forget`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({verb:t})}),r=await it(n);return{ok:(r==null?void 0:r.ok)===!0,commands:r==null?void 0:r.commands,error:r==null?void 0:r.error}}catch{return{ok:!1,error:"Could not reach the server."}}}async fetchSessionGrants(){try{const t=await fetch(`${this.baseUrl}/api/session-grants`,{signal:AbortSignal.timeout(8e3)}),n=await it(t);return!n||!Array.isArray(n.grants)?null:n.grants}catch{return null}}async revokeSessionGrant(t){try{const n=await fetch(`${this.baseUrl}/api/session-grants/clear`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sessionId:t})}),r=await it(n);return(r==null?void 0:r.ok)===!0}catch{return!1}}async fetchAdminChecks(){try{const t=await fetch(`${this.baseUrl}/api/admin/checks`,{signal:AbortSignal.timeout(15e3)}),n=await it(t);return!n||!Array.isArray(n.system)||!Array.isArray(n.enterprise)||!Array.isArray(n.providers)?null:n}catch{return null}}async fetchHub(){var t;try{const n=await fetch(`${this.baseUrl}/api/hub`,{signal:AbortSignal.timeout(8e3)}),r=await it(n);return!r||!Array.isArray((t=r.toolsets)==null?void 0:t.toolsets)?null:r}catch{return null}}async rateTrace(t,n){try{const r=await fetch(`${this.baseUrl}/api/traces/${encodeURIComponent(t)}/verdict`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({verdict:n}),signal:AbortSignal.timeout(8e3)}),a=await it(r);return a!=null&&a.ok&&a.rated?{traceId:a.rated.traceId,corpusLabeled:!!a.rated.corpusLabeled}:null}catch{return null}}async fetchTraceDetail(t){try{const n=await fetch(`${this.baseUrl}/api/traces/${encodeURIComponent(t)}`,{signal:AbortSignal.timeout(8e3)}),r=await it(n);return r&&Array.isArray(r.steps)?r:null}catch{return null}}async sendAdminRequest(t,n,r){try{const a=Xt(),s=await fetch(`${this.baseUrl}${t}`,{method:n,headers:{"Content-Type":"application/json",...a?{Authorization:`Bearer ${a}`}:{}},body:r!==void 0?JSON.stringify(r):void 0,signal:AbortSignal.timeout(15e3)}),o=s.headers.get("content-type")||"";let l=null;if(o.includes("application/json")||o.includes("text/json"))try{l=await s.json()}catch{l=null}return{status:s.status,data:l}}catch{return null}}async fetchAdminAuthStatus(){const t=await this.sendAdminRequest("/api/admin/auth-status","GET");if(!t||typeof t.data!="object"||t.data===null)return null;const n=t.data;return typeof n.configured!="boolean"||typeof n.authenticated!="boolean"?null:{configured:n.configured,authenticated:n.authenticated,user:typeof n.user=="string"?n.user:null,role:typeof n.role=="string"?n.role:null,mustChangePassword:n.mustChangePassword===!0}}async changeAdminPassword(t,n){const r=await this.sendAdminRequest("/api/admin/change-password","POST",{currentPassword:t,newPassword:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&a.ok?{ok:!0}:{ok:!1,error:a.error||"Could not change the password."}}async fetchAdminUsers(){const t=await this.sendAdminRequest("/api/admin/users","GET");if(!t)return{ok:!1,error:"Could not reach the dashboard server."};const n=t.data??{};return t.status===200&&n.ok&&Array.isArray(n.users)?n:{ok:!1,error:n.error||"Failed to load users.",forbidden:t.status===403,unauthorized:t.status===401}}async addAdminUser(t,n,r){const a=await this.sendAdminRequest("/api/admin/users","POST",{user:t,password:n,role:r});if(!a)return{ok:!1,error:"Could not reach the dashboard server."};const s=a.data??{};return a.status===200&&s.ok?s:{ok:!1,error:s.error||"Failed to add user.",forbidden:a.status===403,unauthorized:a.status===401}}async removeAdminUser(t){const n=await this.sendAdminRequest(`/api/admin/users/${encodeURIComponent(t)}`,"DELETE");if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?r:{ok:!1,error:r.error||"Failed to remove user.",forbidden:n.status===403,unauthorized:n.status===401}}async fetchAdminCatalog(){const t=await this.sendAdminRequest("/api/admin/catalog","GET"),n=t==null?void 0:t.data;return!n||!Array.isArray(n.providers)?null:n.providers}async adminSetup(t,n){const r=await this.sendAdminRequest("/api/admin/setup","POST",{user:t,password:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&typeof a.token=="string"?(dg(a.token),{ok:!0,user:a.user,token:a.token}):{ok:!1,error:a.error||"Setup failed.",unauthorized:r.status===401}}async adminLogin(t,n){const r=await this.sendAdminRequest("/api/admin/login","POST",{user:t,password:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&typeof a.token=="string"?(dg(a.token),{ok:!0,user:a.user,token:a.token}):{ok:!1,error:a.error||"Login failed.",unauthorized:r.status===401}}async adminLogout(){await this.sendAdminRequest("/api/admin/logout","POST"),dg(null)}async shutdown(t){const n=await this.sendAdminRequest("/api/admin/shutdown","POST",{target:t});if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?r:{ok:!1,error:r.error||"Shutdown failed.",unauthorized:n.status===401,forbidden:n.status===403}}async saveProvider(t,n){const r=await this.sendAdminRequest(`/api/admin/providers/${encodeURIComponent(t)}`,"PUT",n);if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&a.ok?a:{ok:!1,error:a.error||"Save failed.",unauthorized:r.status===401}}async deleteProvider(t){const n=await this.sendAdminRequest(`/api/admin/providers/${encodeURIComponent(t)}`,"DELETE");if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?r:{ok:!1,error:r.error||"Remove failed.",unauthorized:n.status===401}}async testProvider(t){const n=await this.sendAdminRequest(`/api/admin/providers/${encodeURIComponent(t)}/test`,"POST");if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200?r:{ok:!1,error:r.error||"Test failed.",unauthorized:n.status===401}}async fetchOmniRouteStatus(){const t=await this.sendAdminRequest("/api/admin/omniroute","GET");if(!t)return null;const n=t.data??{};return t.status!==200||!n.status?null:n.status}async controlOmniRoute(t){const n=await this.sendAdminRequest("/api/admin/omniroute","POST",{action:t});if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200?r:{ok:!1,error:r.error||"OmniRoute control failed.",unauthorized:n.status===401,forbidden:n.status===403}}async fetchAdminWorkspace(){const t=await this.sendAdminRequest("/api/admin/workspace","GET");if(!t)return null;const n=t.data??{};return t.status!==200||n.ok!==!0?null:{configured:typeof n.configured=="string"?n.configured:null,effective:typeof n.effective=="string"?n.effective:null,processCwd:typeof n.processCwd=="string"?n.processCwd:"",configuredValid:n.configuredValid===!0}}async saveAdminWorkspace(t){const n=await this.sendAdminRequest("/api/admin/workspace","PUT",{cwd:t});if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok===!0?{ok:!0,workspace:{configured:typeof r.configured=="string"?r.configured:null,effective:typeof r.effective=="string"?r.effective:null,processCwd:typeof r.processCwd=="string"?r.processCwd:"",configuredValid:r.configuredValid===!0}}:{ok:!1,error:r.error||"Save failed.",unauthorized:n.status===401,forbidden:n.status===403}}async fetchAdminCache(){const t=await this.sendAdminRequest("/api/admin/cache","GET");if(!t)return null;const n=t.data;return!n||n.ok!==!0||!Array.isArray(n.workspaces)?null:n}async clearAdminCache(t){const n=await this.sendAdminRequest("/api/admin/cache/clear","POST",{scope:t});if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?{ok:!0,removed:r.removed??0}:{ok:!1,error:r.error||"Could not clear the cache.",unauthorized:n.status===401,forbidden:n.status===403}}async fetchAdminServices(){const t=await this.sendAdminRequest("/api/admin/services","GET");if(!t)return null;const n=t.data;return!n||n.ok!==!0||!Array.isArray(n.services)?null:n}async saveService(t,n){const r=await this.sendAdminRequest(`/api/admin/services/${encodeURIComponent(t)}`,"PUT",{values:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&a.ok?a:{ok:!1,error:a.error||"Save failed.",unauthorized:r.status===401,forbidden:r.status===403}}async testService(t){const n=await this.sendAdminRequest(`/api/admin/services/${encodeURIComponent(t)}/test`,"POST");if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200?r:{ok:!1,error:r.error||"Test failed."}}async removeService(t){const n=await this.sendAdminRequest(`/api/admin/services/${encodeURIComponent(t)}`,"DELETE");if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?r:{ok:!1,error:r.error||"Remove failed.",unauthorized:n.status===401,forbidden:n.status===403}}async fetchAdminQuota(){const t=await this.sendAdminRequest("/api/admin/quota","GET");if(!t)return null;const n=t.data;return!n||!n.ok||typeof n.quota!="object"?null:n}async setToolsetEnabled(t,n){const r=await this.sendAdminRequest(`/api/admin/hub/toolsets/${encodeURIComponent(t)}`,"PUT",{enabled:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&a.ok?a:{ok:!1,error:a.error||"Toggle failed.",unauthorized:r.status===401,forbidden:r.status===403}}async setSkillEnabled(t,n){const r=await this.sendAdminRequest(`/api/admin/hub/skills/${encodeURIComponent(t)}`,"PUT",{enabled:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&a.ok?a:{ok:!1,error:a.error||"Toggle failed.",unauthorized:r.status===401,forbidden:r.status===403}}async fetchKnowledge(){try{const n=await(await fetch(`${this.baseUrl}/api/knowledge`,{headers:mt(),signal:AbortSignal.timeout(8e3)})).json();return Array.isArray(n.tags)?n.tags:null}catch{return null}}async knowledgeIngest(t,n){try{const r=await fetch(`${this.baseUrl}/api/knowledge/ingest`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({tag:t,paths:n})}),a=await r.json();return r.status===200&&a.ok?{...a,ok:!0}:{ok:!1,error:a.error||"Ingest failed."}}catch(r){return{ok:!1,error:r instanceof Error?r.message:String(r)}}}async knowledgeQuery(t,n,r){try{const a=await fetch(`${this.baseUrl}/api/knowledge/query`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({tag:t,question:n,topK:r})}),s=await a.json();return a.status===200&&s.ok?{...s,ok:!0}:{ok:!1,error:s.error||"Query failed."}}catch(a){return{ok:!1,error:a instanceof Error?a.message:String(a)}}}async knowledgeForget(t){try{const n=await fetch(`${this.baseUrl}/api/knowledge/forget`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({tag:t})}),r=await n.json();return n.status===200&&r.ok?{...r,ok:!0}:{ok:!1,error:r.error||"Forget failed."}}catch(n){return{ok:!1,error:n instanceof Error?n.message:String(n)}}}async marketplaceSearch(t){try{const r=await(await fetch(`${this.baseUrl}/api/skills/marketplace?q=${encodeURIComponent(t)}`,{headers:mt()})).json();return Array.isArray(r.results)?r.results:[]}catch{return[]}}async marketplaceInstall(t){try{const n=await fetch(`${this.baseUrl}/api/skills/marketplace/install`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({name:t})}),r=await n.json();return n.status===200&&r.ok?{ok:!0}:{ok:!1,error:r.error||"Install failed.",quarantined:r.quarantined===!0}}catch(n){return{ok:!1,error:n instanceof Error?n.message:String(n)}}}async marketplaceUninstall(t){try{const n=await fetch(`${this.baseUrl}/api/skills/marketplace/uninstall`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({name:t})}),r=await n.json();return n.status===200&&r.ok?{ok:!0}:{ok:!1,error:r.error||"Uninstall failed."}}catch(n){return{ok:!1,error:n instanceof Error?n.message:String(n)}}}async sendChannelMessage(t,n){const r=await this.sendAdminRequest("/api/admin/hub/channels/send","POST",{target:t,text:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&a.ok?a:{ok:!1,error:a.error||"Send failed.",unauthorized:r.status===401,forbidden:r.status===403}}async gatewayPolicies(){const t=await this.sendAdminRequest("/api/admin/gateway/policies","GET");if(!t)return{ok:!1,error:"Could not reach the dashboard server."};const n=t.data??{};return t.status===200&&n.ok?{ok:!0,policies:n.policies,statusRecipients:n.statusRecipients,contacts:n.contacts,askUserWait:n.askUserWait,askUserTimeoutMs:n.askUserTimeoutMs}:{ok:!1,error:n.error||"Failed to read policies.",unauthorized:t.status===401,forbidden:t.status===403}}async saveGatewayPolicies(t,n,r,a){const s={policies:t};Array.isArray(n)&&(s.statusRecipients=n),Array.isArray(r)&&(s.contacts=r),a&&(s.askUserWait=a.wait,typeof a.timeoutMs=="number"&&(s.askUserTimeoutMs=a.timeoutMs));const o=await this.sendAdminRequest("/api/admin/gateway/policies","PUT",s);if(!o)return{ok:!1,error:"Could not reach the dashboard server."};const l=o.data??{};return o.status===200&&l.ok?l:{ok:!1,error:l.error||"Failed to save policies.",unauthorized:o.status===401,forbidden:o.status===403}}async fetchGatewayConversations(t={}){const n=new URLSearchParams;t.offset&&n.set("offset",String(t.offset)),t.limit&&n.set("limit",String(t.limit)),t.q&&n.set("q",t.q);const r=n.toString(),a=await this.sendAdminRequest(`/api/admin/gateway/conversations${r?`?${r}`:""}`,"GET");if(!a)return{ok:!1,error:"Could not reach the dashboard server."};const s=a.data??{};return a.status===200&&s.ok?{ok:!0,conversations:s.conversations,total:s.total,hasMore:s.hasMore}:{ok:!1,error:s.error||"Failed to load conversations.",unauthorized:a.status===401,forbidden:a.status===403}}async clearGatewayConversation(t){const n=await this.sendAdminRequest("/api/admin/gateway/conversations","DELETE",{key:t});if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?{ok:!0}:{ok:!1,error:r.error||"Failed to clear conversation.",unauthorized:n.status===401,forbidden:n.status===403}}async addConversationTag(t,n){const r=await this.sendAdminRequest("/api/admin/gateway/conversations/tags","PUT",{action:"add",key:t,tag:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&a.ok?{ok:!0}:{ok:!1,error:a.error||"Failed to add tag.",unauthorized:r.status===401,forbidden:r.status===403}}async removeConversationTag(t,n){const r=await this.sendAdminRequest("/api/admin/gateway/conversations/tags","PUT",{action:"remove",key:t,tag:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&a.ok?{ok:!0}:{ok:!1,error:a.error||"Failed to remove tag.",unauthorized:r.status===401,forbidden:r.status===403}}async getAllConversationTags(){const t=await this.sendAdminRequest("/api/admin/gateway/conversations/tags","PUT",{action:"getAllTags"});if(!t)return{ok:!1,error:"Could not reach the dashboard server."};const n=t.data??{};return t.status===200&&n.ok?{ok:!0,tags:n.tags}:{ok:!1,error:n.error||"Failed to load tags.",unauthorized:t.status===401,forbidden:t.status===403}}async exportGatewayConversations(t){var n,r,a;try{const s=Xt(),o=await fetch(`${this.baseUrl}/api/admin/gateway/conversations/export`,{method:"POST",headers:{"Content-Type":"application/json",...s?{Authorization:`Bearer ${s}`}:{}},body:JSON.stringify({keys:t}),signal:AbortSignal.timeout(3e4)});if(o.status===200&&((n=o.headers.get("content-type"))!=null&&n.includes("application/zip"))){const c=await o.blob(),u=URL.createObjectURL(c),d=document.createElement("a");return d.href=u,d.download=((a=(r=o.headers.get("content-disposition"))==null?void 0:r.match(/filename="(.+)"/))==null?void 0:a[1])||"conversations.zip",document.body.appendChild(d),d.click(),document.body.removeChild(d),URL.revokeObjectURL(u),{ok:!0}}return{ok:!1,error:(await o.json().catch(()=>({}))).error||"Export failed."}}catch(s){return{ok:!1,error:s instanceof Error?s.message:String(s)}}}async getContacts(){const t=await this.sendAdminRequest("/api/admin/contacts","GET");if(!t)return{ok:!1,error:"Could not reach the dashboard server."};const n=t.data??{};return t.status===200&&n.ok?{ok:!0,contacts:n.contacts}:{ok:!1,error:n.error||"Failed to read contacts."}}async approveContact(t,n){return this.contactAction("approve",t,n)}async rejectContact(t,n){return this.contactAction("reject",t,n)}async deleteContact(t,n){return this.contactAction("delete",t,n)}async updateContact(t,n,r){const a=await this.sendAdminRequest("/api/admin/contacts","PUT",{action:"update",platform:t,id:n,...r});if(!a)return{ok:!1,error:"Could not reach the dashboard server."};const s=a.data??{};return a.status===200&&s.ok?s:{ok:!1,error:s.error||"Update failed."}}async contactAction(t,n,r){const a=await this.sendAdminRequest("/api/admin/contacts","PUT",{action:t,platform:n,nameOrId:r});if(!a)return{ok:!1,error:"Could not reach the dashboard server."};const s=a.data??{};return a.status===200&&s.ok?s:{ok:!1,error:s.error||`${t} failed.`}}async getPlatformConfigs(){const t=await this.sendAdminRequest("/api/config/platforms","GET");if(!t)return[];const n=t.data??{};return Array.isArray(n.platforms)?n.platforms:[]}async setPlatformConfig(t,n){const r=await this.sendAdminRequest(`/api/config/platforms/${encodeURIComponent(t)}`,"POST",{values:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&a.ok?a:{ok:!1,error:a.error||"Save failed.",unauthorized:r.status===401,forbidden:r.status===403}}async removePlatformConfig(t){const n=await this.sendAdminRequest(`/api/config/platforms/${encodeURIComponent(t)}`,"DELETE");if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?r:{ok:!1,error:r.error||"Remove failed.",unauthorized:n.status===401,forbidden:n.status===403}}async verifyPlatformConfig(t,n){const r=await this.sendAdminRequest(`/api/config/platforms/${encodeURIComponent(t)}/verify`,"POST",{values:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return{ok:a.ok??!1,info:a.info,error:a.error}}async saveAdminQuota(t){const n=await this.sendAdminRequest("/api/admin/quota","PUT",t);if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?r:{ok:!1,error:r.error||"Save failed.",unauthorized:n.status===401}}async getBedrockStatus(){const t=await this.sendAdminRequest("/api/bedrock/status","GET");return!t||t.status!==200?{configured:!1,region:"us-east-1",authMethod:"none",apiKeySet:!1,iamKeySet:!1}:t.data??{}}async setupBedrock(t){const n=await this.sendAdminRequest("/api/bedrock/setup","POST",{envVars:t});if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?{ok:!0,envVarsWritten:r.envVarsWritten}:{ok:!1,error:r.error||"Save failed."}}async probeBedrock(t){const n=await this.sendAdminRequest("/api/bedrock/probe","POST",{region:t});if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?{ok:!0,models:r.models}:{ok:!1,error:r.error||"Probe failed."}}async listTasks(){const t=await this.sendAdminRequest("/api/tasks","GET");if(!t)return null;const n=t.data??{};return{status:t.status,tasks:Array.isArray(n.tasks)?n.tasks:[]}}async startTask(t,n){const r=await this.sendAdminRequest("/api/tasks","POST",{args:t,timeoutMs:n});if(!r)return{ok:!1,error:"Could not reach the dashboard server."};const a=r.data??{};return r.status===200&&a.ok&&a.task?a:{ok:!1,error:a.error||"Start failed.",unauthorized:r.status===401,forbidden:r.status===403}}async getTask(t){const n=await this.sendAdminRequest(`/api/tasks/${encodeURIComponent(t)}`,"GET");if(!n)return null;const r=n.data??{};return{status:n.status,task:r.task??null}}async cancelTask(t){const n=await this.sendAdminRequest(`/api/tasks/${encodeURIComponent(t)}/cancel`,"POST");if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?r:{ok:!1,error:r.error||"Cancel failed.",unauthorized:n.status===401,forbidden:n.status===403}}subscribeTask(t,n){const r=Xt(),a=new EventSource(`${this.baseUrl}/api/tasks/${encodeURIComponent(t)}/events?token=${encodeURIComponent(r??"")}`);return a.addEventListener("log",s=>{var o;try{(o=n.onLog)==null||o.call(n,JSON.parse(s.data))}catch{}}),a.addEventListener("status",s=>{var o;try{const l=JSON.parse(s.data);l.status&&((o=n.onStatus)==null||o.call(n,l.status))}catch{}}),()=>a.close()}async getWhatsAppStatus(){const t=await this.sendAdminRequest("/api/whatsapp","GET");if(!t)return null;const n=t.data??{};return t.status===200&&n.ok&&n.status?{status:n.status,contacts:n.contacts??{}}:null}async startWhatsAppPair(t){const n=await this.sendAdminRequest("/api/whatsapp/pair","POST",{phone:t||void 0});if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?r:{ok:!1,error:r.error||"Pairing failed to start.",unauthorized:n.status===401,forbidden:n.status===403}}async cancelWhatsAppPair(){const t=await this.sendAdminRequest("/api/whatsapp/cancel","POST");if(!t)return{ok:!1,error:"Could not reach the dashboard server."};const n=t.data??{};return t.status===200&&n.ok?n:{ok:!1,error:n.error||"Cancel failed.",unauthorized:t.status===401,forbidden:t.status===403}}async unpairWhatsApp(){const t=await this.sendAdminRequest("/api/whatsapp/unpair","POST");if(!t)return{ok:!1,error:"Could not reach the dashboard server."};const n=t.data??{};return t.status===200&&n.ok?n:{ok:!1,error:n.error||"Unpair failed.",unauthorized:t.status===401,forbidden:t.status===403}}subscribeWhatsApp(t){const n=Xt(),r=new EventSource(`${this.baseUrl}/api/whatsapp/events?token=${encodeURIComponent(n??"")}`);return r.addEventListener("qr",a=>{var s;try{const o=JSON.parse(a.data);o.qr&&((s=t.onQr)==null||s.call(t,o.qr))}catch{}}),r.addEventListener("code",a=>{var s;try{const o=JSON.parse(a.data);o.code&&((s=t.onCode)==null||s.call(t,o.code))}catch{}}),r.addEventListener("status",a=>{var s;try{(s=t.onStatus)==null||s.call(t,JSON.parse(a.data))}catch{}}),()=>r.close()}async chatResolve(t){const n=Xt();try{const r=await fetch(`${this.baseUrl}/api/chat/resolve`,{method:"POST",headers:{"Content-Type":"application/json",...n?{Authorization:`Bearer ${n}`}:{}},body:JSON.stringify({message:t}),signal:AbortSignal.timeout(1e4)}),a=await r.json();return r.status===200&&a.ok&&Array.isArray(a.matches)?{ok:!0,matches:a.matches}:{ok:!1,matches:[],error:typeof a.error=="string"?a.error:"Resolve failed."}}catch{return{ok:!1,matches:[],error:"Could not reach the dashboard server."}}}async listRoutableModels(){const t=Xt();try{const n=await fetch(`${this.baseUrl}/api/chat/routable-models`,{headers:t?{Authorization:`Bearer ${t}`}:{},signal:AbortSignal.timeout(1e4)}),r=await n.json();return n.status===200&&r.ok&&Array.isArray(r.models)?r.models:[]}catch{return[]}}async listProjects(){const t=Xt();try{const n=await fetch(`${this.baseUrl}/api/projects`,{headers:t?{Authorization:`Bearer ${t}`}:{},signal:AbortSignal.timeout(1e4)}),r=await n.json();return n.status===200&&r.ok&&Array.isArray(r.projects)?r.projects:[]}catch{return[]}}async attachProject(t){const n=Xt();try{const r=await fetch(`${this.baseUrl}/api/projects/attach`,{method:"POST",headers:{"Content-Type":"application/json",...n?{Authorization:`Bearer ${n}`}:{}},body:JSON.stringify({path:t}),signal:AbortSignal.timeout(3e4)}),a=await r.json();return r.status===200&&a.ok&&a.project?{ok:!0,project:a.project}:{ok:!1,error:typeof a.error=="string"?a.error:"Attach failed."}}catch{return{ok:!1,error:"Could not reach the dashboard server."}}}async browseDirectories(t,n){const r=Xt();try{const a=new URLSearchParams;t&&a.set("path",t),n!=null&&n.showDrives&&a.set("showDrives","1");const s=a.toString()?`?${a.toString()}`:"",o=await fetch(`${this.baseUrl}/api/browse${s}`,{headers:r?{Authorization:`Bearer ${r}`}:{},signal:AbortSignal.timeout(1e4)}),l=await o.json();return o.status===200&&l.ok&&Array.isArray(l.entries)?{ok:!0,path:l.path??"",entries:l.entries,parent:l.parent??null,isProject:l.isProject??!1,drives:l.drives,breadcrumbs:l.breadcrumbs}:{ok:!1,path:"",entries:[],parent:null,isProject:!1,error:typeof l.error=="string"?l.error:"Browse failed."}}catch{return{ok:!1,path:"",entries:[],parent:null,isProject:!1,error:"Could not reach the dashboard server."}}}async resolveFolder(t,n){const r=Xt();try{const a=await fetch(this.baseUrl+"/api/browse/resolve-folder",{method:"POST",headers:{"Content-Type":"application/json",...r?{Authorization:"Bearer "+r}:{}},body:JSON.stringify({name:t,subPath:n||""}),signal:AbortSignal.timeout(1e4)}),s=await a.json();return a.status===200&&s.ok&&s.path?{ok:!0,path:s.path}:{ok:!1,path:"",error:typeof s.error=="string"?s.error:"Could not resolve folder."}}catch{return{ok:!1,path:"",error:"Could not reach the dashboard server."}}}async listChatSessions(){const t=Xt();try{const n=await fetch(`${this.baseUrl}/api/sessions`,{headers:t?{Authorization:`Bearer ${t}`}:{},signal:AbortSignal.timeout(1e4)}),r=await n.json();return n.status===200&&r.ok&&Array.isArray(r.sessions)?r.sessions:[]}catch{return[]}}async deleteChatSession(t){const n=Xt();try{const r=await fetch(`${this.baseUrl}/api/sessions/${encodeURIComponent(t)}`,{method:"DELETE",headers:n?{Authorization:`Bearer ${n}`}:{},signal:AbortSignal.timeout(1e4)}),a=await r.json();return r.status===200&&a.ok?{ok:!0}:{ok:!1,error:a.error||"Could not delete the session."}}catch{return{ok:!1,error:"Network error — could not delete the session."}}}async renameChatSession(t,n){const r=Xt();try{const a=await fetch(`${this.baseUrl}/api/sessions/${encodeURIComponent(t)}/rename`,{method:"POST",headers:{"Content-Type":"application/json",...r?{Authorization:`Bearer ${r}`}:{}},body:JSON.stringify({title:n}),signal:AbortSignal.timeout(1e4)}),s=await a.json();return a.status===200&&s.ok?{ok:!0}:{ok:!1,error:s.error||"Could not rename the session."}}catch{return{ok:!1,error:"Network error — could not rename the session."}}}async getChatSession(t){const n=Xt();try{const r=await fetch(`${this.baseUrl}/api/sessions/${encodeURIComponent(t)}`,{headers:n?{Authorization:`Bearer ${n}`}:{},signal:AbortSignal.timeout(1e4)}),a=await r.json();return r.status===200&&a.ok&&a.session?a.session:null}catch{return null}}async chatSend(t,n,r,a){const s=Xt();try{const o=await fetch(`${this.baseUrl}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json",...s?{Authorization:`Bearer ${s}`}:{}},body:JSON.stringify({sessionId:t,message:n,provider:r==null?void 0:r.provider,model:r==null?void 0:r.model,...(r==null?void 0:r.strict)===void 0?{}:{strict:r.strict},projectPath:r==null?void 0:r.projectPath,attachments:r==null?void 0:r.attachments,...(r==null?void 0:r.worktree)===void 0?{}:{worktree:r.worktree},...(r==null?void 0:r.keepWorktree)===void 0?{}:{keepWorktree:r.keepWorktree},...(r==null?void 0:r.resume)===void 0?{}:{resume:r.resume}}),signal:a?AbortSignal.any([AbortSignal.timeout(3e5),a]):AbortSignal.timeout(3e5)}),l=await o.json();return o.status===200&&l.ok?{ok:!0,content:typeof l.content=="string"?l.content:"",followups:Array.isArray(l.followups)?l.followups:[],provider:typeof l.provider=="string"?l.provider:null,model:typeof l.model=="string"?l.model:null,...typeof l.routingNotice=="string"&&l.routingNotice?{routingNotice:l.routingNotice}:{},...typeof l.workspaceNotice=="string"&&l.workspaceNotice?{workspaceNotice:l.workspaceNotice}:{},...typeof l.workspacePath=="string"&&l.workspacePath?{workspacePath:l.workspacePath}:{},...typeof l.workspaceSource=="string"&&l.workspaceSource?{workspaceSource:l.workspaceSource}:{},generationFailed:l.generationFailed===!0,retryQueued:l.retryQueued===!0,...l.needsProject===!0?{needsProject:!0}:{},...l.refused===!0?{refused:!0}:{},...iB(l.worktree)?{worktree:l.worktree}:{},...sB(l.resume)?{resume:l.resume}:{},...Array.isArray(l.findings)?{findings:l.findings}:{},...oB(l.turnReport)?{turnReport:l.turnReport}:{}}:{ok:!1,error:typeof l.error=="string"?l.error:"The agent could not answer.",unauthorized:o.status===401,forbidden:o.status===403}}catch(o){const l=o==null?void 0:o.name;return l==="TimeoutError"?{ok:!1,turnStillRunning:!0,error:"The dashboard stopped waiting after 5 minutes — the turn is STILL RUNNING on the server. Its answer will appear here when it lands (nothing was lost — the turn keeps running)."}:l==="AbortError"?{ok:!1,error:"Cancelled."}:{ok:!1,error:"Could not reach the dashboard server."}}}async chatCancel(t){const n=await this.sendAdminRequest("/api/chat/cancel","POST",{sessionId:t});if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?{ok:!0,cancelled:r.cancelled===!0}:{ok:!1,error:r.error||"Cancel failed."}}async chatReset(t){const n=await this.sendAdminRequest("/api/chat/reset","POST",{sessionId:t});if(!n)return{ok:!1,error:"Could not reach the dashboard server."};const r=n.data??{};return n.status===200&&r.ok?{ok:!0}:{ok:!1,error:r.error||"Reset failed."}}async chatSupportBundle(t){var r,a,s;const n=Xt();try{const o=await fetch(`${this.baseUrl}/api/chat/${encodeURIComponent(t)}/support-bundle`,{method:"GET",headers:{...n?{Authorization:`Bearer ${n}`}:{}},signal:AbortSignal.timeout(3e4)});if(o.status===200&&((r=o.headers.get("content-type"))!=null&&r.includes("application/zip"))){const c=await o.blob(),u=URL.createObjectURL(c),d=document.createElement("a");return d.href=u,d.download=((s=(a=o.headers.get("content-disposition"))==null?void 0:a.match(/filename="(.+)"/))==null?void 0:s[1])||"nuvira-support.zip",document.body.appendChild(d),d.click(),document.body.removeChild(d),URL.revokeObjectURL(u),{ok:!0}}return{ok:!1,error:(await o.json().catch(()=>({}))).error||"Could not build the support bundle."}}catch(o){return{ok:!1,error:o instanceof Error?o.message:"Could not reach the dashboard server."}}}subscribeChat(t,n){const r=Xt(),a=new EventSource(`${this.baseUrl}/api/chat/${encodeURIComponent(t)}/events?token=${encodeURIComponent(r??"")}`);return a.addEventListener("progress",s=>{var o;try{const l=JSON.parse(s.data);l.line&&((o=n.onProgress)==null||o.call(n,l.line))}catch{}}),a.addEventListener("status",s=>{var o,l;try{const c=JSON.parse(s.data);c.status&&((o=n.onStatus)==null||o.call(n,c.status)),c.status==="done"&&c.answer&&typeof c.answer.content=="string"&&((l=n.onTurnDone)==null||l.call(n,{content:c.answer.content,followups:Array.isArray(c.answer.followups)?c.answer.followups:[],generationFailed:c.answer.generationFailed===!0,...c.answer.bounded===void 0?{}:{bounded:c.answer.bounded},...c.answer.provider===void 0?{}:{provider:c.answer.provider},...c.answer.model===void 0?{}:{model:c.answer.model}}))}catch{}}),a.addEventListener("token",s=>{var o;try{const l=JSON.parse(s.data);typeof l.text=="string"&&l.text.length>0&&((o=n.onToken)==null||o.call(n,l.text))}catch{}}),a.addEventListener("tool",s=>{var o;try{const l=JSON.parse(s.data);l.tool&&(l.phase==="started"||l.phase==="called")&&((o=n.onTool)==null||o.call(n,{id:l.id||`call_${Math.random().toString(36).slice(2,8)}`,tool:l.tool,phase:l.phase,args:l.args,ok:l.ok,result:l.result,error:l.error,durationMs:l.durationMs}))}catch{}}),a.addEventListener("plan",s=>{var o;try{const l=JSON.parse(s.data);l.goal&&Array.isArray(l.steps)&&((o=n.onPlan)==null||o.call(n,{goal:l.goal,steps:l.steps,revision:l.revision??0}))}catch{}}),a.addEventListener("diff",s=>{var o;try{const l=JSON.parse(s.data);Array.isArray(l.files)&&((o=n.onDiff)==null||o.call(n,{files:l.files,summary:l.summary??""}))}catch{}}),a.addEventListener("finding",s=>{var o;try{const c=JSON.parse(s.data).finding;c&&typeof c.claim=="string"&&(c.verdict==="CONFIRMED"||c.verdict==="PLAUSIBLE")&&((o=n.onFinding)==null||o.call(n,{claim:c.claim,verdict:c.verdict,outcome:typeof c.outcome=="string"?c.outcome:"",evidence:Array.isArray(c.evidence)?c.evidence:[],source:typeof c.source=="string"?c.source:""}))}catch{}}),a.addEventListener("skill_draft",s=>{var o;try{const l=JSON.parse(s.data);l.name&&l.markdown&&((o=n.onSkillDraft)==null||o.call(n,{name:l.name,description:l.description??"",markdown:l.markdown,updatedAt:l.updatedAt??0}))}catch{}}),a.addEventListener("secret_request",s=>{var o;try{const l=JSON.parse(s.data);l.skillName&&Array.isArray(l.missing)&&((o=n.onSecretRequest)==null||o.call(n,{skillName:l.skillName,missing:l.missing,persisted:l.persisted??{}}))}catch{}}),a.addEventListener("execution_result",s=>{var o;try{const l=JSON.parse(s.data);l.skillName&&l.runtime!==void 0&&((o=n.onExecutionResult)==null||o.call(n,{skillName:l.skillName,runtime:l.runtime,success:l.success??!1,durationMs:l.durationMs??0,exitCode:l.exitCode??0,stdout:l.stdout??"",stderr:l.stderr??"",timestamp:l.timestamp??Date.now()}))}catch{}}),a.addEventListener("question",s=>{var o;try{const l=JSON.parse(s.data);l.questionId&&l.question&&((o=n.onQuestion)==null||o.call(n,{questionId:l.questionId,question:l.question,choices:l.choices??[],multiSelect:l.multiSelect===!0}))}catch{}}),()=>a.close()}async chatRespond(t,n,r={}){try{const s=await(await fetch(`${this.baseUrl}/api/chat/${encodeURIComponent(t)}/respond`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({questionId:n,...r})})).json();return{ok:s.ok===!0,error:s.error}}catch(a){return{ok:!1,error:a instanceof Error?a.message:String(a)}}}async skillDraftAccept(t){try{const r=await(await fetch(`${this.baseUrl}/api/skills/drafts/${encodeURIComponent(t)}/accept`,{method:"POST",headers:{...mt()}})).json();return{ok:r.ok===!0,error:r.error}}catch(n){return{ok:!1,error:n instanceof Error?n.message:String(n)}}}async skillDraftReject(t){try{const r=await(await fetch(`${this.baseUrl}/api/skills/drafts/${encodeURIComponent(t)}`,{method:"DELETE",headers:{...mt()}})).json();return{ok:r.ok===!0,error:r.error}}catch(n){return{ok:!1,error:n instanceof Error?n.message:String(n)}}}async saveSecrets(t){try{const r=await(await fetch(`${this.baseUrl}/api/skills/secrets`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({vars:t})})).json();return{ok:r.ok===!0,error:r.error,saved:r.saved,refused:r.refused}}catch(n){return{ok:!1,error:n instanceof Error?n.message:String(n)}}}async fetchSkillEnv(){try{const t=await fetch(`${this.baseUrl}/api/skills/env`,{headers:{...mt()}}),n=await it(t);return(n==null?void 0:n.vars)??[]}catch{return[]}}async deleteSkillEnvVar(t){try{const r=await(await fetch(`${this.baseUrl}/api/skills/env/delete`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({name:t})})).json();return{ok:r.ok===!0,removed:r.removed,error:r.error}}catch(n){return{ok:!1,error:n instanceof Error?n.message:String(n)}}}async testSkillEnvVar(t){try{const r=await(await fetch(`${this.baseUrl}/api/skills/env/test`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({name:t})})).json();return{ok:r.ok===!0,usable:r.usable,detail:r.detail,error:r.error}}catch(n){return{ok:!1,error:n instanceof Error?n.message:String(n)}}}async fetchProcessEnv(){try{const t=await fetch(`${this.baseUrl}/api/process-env`,{headers:{...mt()}}),n=await it(t);return(n==null?void 0:n.vars)??[]}catch{return[]}}async fetchLimits(){try{const t=await fetch(`${this.baseUrl}/api/limits`),n=await it(t);return!n||typeof n.attachmentMaxBytes!="number"||n.attachmentMaxBytes<=0?null:{attachmentMaxBytes:n.attachmentMaxBytes,extractMaxChars:typeof n.extractMaxChars=="number"?n.extractMaxChars:0}}catch{return null}}async fetchContinuity(){try{const t=await fetch(`${this.baseUrl}/api/continuity`,{headers:{...mt()}}),n=await it(t);return!n||n.ok!==!0?null:{sessions:n.sessions??[],recall:n.recall??[],toggles:n.toggles??{sessionStore:!1,sessionRecall:!1}}}catch{return null}}async clearContinuity(t,n,r){try{const s=await(await fetch(`${this.baseUrl}/api/continuity/clear`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({target:t,...n?{id:n}:{},...r?{olderThanMs:r}:{}})})).json();return{ok:s.ok===!0,removed:s.removed,error:s.error}}catch(a){return{ok:!1,error:a instanceof Error?a.message:String(a)}}}async fetchHistory(){try{const t=await fetch(`${this.baseUrl}/api/history`,{headers:{...mt()}});return await it(t)}catch{return null}}async clearHistory(t,n={}){try{const a=await(await fetch(`${this.baseUrl}/api/history/clear`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({target:t,...n.id?{id:n.id}:{},...n.olderThanMs?{olderThanMs:n.olderThanMs}:{}})})).json();return{ok:a.ok===!0,removed:a.removed,error:a.error}}catch(r){return{ok:!1,error:r instanceof Error?r.message:String(r)}}}async fetchVerifyBacklog(){try{const t=await fetch(`${this.baseUrl}/api/models/verify-next`,{headers:{...mt()}});return await it(t)}catch{return null}}async startVerifyBacklog(t){try{const n=await fetch(`${this.baseUrl}/api/models/verify-next`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({count:t})}),r=await it(n);return r?{ok:r.ok===!0,error:r.error,refusal:r.refusal,state:r.state}:{ok:!1,error:"The dashboard server did not respond."}}catch(n){return{ok:!1,error:n instanceof Error?n.message:"Could not start the run."}}}async saveProcessEnvVar(t,n){try{const a=await(await fetch(`${this.baseUrl}/api/process-env`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({name:t,value:n})})).json();return{ok:a.ok===!0,row:a.row,error:a.error,reason:a.reason}}catch(r){return{ok:!1,error:r instanceof Error?r.message:String(r)}}}async deleteProcessEnvVar(t){try{const r=await(await fetch(`${this.baseUrl}/api/process-env/delete`,{method:"POST",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({name:t})})).json();return{ok:r.ok===!0,removed:r.removed,row:r.row,error:r.error}}catch(n){return{ok:!1,error:n instanceof Error?n.message:String(n)}}}async fetchHooks(){try{const t=await fetch(`${this.baseUrl}/api/hooks`,{headers:{...mt()}}),n=await it(t);return!n||!Array.isArray(n.hooks)?null:n}catch{return null}}async saveHooks(t){try{const n=await fetch(`${this.baseUrl}/api/hooks`,{method:"PUT",headers:{"Content-Type":"application/json",...mt()},body:JSON.stringify({hooks:t})}),r=await n.json();return{ok:r.ok===!0,hooks:r.hooks,error:r.error,forbidden:n.status===403}}catch(n){return{ok:!1,error:n instanceof Error?n.message:String(n)}}}}const K=new hB;async function pB(e=!1){const t=await K.sendAdminRequest(`/api/mcp${e?"?deep=1":""}`,"GET");return!t||t.status!==200?null:t.data}async function mB(e){const t=await K.sendAdminRequest("/api/mcp/settings","POST",{patch:e}),n=(t==null?void 0:t.data)??null;return t?n??{ok:t.status===200,error:`Server returned HTTP ${t.status}`}:{ok:!1,error:"Could not reach the dashboard server."}}async function gB(e){const t=await K.sendAdminRequest("/api/mcp/install","POST",e);return t?t.data??{ok:!1,error:`Server returned HTTP ${t.status}`}:{ok:!1,error:"Could not reach the dashboard server."}}async function vB(e){const t=await K.sendAdminRequest("/api/mcp/servers","POST",e);return t?t.data??{ok:!1,error:`Server returned HTTP ${t.status}`}:{ok:!1,error:"Could not reach the dashboard server."}}async function yB(e){const t=await K.sendAdminRequest("/api/mcp/uninstall","POST",{name:e});return t?t.data??{ok:!1,reason:`Server returned HTTP ${t.status}`}:{ok:!1,reason:"Could not reach the dashboard server."}}const du=["enterprise","neutral","pastel","executive","contrast","premium","premium-amoled"],Bp=["light","dark"],aw=[100,112,125,150],ch={enterprise:"Enterprise",neutral:"Neutral",pastel:"Pastel",executive:"Executive",contrast:"High contrast",premium:"Premium","premium-amoled":"Premium AMOLED"},IT="nuvira.dashboard.theme",cS={palette:"enterprise",mode:"dark",a11y:!1,fontScale:100};function Bo(e,t){return e.includes(t)}function bB(){return typeof window>"u"||typeof window.matchMedia!="function"?null:window.matchMedia("(prefers-color-scheme: dark)").matches}function $T(){const e=bB();return e===null?{...cS}:{...cS,mode:e?"dark":"light"}}function LT(){const e=$T();if(typeof localStorage>"u")return e;let t;try{const a=localStorage.getItem(IT);if(!a)return e;t=JSON.parse(a)}catch{return e}if(typeof t!="object"||t===null)return e;const n=t,r=Bo(aw,n.fontScale)?n.fontScale:e.fontScale;return{palette:Bo(du,n.palette)?n.palette:e.palette,mode:Bo(Bp,n.mode)?n.mode:e.mode,a11y:typeof n.a11y=="boolean"?n.a11y:e.a11y,fontScale:r}}function DT(e){if(!(typeof localStorage>"u"))try{localStorage.setItem(IT,JSON.stringify(e))}catch{}}function iw(e,t){const n=typeof document<"u"?document.documentElement:void 0;n&&(n.setAttribute("data-palette",e.palette),n.setAttribute("data-mode",e.mode),n.setAttribute("data-a11y",e.a11y?"on":"off"),n.setAttribute("data-font-scale",String(e.fontScale)),n.style.colorScheme=e.mode)}function xB(e,t){const n={palette:Bo(du,t.palette)?t.palette:e.palette,mode:Bo(Bp,t.mode)?t.mode:e.mode,a11y:t.a11y??e.a11y,fontScale:Bo(aw,t.fontScale)?t.fontScale:e.fontScale};return n.a11y||(n.fontScale=100),n}let pr=LT();const xy=new Set;function BT(){for(const e of xy)e()}function wB(e){return xy.add(e),()=>{xy.delete(e)}}function uS(){return pr}function Hd(e){const t=xB(pr,e);t.palette===pr.palette&&t.mode===pr.mode&&t.a11y===pr.a11y&&t.fontScale===pr.fontScale||(pr=t,iw(pr),DT(pr),BT())}function kB(){pr=$T(),iw(pr),DT(pr),BT()}function SB(){return b.useSyncExternalStore(wB,uS,uS)}const dS={light:"Light",dark:"Dark"},fS={100:"100%",112:"112%",125:"125%",150:"150%"};function jB(){const e=SB(),[t,n]=b.useState(!1),r=b.useRef(null),a=b.useRef(null),s=b.useRef(null),o=b.useId(),l=`${o}-panel`;b.useEffect(()=>{if(!t)return;function u(f){var h;f.key==="Escape"&&(n(!1),(h=r.current)==null||h.focus())}function d(f){var p;const h=f.target;h&&((p=s.current)!=null&&p.contains(h))||n(!1)}return document.addEventListener("keydown",u),document.addEventListener("pointerdown",d),()=>{document.removeEventListener("keydown",u),document.removeEventListener("pointerdown",d)}},[t]),b.useEffect(()=>{var d,f,h;if(!t)return;(h=((d=a.current)==null?void 0:d.querySelector("input:checked"))??((f=a.current)==null?void 0:f.querySelector("input")))==null||h.focus()},[t]);const c=`${ch[e.palette]} palette, ${dS[e.mode].toLowerCase()} mode, text size ${fS[e.fontScale]}`+(e.a11y?", accessibility mode on":"");return i.jsxs("div",{className:"theme-switcher",ref:s,onBlur:u=>{const d=u.relatedTarget;d&&!u.currentTarget.contains(d)&&n(!1)},children:[i.jsxs("button",{type:"button",ref:r,className:"theme-trigger","aria-expanded":t,"aria-controls":t?l:void 0,onClick:()=>n(u=>!u),children:[i.jsx("span",{"aria-hidden":"true",children:"🎨"}),i.jsx("span",{children:"Appearance"})]}),t&&i.jsxs("div",{className:"theme-panel",id:l,ref:a,children:[i.jsxs("fieldset",{className:"theme-group",children:[i.jsx("legend",{className:"theme-group-label",children:"Palette"}),du.map(u=>i.jsxs("label",{className:"theme-option",children:[i.jsx("input",{type:"radio",name:`${o}-palette`,value:u,checked:e.palette===u,onChange:()=>Hd({palette:u})}),i.jsx("span",{className:"theme-swatch","data-swatch":u,"aria-hidden":"true"}),i.jsx("span",{className:"theme-option-label",children:ch[u]})]},u))]}),i.jsxs("fieldset",{className:"theme-group",children:[i.jsx("legend",{className:"theme-group-label",children:"Mode"}),Bp.map(u=>i.jsxs("label",{className:"theme-option",children:[i.jsx("input",{type:"radio",name:`${o}-mode`,value:u,checked:e.mode===u,onChange:()=>Hd({mode:u})}),i.jsx("span",{className:"theme-option-label",children:dS[u]})]},u))]}),i.jsxs("fieldset",{className:"theme-group",children:[i.jsx("legend",{className:"theme-group-label",children:"Text size"}),aw.map(u=>i.jsxs("label",{className:"theme-option",children:[i.jsx("input",{type:"radio",name:`${o}-scale`,value:u,checked:e.fontScale===u,onChange:()=>Hd({fontScale:u,a11y:e.a11y||u!==100})}),i.jsx("span",{className:"theme-option-label",children:fS[u]})]},u)),!e.a11y&&i.jsx("p",{className:"theme-hint",children:"A larger size turns on accessibility mode, which is what defines it."})]}),i.jsxs("div",{className:"theme-group",children:[i.jsxs("label",{className:"theme-switch",children:[i.jsx("input",{type:"checkbox",checked:e.a11y,onChange:u=>Hd({a11y:u.target.checked})}),i.jsx("span",{className:"theme-switch-track","aria-hidden":"true"}),i.jsx("span",{className:"theme-option-label",children:"Accessibility mode"})]}),i.jsx("p",{className:"theme-hint",children:"Larger targets, stronger borders and no motion. Off by default so it never changes the look for anyone who does not need it."})]}),i.jsx("button",{type:"button",className:"theme-reset",onClick:kB,children:"Reset to system default"}),i.jsx("p",{className:"sr-only",role:"status",children:c})]})]})}function NB(){const[e,t]=b.useState(null),[n,r]=b.useState(!1),[a,s]=b.useState(""),[o,l]=b.useState(""),[c,u]=b.useState(!1),[d,f]=b.useState(null),h=b.useRef(null),p=b.useCallback(()=>{K.fetchAdminAuthStatus().then(w=>t(w))},[]);b.useEffect(()=>{p()},[p]),b.useEffect(()=>{if(!n)return;function w(S){h.current&&!h.current.contains(S.target)&&r(!1)}function j(S){S.key==="Escape"&&r(!1)}return document.addEventListener("mousedown",w),document.addEventListener("keydown",j),()=>{document.removeEventListener("mousedown",w),document.removeEventListener("keydown",j)}},[n]);const m=(e==null?void 0:e.authenticated)===!0,g=(e==null?void 0:e.configured)===!0,y=async w=>{w.preventDefault(),u(!0),f(null);const j=g?await K.adminLogin(a,o):await K.adminSetup(a,o);j.ok?(s(""),l(""),r(!1),p()):f(j.error||(g?"Login failed.":"Setup failed.")),u(!1)},v=async()=>{r(!1),await K.adminLogout(),p()},k=e?m?`👤 ${e.user||"account"}${e.role?` · ${e.role}`:""}`:"👤 Sign in":"👤 Account";return i.jsxs("div",{className:"topbar-account",ref:h,children:[i.jsx("button",{type:"button",className:"topbar-action","aria-haspopup":"menu","aria-expanded":n,onClick:()=>r(w=>!w),children:k}),n?i.jsx("div",{className:"topbar-account-menu",role:"menu",children:m?i.jsxs(i.Fragment,{children:[i.jsxs("div",{className:"topbar-account-user",children:[i.jsx("span",{children:(e==null?void 0:e.user)||"account"}),e!=null&&e.role?i.jsx("span",{className:`admin-role-badge admin-role-${e.role}`,children:e.role}):null]}),e!=null&&e.mustChangePassword?i.jsx("p",{className:"topbar-account-hint",children:"Still on the first-run password — change it on the Admin page before writes will work."}):null,i.jsx("button",{type:"button",className:"topbar-account-item",onClick:()=>void v(),children:"🚪 Log out"})]}):i.jsxs("form",{className:"topbar-account-form",onSubmit:y,children:[i.jsx("p",{className:"topbar-account-title",children:g?"Sign in":"Create the first admin"}),i.jsxs("label",{children:[i.jsx("span",{children:"Username"}),i.jsx("input",{type:"text",value:a,onChange:w=>s(w.target.value),autoComplete:"username",placeholder:"admin"})]}),i.jsxs("label",{children:[i.jsx("span",{children:"Password"}),i.jsx("input",{type:"password",value:o,onChange:w=>l(w.target.value),autoComplete:g?"current-password":"new-password",placeholder:"••••••••"})]}),d?i.jsx("div",{className:"admin-error",children:d}):null,i.jsx("button",{type:"submit",className:"admin-refresh-btn",disabled:c||!a||!o,children:c?"⏳ …":g?"🔐 Sign in":"🔐 Create admin"}),g?null:i.jsx("p",{className:"topbar-account-hint",children:"The first user is always an admin."})]})}):null]})}const zT=[{group:"General",items:[{keys:["?"],description:"Show the shortcut cheatsheet"},{keys:["F1"],description:"Open the Help page"},{keys:["Esc"],description:"Close a dialog or panel"},{keys:["g","c"],description:"Go to Chat"},{keys:["g","o"],description:"Go to Overview"},{keys:["g","t"],description:"Go to Tasks"},{keys:["g","m"],description:"Go to Models"},{keys:["g","s"],description:"Go to System"},{keys:["g","h"],description:"Go to Agent Hub"}]},{group:"Navigation",items:[{keys:["/"],description:"Focus the navigation filter"},{keys:["["],description:"Collapse / expand the navigation drawer"}]}],EB={c:"/chat",o:"/overview",t:"/tasks",m:"/models",s:"/system",h:"/hub"};function _B(e){var a;const t=e;if(!t||typeof t.tagName!="string")return!1;if(t.isContentEditable)return!0;const n=(a=t.getAttribute)==null?void 0:a.call(t,"contenteditable");if(n!=null&&n!=="false")return!0;const r=t.tagName.toLowerCase();return r==="input"||r==="textarea"||r==="select"}function CB({open:e,onClose:t}){const n=b.useId(),r=b.useRef(null),a=b.useRef(null);return b.useEffect(()=>{var l;if(!e)return;a.current=document.activeElement;const s=()=>{var c;return Array.from(((c=r.current)==null?void 0:c.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'))??[])};(l=s()[0])==null||l.focus();function o(c){if(c.key==="Escape"){c.stopPropagation(),t();return}if(c.key!=="Tab")return;const u=s();if(u.length===0)return;const d=u[0],f=u[u.length-1];c.shiftKey&&document.activeElement===d?(c.preventDefault(),f.focus()):!c.shiftKey&&document.activeElement===f&&(c.preventDefault(),d.focus())}return document.addEventListener("keydown",o),()=>{var c;document.removeEventListener("keydown",o),(c=a.current)==null||c.focus()}},[e,t]),e?i.jsx("div",{className:"modal-scrim",onClick:t,children:i.jsxs("div",{className:"shortcuts-dialog",role:"dialog","aria-modal":"true","aria-labelledby":n,ref:r,onClick:s=>s.stopPropagation(),children:[i.jsxs("div",{className:"shortcuts-head",children:[i.jsx("h2",{className:"shortcuts-title",id:n,children:"⌨️ Keyboard shortcuts"}),i.jsx("button",{type:"button",className:"btn-secondary",onClick:t,"aria-label":"Close keyboard shortcuts",children:"✕ Close"})]}),zT.map(s=>i.jsxs("section",{className:"shortcuts-group",children:[i.jsx("h3",{className:"shortcuts-group-title",children:s.group}),i.jsx("dl",{className:"shortcuts-list",children:s.items.map(o=>i.jsxs("div",{className:"shortcuts-row",children:[i.jsx("dt",{className:"shortcuts-keys",children:o.keys.map(l=>i.jsx("kbd",{className:"shortcuts-key",children:l},l))}),i.jsx("dd",{className:"shortcuts-description",children:o.description})]},o.description))})]},s.group)),i.jsxs("p",{className:"shortcuts-note",children:["Shortcuts are ignored while you are typing, so ",i.jsx("kbd",{className:"shortcuts-key",children:"?"})," in a question stays a question mark."]})]})}):null}const FT=[{path:"/overview",label:"Overview",icon:"📊"},{path:"/tasks",label:"Tasks",icon:"🚀"},{path:"/models",label:"Models",icon:"🧠"},{path:"/system",label:"System",icon:"⚙️"},{path:"/help",label:"Help",icon:"❓"}],wy=[{label:"Agent Management",items:[{path:"/chat",label:"Chat",icon:"💬"},{path:"/hub",label:"Agent Hub",icon:"🧰"},{path:"/capabilities",label:"Capabilities",icon:"📋"},{path:"/dag",label:"Execution",icon:"🔀"},{path:"/routing",label:"Routing",icon:"🤖"},{path:"/requests",label:"Requests",icon:"📨"},{path:"/hooks",label:"Hooks",icon:"🪝"}]},{label:"Analysis & Monitoring",items:[{path:"/traces",label:"Traces",icon:"🔍"},{path:"/evals",label:"Evals",icon:"🏆"},{path:"/benchmarks",label:"Benchmarks",icon:"📈"},{path:"/costs",label:"Costs",icon:"💰"}]},{label:"Resources",items:[{path:"/memory",label:"Memory",icon:"💾"},{path:"/knowledge",label:"Knowledge",icon:"📚"},{path:"/history",label:"History",icon:"📝"},{path:"/decisions",label:"Decisions",icon:"🧭"},{path:"/env",label:"Env Config",icon:"🔐"},{path:"/process-env",label:"Process Env",icon:"🌱"}]},{label:"Integrations",items:[{path:"/platforms",label:"Platforms",icon:"🌐"},{path:"/mcp",label:"MCP",icon:"🔌"},{path:"/gateway",label:"Gateway",icon:"📡"},{path:"/contacts",label:"Contacts",icon:"📇"},{path:"/bedrock",label:"Bedrock",icon:"🪨"}]},{label:"Runtime",items:[{path:"/models/timeline",label:"Timeline",icon:"📅"},{path:"/executions",label:"Executions",icon:"📜"},{path:"/admin",label:"Admin",icon:"🛠️"}]}];function AB(e){const t=e.trim().toLowerCase();return t?wy.map(n=>n.label.toLowerCase().includes(t)?n:{...n,items:n.items.filter(r=>r.label.toLowerCase().includes(t))}).filter(n=>n.items.length>0):wy}function TB({children:e,connected:t,lastUpdated:n,onRefresh:r,refreshing:a=!1}){const[s,o]=b.useState(!1),[l,c]=b.useState(""),[u,d]=b.useState(!1),f=b.useRef(null),h=b.useRef(null),p=b.useRef(0),m=b.useId(),g=Li(),y=rw(),v=t?"connected":"reconnecting",k=t?"Connected":"Reconnecting...",w=AB(l),j=()=>o(!1);return b.useEffect(()=>{function S(x){var N,E;if(!(x.metaKey||x.ctrlKey||x.altKey)&&!_B(x.target)){if(x.key==="Escape"){if(u)return;s&&(o(!1),(N=f.current)==null||N.focus());return}if(x.key==="?"){x.preventDefault(),d(!0);return}if(x.key==="F1"){x.preventDefault(),y("/help");return}if(x.key==="/"){x.preventDefault(),(E=h.current)==null||E.focus();return}if(x.key==="["){x.preventDefault(),o(P=>!P);return}if(x.key==="g"){p.current=Date.now();return}if(Date.now()-p.current<1500){const P=EB[x.key.toLowerCase()];p.current=0,P&&(x.preventDefault(),y(P))}}}return document.addEventListener("keydown",S),()=>document.removeEventListener("keydown",S)},[s,u,y]),b.useEffect(()=>{var S;s&&((S=h.current)==null||S.focus())},[s]),b.useEffect(()=>{j()},[g.pathname]),i.jsxs("div",{className:"layout",children:[i.jsxs("header",{className:"topbar",children:[i.jsx("button",{type:"button",ref:f,className:"topbar-menu","aria-label":"Toggle navigation","aria-controls":"app-nav","aria-expanded":s,onClick:()=>o(S=>!S),children:i.jsx("span",{"aria-hidden":"true",children:"☰"})}),i.jsxs("div",{className:"topbar-brand",children:[i.jsx("span",{className:"topbar-logo","aria-hidden":"true",children:"🤖"}),i.jsx("span",{className:"topbar-title",children:"Agent-Nuvira"})]}),i.jsx("nav",{className:"primary-nav","aria-label":"Primary",children:FT.map(S=>i.jsxs(oS,{to:S.path,end:!0,className:({isActive:x})=>`primary-link${x?" active":""}`,children:[i.jsx("span",{"aria-hidden":"true",children:S.icon})," ",S.label]},S.path))}),i.jsxs("div",{className:"topbar-actions",children:[i.jsxs("button",{type:"button",className:"topbar-action",onClick:r,disabled:a,"aria-busy":a,children:[i.jsx("span",{"aria-hidden":"true",children:"⟳"})," ",a?"Refreshing…":"Refresh"]}),i.jsxs("button",{type:"button",className:"topbar-action","aria-haspopup":"dialog","aria-expanded":u,onClick:()=>d(!0),children:[i.jsx("span",{"aria-hidden":"true",children:"⌨️"})," Shortcuts"]}),i.jsx(jB,{}),i.jsxs("a",{className:"topbar-action",href:"https://www.agent-nuvira.com",target:"_blank",rel:"noopener noreferrer",title:"Agent-Nuvira website — capabilities, commands, docs, setup",children:[i.jsx("span",{"aria-hidden":"true",children:"🌐"})," Website"]}),i.jsx(NB,{})]})]}),i.jsxs("div",{className:"layout-body",children:[s&&i.jsx("div",{className:"nav-scrim",onClick:j,"aria-hidden":"true"}),i.jsxs("nav",{className:`nav${s?" open":""}`,id:"app-nav","aria-label":"Sections",children:[i.jsxs("div",{className:"nav-search",children:[i.jsx("label",{className:"sr-only",htmlFor:m,children:"Filter navigation"}),i.jsx("input",{id:m,ref:h,type:"search",className:"nav-search-input",placeholder:"Search",value:l,onChange:S=>c(S.target.value)})]}),i.jsxs("div",{className:"nav-links",children:[w.map(S=>i.jsxs("section",{className:"nav-group",children:[i.jsx("h2",{className:"nav-group-title",children:S.label}),S.items.map(x=>i.jsxs(oS,{to:x.path,end:x.path==="/",className:({isActive:N})=>`nav-link${N?" active":""}`,children:[i.jsx("span",{className:"nav-icon","aria-hidden":"true",children:x.icon}),x.label]},x.path))]},S.label)),w.length===0&&i.jsxs("p",{className:"nav-empty",children:["No sections match “",l,"”."]})]}),i.jsxs("div",{className:"nav-footer",children:[i.jsx("span",{className:`status-dot ${v}`}),i.jsx("span",{className:"status-text",children:k}),i.jsx("span",{className:"last-updated",children:n})]})]}),i.jsx("main",{className:"main",children:e})]}),i.jsx(CB,{open:u,onClose:()=>d(!1)})]})}function UT(e){var t,n,r="";if(typeof e=="string"||typeof e=="number")r+=e;else if(typeof e=="object")if(Array.isArray(e)){var a=e.length;for(t=0;t<a;t++)e[t]&&(n=UT(e[t]))&&(r&&(r+=" "),r+=n)}else for(n in e)e[n]&&(r&&(r+=" "),r+=n);return r}function Ye(){for(var e,t,n=0,r="",a=arguments.length;n<a;n++)(e=arguments[n])&&(t=UT(e))&&(r&&(r+=" "),r+=t);return r}var OB=Array.isArray,Wn=OB,PB=typeof fi=="object"&&fi&&fi.Object===Object&&fi,WT=PB,RB=WT,MB=typeof self=="object"&&self&&self.Object===Object&&self,IB=RB||MB||Function("return this")(),ga=IB,$B=ga,LB=$B.Symbol,rd=LB,hS=rd,HT=Object.prototype,DB=HT.hasOwnProperty,BB=HT.toString,lc=hS?hS.toStringTag:void 0;function zB(e){var t=DB.call(e,lc),n=e[lc];try{e[lc]=void 0;var r=!0}catch{}var a=BB.call(e);return r&&(t?e[lc]=n:delete e[lc]),a}var FB=zB,UB=Object.prototype,WB=UB.toString;function HB(e){return WB.call(e)}var GB=HB,pS=rd,qB=FB,KB=GB,VB="[object Null]",YB="[object Undefined]",mS=pS?pS.toStringTag:void 0;function XB(e){return e==null?e===void 0?YB:VB:mS&&mS in Object(e)?qB(e):KB(e)}var Ka=XB;function QB(e){return e!=null&&typeof e=="object"}var Va=QB,ZB=Ka,JB=Va,ez="[object Symbol]";function tz(e){return typeof e=="symbol"||JB(e)&&ZB(e)==ez}var El=tz,nz=Wn,rz=El,az=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,iz=/^\w*$/;function sz(e,t){if(nz(e))return!1;var n=typeof e;return n=="number"||n=="symbol"||n=="boolean"||e==null||rz(e)?!0:iz.test(e)||!az.test(e)||t!=null&&e in Object(t)}var sw=sz;function oz(e){var t=typeof e;return e!=null&&(t=="object"||t=="function")}var Di=oz;const _l=Je(Di);var lz=Ka,cz=Di,uz="[object AsyncFunction]",dz="[object Function]",fz="[object GeneratorFunction]",hz="[object Proxy]";function pz(e){if(!cz(e))return!1;var t=lz(e);return t==dz||t==fz||t==uz||t==hz}var ow=pz;const Be=Je(ow);var mz=ga,gz=mz["__core-js_shared__"],vz=gz,fg=vz,gS=function(){var e=/[^.]+$/.exec(fg&&fg.keys&&fg.keys.IE_PROTO||"");return e?"Symbol(src)_1."+e:""}();function yz(e){return!!gS&&gS in e}var bz=yz,xz=Function.prototype,wz=xz.toString;function kz(e){if(e!=null){try{return wz.call(e)}catch{}try{return e+""}catch{}}return""}var GT=kz,Sz=ow,jz=bz,Nz=Di,Ez=GT,_z=/[\\^$.*+?()[\]{}|]/g,Cz=/^\[object .+?Constructor\]$/,Az=Function.prototype,Tz=Object.prototype,Oz=Az.toString,Pz=Tz.hasOwnProperty,Rz=RegExp("^"+Oz.call(Pz).replace(_z,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function Mz(e){if(!Nz(e)||jz(e))return!1;var t=Sz(e)?Rz:Cz;return t.test(Ez(e))}var Iz=Mz;function $z(e,t){return e==null?void 0:e[t]}var Lz=$z,Dz=Iz,Bz=Lz;function zz(e,t){var n=Bz(e,t);return Dz(n)?n:void 0}var Ws=zz,Fz=Ws,Uz=Fz(Object,"create"),zp=Uz,vS=zp;function Wz(){this.__data__=vS?vS(null):{},this.size=0}var Hz=Wz;function Gz(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=t?1:0,t}var qz=Gz,Kz=zp,Vz="__lodash_hash_undefined__",Yz=Object.prototype,Xz=Yz.hasOwnProperty;function Qz(e){var t=this.__data__;if(Kz){var n=t[e];return n===Vz?void 0:n}return Xz.call(t,e)?t[e]:void 0}var Zz=Qz,Jz=zp,eF=Object.prototype,tF=eF.hasOwnProperty;function nF(e){var t=this.__data__;return Jz?t[e]!==void 0:tF.call(t,e)}var rF=nF,aF=zp,iF="__lodash_hash_undefined__";function sF(e,t){var n=this.__data__;return this.size+=this.has(e)?0:1,n[e]=aF&&t===void 0?iF:t,this}var oF=sF,lF=Hz,cF=qz,uF=Zz,dF=rF,fF=oF;function Cl(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}Cl.prototype.clear=lF;Cl.prototype.delete=cF;Cl.prototype.get=uF;Cl.prototype.has=dF;Cl.prototype.set=fF;var hF=Cl;function pF(){this.__data__=[],this.size=0}var mF=pF;function gF(e,t){return e===t||e!==e&&t!==t}var lw=gF,vF=lw;function yF(e,t){for(var n=e.length;n--;)if(vF(e[n][0],t))return n;return-1}var Fp=yF,bF=Fp,xF=Array.prototype,wF=xF.splice;function kF(e){var t=this.__data__,n=bF(t,e);if(n<0)return!1;var r=t.length-1;return n==r?t.pop():wF.call(t,n,1),--this.size,!0}var SF=kF,jF=Fp;function NF(e){var t=this.__data__,n=jF(t,e);return n<0?void 0:t[n][1]}var EF=NF,_F=Fp;function CF(e){return _F(this.__data__,e)>-1}var AF=CF,TF=Fp;function OF(e,t){var n=this.__data__,r=TF(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this}var PF=OF,RF=mF,MF=SF,IF=EF,$F=AF,LF=PF;function Al(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}Al.prototype.clear=RF;Al.prototype.delete=MF;Al.prototype.get=IF;Al.prototype.has=$F;Al.prototype.set=LF;var Up=Al,DF=Ws,BF=ga,zF=DF(BF,"Map"),cw=zF,yS=hF,FF=Up,UF=cw;function WF(){this.size=0,this.__data__={hash:new yS,map:new(UF||FF),string:new yS}}var HF=WF;function GF(e){var t=typeof e;return t=="string"||t=="number"||t=="symbol"||t=="boolean"?e!=="__proto__":e===null}var qF=GF,KF=qF;function VF(e,t){var n=e.__data__;return KF(t)?n[typeof t=="string"?"string":"hash"]:n.map}var Wp=VF,YF=Wp;function XF(e){var t=YF(this,e).delete(e);return this.size-=t?1:0,t}var QF=XF,ZF=Wp;function JF(e){return ZF(this,e).get(e)}var eU=JF,tU=Wp;function nU(e){return tU(this,e).has(e)}var rU=nU,aU=Wp;function iU(e,t){var n=aU(this,e),r=n.size;return n.set(e,t),this.size+=n.size==r?0:1,this}var sU=iU,oU=HF,lU=QF,cU=eU,uU=rU,dU=sU;function Tl(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}Tl.prototype.clear=oU;Tl.prototype.delete=lU;Tl.prototype.get=cU;Tl.prototype.has=uU;Tl.prototype.set=dU;var uw=Tl,qT=uw,fU="Expected a function";function dw(e,t){if(typeof e!="function"||t!=null&&typeof t!="function")throw new TypeError(fU);var n=function(){var r=arguments,a=t?t.apply(this,r):r[0],s=n.cache;if(s.has(a))return s.get(a);var o=e.apply(this,r);return n.cache=s.set(a,o)||s,o};return n.cache=new(dw.Cache||qT),n}dw.Cache=qT;var KT=dw;const hU=Je(KT);var pU=KT,mU=500;function gU(e){var t=pU(e,function(r){return n.size===mU&&n.clear(),r}),n=t.cache;return t}var vU=gU,yU=vU,bU=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,xU=/\\(\\)?/g,wU=yU(function(e){var t=[];return e.charCodeAt(0)===46&&t.push(""),e.replace(bU,function(n,r,a,s){t.push(a?s.replace(xU,"$1"):r||n)}),t}),kU=wU;function SU(e,t){for(var n=-1,r=e==null?0:e.length,a=Array(r);++n<r;)a[n]=t(e[n],n,e);return a}var fw=SU,bS=rd,jU=fw,NU=Wn,EU=El,xS=bS?bS.prototype:void 0,wS=xS?xS.toString:void 0;function VT(e){if(typeof e=="string")return e;if(NU(e))return jU(e,VT)+"";if(EU(e))return wS?wS.call(e):"";var t=e+"";return t=="0"&&1/e==-1/0?"-0":t}var _U=VT,CU=_U;function AU(e){return e==null?"":CU(e)}var YT=AU,TU=Wn,OU=sw,PU=kU,RU=YT;function MU(e,t){return TU(e)?e:OU(e,t)?[e]:PU(RU(e))}var XT=MU,IU=El;function $U(e){if(typeof e=="string"||IU(e))return e;var t=e+"";return t=="0"&&1/e==-1/0?"-0":t}var Hp=$U,LU=XT,DU=Hp;function BU(e,t){t=LU(t,e);for(var n=0,r=t.length;e!=null&&n<r;)e=e[DU(t[n++])];return n&&n==r?e:void 0}var hw=BU,zU=hw;function FU(e,t,n){var r=e==null?void 0:zU(e,t);return r===void 0?n:r}var QT=FU;const wr=Je(QT);function UU(e){return e==null}var WU=UU;const Xe=Je(WU);var HU=Ka,GU=Wn,qU=Va,KU="[object String]";function VU(e){return typeof e=="string"||!GU(e)&&qU(e)&&HU(e)==KU}var YU=VU;const Is=Je(YU);var ZT={exports:{}},rt={};/**
68
68
  * @license React
69
69
  * react-is.production.min.js
70
70
  *
@@ -202,7 +202,7 @@ ${r}`);return n&&t.push(n),t}function Bye(e){return/(^|\n)\s*(PASS|FAIL|✅|❌|
202
202
  `),n=[],r=new Set;for(let a=0;a<t.length;a+=1){const s=t[a];let o=s.match(Y_);!o&&a+1<t.length&&/deploy(?:ed|ment|ing)?:\s*$/i.test(s.trim())&&(o=t[a+1].match(Y_));const l=s.match(V_)||(a+1<t.length?t[a+1].match(V_):null);if(!o||!l)continue;const c=Uye(l[0]);r.has(c)||(r.add(c),n.push({url:c,title:s.trim().slice(0,80)||"Deployment"}))}return n}function wf(e){const t=[],n=[],r=[];K_.lastIndex=0;let a;for(;(a=K_.exec(e))!==null;){const s=(a[1]||"").toLowerCase(),o=a[2];if(s==="diff"||o.includes("diff --git ")){const l=Dye(o);l.length>0&&t.push({files:l,summary:`${l.length} file${l.length===1?"":"s"} changed`})}else Bye(o)&&n.push({verdict:zye(o),title:Fye(o),body:o})}for(const s of Wye(e))r.push(s);return{diffs:t,results:n,deploys:r}}const Hye=3e5,Gye=3e3,qye=10,Kye=5e3,Vye=2e3,Yye=/\.(pdf|docx|xlsx|pptx)$/i,Xye=/\.(png|jpe?g|gif|webp|bmp|tiff?)$/i,Qye=/\.(txt|md|markdown|text|log|csv|tsv|json|xml|yaml|yml|html?|htaccess|css|js|mjs|cjs|jsx|ts|tsx|py|rb|go|rs|java|kt|c|h|cpp|cs|php|sh|bash|zsh|sql|ini|toml|cfg|conf|env)$/i;function Zye(e){let t="";for(let r=0;r<e.length;r+=32768)t+=String.fromCharCode(...e.subarray(r,r+32768));return btoa(t)}function Jye(e,t){const n=t.includes(0),r=t.length===0?1:t.reduce((a,s)=>s===9||s===10||s===13||s>=32&&s<127||s>=128?a+1:a,0)/t.length;return!n&&r>.9?{how:"text"}:Yye.test(e)?{how:"binary"}:Qye.test(e)?{how:"text"}:Xye.test(e)?{how:"unsupported",reason:`"${e}" is an image, and this composer only sends text and documents. Save it into the project folder and ask me to describe it — I can read images from there.`}:{how:"unsupported",reason:`"${e}" is not a text file and not a document type I can read. Attach a PDF, DOCX, XLSX, PPTX, or a text/CSV/JSON/Markdown file — or put the file in the project folder and ask me to read it.`}}function ebe(e){const t=["pending","running","done","blocked"].includes(e.status),n=typeof e.note=="string"&&e.note.trim()?e.note.trim():void 0;return{id:e.id,description:e.description,status:t?e.status:"pending",...n?{note:n}:{}}}function tbe(e){return e==="read_file"||e==="glob"||e==="list_dir"?"📖":e==="edit_file"||e==="write_file"?"✏️":e==="run_terminal"||e==="run_cli"?"⚙️":e==="web_search"||e==="read_page"?"🌐":e==="delegate"||e==="spawn_subagents"?"👥":e==="ask_user"?"🤔":"🔧"}function nbe(e){const t=String(e??"").trim().toLowerCase();return t==="max"||t==="maximum"||t==="unlimited"||t==="performance"||t==="performance-first"?"max":"balanced"}function Cc({diff:e,selectable:t=!1,onCommitAccepted:n,lockedHint:r}){const[a,s]=b.useState(null),o=new Set(a??e.files.map(d=>d.path)),l=d=>{s(f=>{const h=f??e.files.map(p=>p.path);return h.includes(d)?h.filter(p=>p!==d):[...h,d]})},c=e.files.reduce((d,f)=>{var h;return d+(((h=f.body.match(/^\+/gm))==null?void 0:h.length)??0)},0),u=e.files.reduce((d,f)=>{var h;return d+(((h=f.body.match(/^-/gm))==null?void 0:h.length)??0)},0);return i.jsxs("div",{className:"chat-diff-card",children:[i.jsxs("div",{className:"chat-diff-head",children:[i.jsx("span",{className:"chat-diff-icon",children:"🔧"}),i.jsx("span",{className:"chat-diff-title",children:"git diff"}),i.jsxs("span",{className:"chat-diff-meta",children:[e.files.length," file",e.files.length===1?"":"s"," · +",c," −",u]})]}),i.jsx("div",{className:"chat-diff-files",children:e.files.map(d=>{const f=o.has(d.path);return i.jsxs("details",{className:`chat-diff-file${f?"":" chat-diff-file-rejected"}`,open:e.files.length===1,children:[i.jsxs("summary",{className:"chat-diff-file-path",children:[t?i.jsx("button",{type:"button",className:`chat-diff-toggle${f?" chat-diff-toggle-on":""}`,title:f?"Accepted — click to reject":"Rejected — click to accept",onClick:h=>{h.preventDefault(),h.stopPropagation(),l(d.path)},children:f?"✓":"✗"}):null,d.path]}),i.jsx("pre",{className:"chat-diff-body",children:d.body.split(`
203
203
  `).map((h,p)=>{const m=h.startsWith("+")?"diff-add":h.startsWith("-")?"diff-del":h.startsWith("@@")?"diff-hunk":"";return i.jsx("div",{className:`chat-diff-line ${m}`,children:h||" "},p)})})]},d.path)})}),t&&n?i.jsxs("div",{className:"chat-diff-actions",children:[i.jsxs("button",{className:"admin-refresh-btn",type:"button",disabled:o.size===0,onClick:()=>n([...o]),children:["Commit accepted (",o.size,")"]}),i.jsx("span",{className:"admin-hint",children:"Only accepted files are committed — the agent re-confirms with a question card."})]}):r?i.jsx("div",{className:"chat-diff-actions",children:i.jsxs("span",{className:"admin-hint chat-diff-locked",children:["🔒 ",r]})}):null]})}function w$({text:e,label:t}){const[n,r]=b.useState(!1),a=async()=>{var s;try{await((s=navigator.clipboard)==null?void 0:s.writeText(e)),r(!0),setTimeout(()=>r(!1),1500)}catch{}};return i.jsx("button",{type:"button",className:"chat-card-copy",title:`Copy ${t}`,onClick:()=>void a(),children:n?"✓ Copied":"⧉ Copy"})}function rbe({result:e}){const t=e.verdict==="pass"?"✅":e.verdict==="fail"?"❌":"📋";return i.jsxs("div",{className:`chat-result-card chat-result-${e.verdict}`,children:[i.jsxs("div",{className:"chat-result-head",children:[i.jsx("span",{className:"chat-result-icon",children:t}),i.jsx("span",{className:"chat-result-title",children:e.title}),i.jsx("span",{className:"chat-result-meta",children:e.verdict}),i.jsx(w$,{text:e.body,label:"result output"})]}),i.jsx("pre",{className:"chat-result-body",children:e.body})]})}function abe({deploy:e}){return i.jsxs("div",{className:"chat-deploy-card",children:[i.jsxs("div",{className:"chat-deploy-head",children:[i.jsx("span",{className:"chat-deploy-icon",children:"🚀"}),i.jsx("span",{className:"chat-deploy-title",children:e.title||"Deployment"}),i.jsx(w$,{text:e.url,label:"deployment URL"})]}),i.jsx("a",{className:"chat-deploy-url",href:e.url,target:"_blank",rel:"noopener noreferrer",children:e.url})]})}function ibe({children:e}){const t=b.useRef(null),n=r=>{if(!t.current)return;const a=Array.from(t.current.querySelectorAll("[data-artifact-card]"));if(a.length===0)return;const s=a.indexOf(document.activeElement);let o=-1;r.key==="ArrowDown"?o=s+1>=a.length?0:s+1:r.key==="ArrowUp"?o=s-1<0?a.length-1:s-1:r.key==="Home"?o=0:r.key==="End"&&(o=a.length-1),o>=0&&o!==s&&(r.preventDefault(),a[o].focus())};return i.jsx("div",{className:"chat-artifacts",ref:t,role:"group","aria-label":"Artifacts",onKeyDown:n,children:e})}function X_({draft:e,onAccept:t,onReject:n,onEdit:r}){const a=e.status??"pending",s=e.markdown.split(`
204
204
  `),o=s.findIndex(c=>c.startsWith("# "))>=0?s.findIndex(c=>c.startsWith("# ")):0,l=s.slice(o,o+14).join(`
205
- `);return i.jsxs("div",{className:`chat-draft-card${a==="saved"?" chat-draft-saved":""}${a==="rejected"?" chat-draft-rejected":""}`,children:[i.jsxs("div",{className:"chat-draft-head",children:[i.jsx("span",{className:"chat-draft-icon",children:"🧠"}),i.jsxs("span",{className:"chat-draft-title",children:["New skill draft: ",e.name]}),i.jsx("span",{className:"chat-draft-meta",children:"pending your review"})]}),i.jsx("p",{className:"chat-draft-desc",children:e.description}),i.jsx("pre",{className:"chat-draft-body",children:l}),a==="saving"?i.jsx("div",{className:"admin-hint",children:"Saving…"}):a==="saved"?i.jsx("div",{className:"admin-hint",children:"✅ Saved — the skill is live: load it in chat or see it in the Agent Hub Skills tab."}):a==="rejected"?i.jsx("div",{className:"admin-hint",children:"🗑️ Rejected — the draft was discarded, nothing was saved."}):i.jsxs("div",{className:"chat-draft-actions",children:[i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:()=>t(e.name),children:"✅ Accept"}),i.jsx("button",{className:"admin-mini-btn",type:"button",onClick:()=>r(e.name),children:"✏️ Edit"}),i.jsx("button",{className:"admin-mini-btn",type:"button",onClick:()=>n(e.name),children:"↩ Reject"})]})]})}function sbe({request:e,onSave:t}){const[n,r]=b.useState({}),[a,s]=b.useState(!1),o=e.missing.every(u=>{var d;return(d=n[u])==null?void 0:d.trim()}),l=e.missing.filter(u=>e.persisted[u]),c=e.missing.filter(u=>!e.persisted[u]);return i.jsxs("div",{className:"chat-secret-card",children:[i.jsxs("div",{className:"chat-secret-head",children:[i.jsx("span",{className:"chat-secret-icon",children:"🔐"}),i.jsxs("span",{className:"chat-secret-title",children:[e.skillName," needs environment variables"]})]}),l.length>0?i.jsxs("div",{className:"chat-secret-persisted",children:["Already configured: ",l.map(u=>i.jsx("code",{children:u},u)).join(", ")]}):null,c.length>0&&!a?i.jsxs("div",{className:"chat-secret-fields",children:[c.map(u=>i.jsxs("div",{className:"chat-secret-row",children:[i.jsxs("label",{className:"chat-secret-label",htmlFor:`secret-${u}`,children:[u,":"]}),i.jsx("input",{id:`secret-${u}`,className:"chat-secret-input",type:"password",placeholder:`Enter ${u} value…`,value:n[u]??"",onChange:d=>r(f=>({...f,[u]:d.target.value}))})]},u)),i.jsx("button",{className:"admin-refresh-btn",type:"button",disabled:!o,onClick:()=>{t(n),s(!0)},children:"💾 Save to ~/.nuvira/.env"})]}):a?i.jsx("div",{className:"admin-hint",children:"✅ Saved — the skill will pick up these values on next load."}):i.jsx("div",{className:"admin-hint",children:"All required env vars are already configured."})]})}function obe({result:e}){const[t,n]=b.useState(!1),r=e.success?"✅":"❌",a=e.success?"Success":`Failed (exit ${e.exitCode})`,s=e.success?"chat-exec-success":"chat-exec-failure",o=new Date(e.timestamp).toLocaleTimeString();return i.jsxs("div",{className:`chat-exec-card ${s}`,children:[i.jsxs("div",{className:"chat-exec-head",onClick:()=>n(!t),style:{cursor:"pointer"},children:[i.jsx("span",{className:"chat-exec-icon",children:"📜"}),i.jsx("span",{className:"chat-exec-title",children:e.skillName}),i.jsxs("span",{className:"chat-exec-status",children:[r," ",a]}),i.jsxs("span",{className:"chat-exec-meta",children:[e.runtime," · ",e.durationMs,"ms · ",o]}),i.jsx("span",{className:"chat-exec-expand",children:t?"▼":"▶"})]}),t&&i.jsxs("div",{className:"chat-exec-body",children:[e.stdout&&i.jsxs("div",{className:"chat-exec-section",children:[i.jsx("div",{className:"chat-exec-section-title",children:"stdout"}),i.jsx("pre",{className:"chat-exec-output",children:e.stdout})]}),e.stderr&&i.jsxs("div",{className:"chat-exec-section chat-exec-stderr",children:[i.jsx("div",{className:"chat-exec-section-title",children:"stderr"}),i.jsx("pre",{className:"chat-exec-output",children:e.stderr})]}),i.jsxs("div",{className:"chat-exec-details",children:[i.jsxs("span",{children:["Runtime: ",e.runtime]}),i.jsxs("span",{children:["Exit code: ",e.exitCode]}),i.jsxs("span",{children:["Duration: ",e.durationMs,"ms"]})]})]})]})}function lbe(e){return e==="done"?"✅":e==="running"?"🔄":e==="blocked"?"⛔":"⬜"}function cbe(e){return e==="done"?"done":e==="running"?"in progress":e==="blocked"?"blocked":"pending"}function Q_({plan:e}){const t=e.steps.length,n=e.steps.filter(c=>c.status==="done").length,r=e.steps.filter(c=>c.status==="blocked").length,a=t===0?0:Math.round(n/t*100),s=t>0&&n===t,o=t>0&&e.steps.every(c=>c.status==="done"||c.status==="blocked"),l=e.steps.some(c=>c.note);return i.jsxs("div",{className:`chat-plan-card${s?" chat-plan-complete":""}`,children:[i.jsxs("div",{className:"chat-plan-head",children:[i.jsx("span",{className:"chat-plan-icon",children:"🗂️"}),i.jsx("span",{className:"chat-plan-goal",children:e.goal}),i.jsxs("span",{className:"chat-plan-count",children:[n,"/",t," done · ",a,"%"]})]}),i.jsx("div",{className:"chat-plan-bar",role:"progressbar","aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":a,children:i.jsx("span",{className:"chat-plan-bar-fill",style:{width:`${a}%`}})}),i.jsxs("table",{className:"chat-plan-table",children:[i.jsx("thead",{children:i.jsxs("tr",{children:[i.jsx("th",{className:"chat-plan-col-n",children:"#"}),i.jsx("th",{children:"Step"}),i.jsx("th",{className:"chat-plan-col-status",children:"Status"}),l?i.jsx("th",{children:"Notes"}):null]})}),i.jsx("tbody",{children:e.steps.map((c,u)=>i.jsxs("tr",{className:`chat-plan-row chat-plan-row-${c.status}`,children:[i.jsx("td",{className:"chat-plan-col-n",children:u+1}),i.jsx("td",{className:"chat-plan-step-text",children:c.description}),i.jsxs("td",{className:"chat-plan-col-status",children:[i.jsx("span",{className:"chat-plan-step-icon",children:lbe(c.status)})," ",cbe(c.status)]}),l?i.jsx("td",{className:"chat-plan-note",children:c.note??""}):null]},c.id))})]}),o?i.jsx("div",{className:"chat-plan-settled",children:s?`✅ Plan complete — ${n}/${t} steps achieved`:`📋 Plan settled — ${n}/${t} achieved, ${r} blocked`}):null]})}function Z_({tools:e,live:t}){return!e||e.length===0?null:i.jsx("div",{className:`chat-tool-cards${t?" chat-tool-cards-live":""}`,children:e.map(n=>{const r=n.phase==="started"||n.ok===void 0,a=n.ok===!1;return i.jsxs("div",{className:`chat-tool-card${r?" chat-tool-running":a?" chat-tool-err":" chat-tool-ok"}`,children:[i.jsxs("div",{className:"chat-tool-head",children:[i.jsx("span",{className:"chat-tool-icon",children:tbe(n.tool)}),i.jsx("span",{className:"chat-tool-name",children:n.tool}),n.args?i.jsx("code",{className:"chat-tool-args",children:n.args}):null,i.jsx("span",{className:"chat-tool-status",title:r?"running":a?"failed":"done",children:r?"⏳":a?"✗":"✓"}),n.durationMs!==void 0&&!r?i.jsxs("span",{className:"chat-tool-dur",children:[n.durationMs,"ms"]}):null]}),n.error||n.result?i.jsxs("details",{className:"chat-tool-detail",children:[i.jsx("summary",{children:a?"Error":"Result"}),i.jsx("pre",{className:"chat-tool-body",children:n.error||n.result})]}):null]},n.id)})})}function k$(e){return(e.evidence??[]).filter(t=>typeof(t==null?void 0:t.ref)=="string"&&t.ref.trim().length>0)}function ube(e){const t=e.filter(n=>n.verdict==="CONFIRMED"&&k$(n).length>0).length;return`${e.length} finding${e.length===1?"":"s"}: ${t} confirmed, ${e.length-t} plausible`}function J_({findings:e}){return!e||e.length===0?null:i.jsxs("details",{className:"chat-steps chat-findings",children:[i.jsx("summary",{children:`🔎 ${ube(e)}`}),i.jsx("div",{className:"chat-finding-cards",children:e.map((t,n)=>{const r=k$(t),a=t.verdict==="CONFIRMED"&&r.length>0;return i.jsxs("div",{className:`chat-finding-card ${a?"chat-finding-confirmed":"chat-finding-plausible"}`,children:[i.jsxs("div",{className:"chat-finding-head",children:[i.jsx("span",{className:"chat-finding-icon","aria-hidden":"true",children:a?"✅":"🔎"}),i.jsx("span",{className:"chat-finding-claim",children:t.claim}),i.jsx("span",{className:`chat-finding-verdict ${a?"chat-finding-verdict-ok":"chat-finding-verdict-guess"}`,title:a?"a check was performed and is shown below":"reasoned, not verified",children:a?"CONFIRMED":"PLAUSIBLE"})]}),t.outcome?i.jsx("div",{className:"chat-finding-outcome",children:t.outcome}):null,r.length>0?i.jsx("ul",{className:"chat-finding-evidence",children:r.map((s,o)=>i.jsxs("li",{children:[i.jsx("span",{className:"chat-finding-kind",children:s.kind}),i.jsx("code",{className:"chat-finding-ref",children:s.ref}),s.detail?i.jsxs("span",{className:"chat-finding-detail",children:["(",s.detail,")"]}):null]},o))}):i.jsx("div",{className:"chat-finding-noevidence",children:"no evidence — reported as PLAUSIBLE, not verified"}),t.source?i.jsxs("div",{className:"chat-finding-source",children:["source: ",t.source]}):null]},`${n}-${t.claim}`)})})]})}function dbe({worktree:e}){return i.jsxs("div",{className:"chat-worktree-card",children:[i.jsxs("div",{className:"chat-worktree-head",children:[i.jsx("span",{className:"chat-worktree-icon","aria-hidden":"true",children:"🌿"}),i.jsx("span",{className:"chat-worktree-title",children:"Ran in an isolated worktree"}),i.jsx("span",{className:`chat-worktree-state ${e.removed?"chat-worktree-gone":"chat-worktree-kept"}`,children:e.removed?"removed":"kept"})]}),i.jsxs("div",{className:"chat-worktree-meta",children:[i.jsx("code",{className:"chat-worktree-dir",title:e.dir,children:e.dir}),i.jsxs("span",{className:"admin-hint",children:["base ",e.base.slice(0,7)]})]}),i.jsx("div",{className:"chat-worktree-note admin-hint",children:e.removed?"the diff below is what is left of it — nothing was written into the project tree":"the directory above is still on disk"}),i.jsx(Cc,{diff:e.diff.payload})]})}function fbe({resume:e}){return i.jsxs("details",{className:"chat-resume-card",children:[i.jsxs("summary",{className:"chat-resume-head",children:[i.jsx("span",{className:"chat-resume-icon","aria-hidden":"true",children:"↩️"}),i.jsx("span",{className:"chat-resume-title",children:"Resumed a recorded run"}),i.jsxs("span",{className:"chat-resume-count",children:[i.jsxs("span",{children:[e.replayed," step",e.replayed===1?"":"s"," replayed"]}),i.jsxs("span",{children:[e.modelCalls," model call",e.modelCalls===1?"":"s"," made"]})]}),i.jsx("span",{className:`chat-resume-state ${e.saved?"chat-resume-saved":"chat-resume-unsaved"}`,title:e.saved?"the record was written back, so a later resume can replay this run":"the record could NOT be written — a later resume will replay nothing from this run",children:e.saved?"recorded":"not recorded"}),i.jsx("span",{className:"chat-card-caret","aria-hidden":"true",children:"▸"})]}),i.jsxs("div",{className:"chat-resume-meta",children:[typeof e.callsAvoided=="number"&&e.callsAvoided>0&&i.jsxs("span",{className:"chat-resume-saved-calls",title:"model calls the resume did not re-pay for",children:[e.callsAvoided," model call",e.callsAvoided===1?"":"s"," saved"]}),i.jsx("code",{className:"chat-resume-id",title:"the checkpoint record this run used",children:e.id})]}),i.jsx("div",{className:"chat-resume-note",children:e.notice})]})}function hbe({report:e}){const t=e.verification==="verified"?"VERIFIED":e.verification==="unverified"?"UNVERIFIED":e.verification==="blocked"?"BLOCKED":"no changes",n=[];return e.flags.unverifiedActionClaim&&n.push("claimed an action no tool ran"),e.flags.unverifiedEditClaim&&n.push("claimed a fix nothing verified"),e.flags.unverifiedBuildClaim&&n.push("claimed a failing build worked"),e.flags.unverifiedEdit&&n.push("edited without verifying"),e.flags.undeliveredArtifact&&n.push("deliverable never written"),e.flags.unfulfilledPromise&&n.push("promised an action it did not take"),e.flags.noActionTaken&&n.push("no action taken"),e.flags.undeliveredChange&&n.push("asked for a change, delivered a plan"),e.flags.unbackedHealthClaim&&n.push("verdict on the product nothing exercised"),i.jsxs("details",{className:`chat-turn-card chat-turn-${e.verification}`,children:[i.jsxs("summary",{className:"chat-turn-head",children:[i.jsx("span",{className:"chat-turn-icon","aria-hidden":"true",children:"📋"}),i.jsx("span",{className:"chat-turn-title",children:"Turn report"}),e.planned?i.jsxs("span",{className:"chat-turn-count",title:e.planCarried?"the tracked plan was carried from an earlier turn — THIS turn did not advance it":"plan steps recorded as done this turn",children:[e.stepCounts.done,"/",e.stepCounts.total," steps",e.planCarried?" · carried":""]}):null,e.summary?i.jsx("span",{className:"chat-turn-headline",title:e.summary,children:e.summary}):null,i.jsx("span",{className:"chat-turn-verdict",title:"derived from recorded evidence, never the model's own narration",children:t}),i.jsx("span",{className:"chat-card-caret","aria-hidden":"true",children:"▸"})]}),i.jsxs("div",{className:"chat-turn-body",children:[e.steps.length>0?i.jsx("ul",{className:"chat-turn-steps",children:e.steps.map(r=>i.jsxs("li",{className:`chat-turn-step chat-turn-step-${r.status}`,children:[i.jsx("span",{className:"chat-turn-step-icon","aria-hidden":"true",children:r.status==="done"?"✅":r.status==="running"?"🔄":r.status==="blocked"?"⛔":"⬜"}),i.jsx("span",{className:"chat-turn-step-text",children:r.description}),r.note?i.jsx("span",{className:"chat-turn-step-note",children:r.note}):null,r.evidence?i.jsx("span",{className:"chat-turn-step-evidence",children:r.evidence}):null]},r.id))}):null,e.changedPaths.length>0?i.jsxs("div",{className:"chat-turn-files",children:[e.changedPaths.length," file",e.changedPaths.length===1?"":"s"," changed:"," ",i.jsxs("code",{children:[e.changedPaths.slice(0,6).join(", "),e.changedPaths.length>6?` +${e.changedPaths.length-6} more`:""]})]}):null,e.planCarried?i.jsx("div",{className:"chat-turn-carried",children:"📋 that plan is carried from an earlier turn — THIS turn did not advance it."}):null,e.unverifiedPaths&&e.unverifiedPaths.length>0?i.jsxs("div",{className:"chat-turn-owed",children:["⚠️ ",e.unverifiedPaths.length," changed path",e.unverifiedPaths.length===1?"":"s"," no check exercised:"," ",i.jsxs("code",{children:[e.unverifiedPaths.slice(0,6).join(", "),e.unverifiedPaths.length>6?` +${e.unverifiedPaths.length-6} more`:""]})]}):null,n.length>0?i.jsx("div",{className:"chat-turn-flags",children:n.map(r=>i.jsxs("span",{className:"chat-turn-flag",children:["⚠️ ",r]},r))}):null]})]})}function mv(){try{if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch{}return`chat-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}const S$="nuvira.dashboard.chat.activeSession";function pbe(){try{const e=sessionStorage.getItem(S$);return e&&e.length>0&&e.length<=64?e:null}catch{return null}}function gv(e){try{sessionStorage.setItem(S$,e)}catch{}}function mbe(e,t){const n=t.trim().toLowerCase(),r=n?e.filter(u=>`${u.title} ${u.preview} ${u.firstUser}`.toLowerCase().includes(n)):e,a=[],s=new Date,o=new Date(s.getFullYear(),s.getMonth(),s.getDate()).getTime(),l=864e5,c=[{label:"Today",match:u=>u>=o},{label:"Yesterday",match:u=>u>=o-l&&u<o},{label:"This week",match:u=>u>=o-7*l&&u<o-l},{label:"Older",match:()=>!0}];for(const u of c){const d=r.filter(f=>u.match(f.updatedAt));d.length>0&&a.push({label:u.label,items:d})}return a}function gbe({ceilingRecovery:e}={}){var re;const[t,n]=b.useState(null),r=qr(),[a,s]=b.useState(Hye);b.useEffect(()=>{K.fetchLimits().then(A=>{A&&A.attachmentMaxBytes>0&&s(A.attachmentMaxBytes)})},[]),b.useEffect(()=>{K.fetchProcessEnv().then(A=>{const H=A.find(Y=>Y.name==="NUVIRA_CAPABILITY_MODE");H&&P(nbe(H.processValue??H.fileValue))})},[]),b.useEffect(()=>{K.listRoutableModels().then(A=>U(A))},[]);const[o,l]=b.useState([]),[c,u]=b.useState(""),[d,f]=b.useState(!1),[h,p]=b.useState(""),[m,g]=b.useState(null),[y,v]=b.useState(!1),[k,w]=b.useState(!1),[j,S]=b.useState(!1),[x,N]=b.useState(""),[E,P]=b.useState("balanced"),[_,R]=b.useState(""),[T,B]=b.useState(null),[$,I]=b.useState(!1),[D,U]=b.useState([]),[M,z]=b.useState(null),[O,J]=b.useState([]),[F,L]=b.useState([]),[ie,fe]=b.useState(null),[ve,Ee]=b.useState(null),[ee,Q]=b.useState(null),[ae,ce]=b.useState([]),[G,xe]=b.useState([]),[we,Pe]=b.useState([]),ge=b.useRef([]),Ie=b.useRef([]),me=b.useRef(null),Qe=b.useRef(null),De=b.useRef(null),_e=b.useRef([]),[pt,We]=b.useState(""),lt=b.useRef(""),Yt=b.useRef(null),[q,Z]=b.useState(null),[se,pe]=b.useState(!1),ke=b.useRef(!1),$e=b.useRef(!1),[zt,Le]=b.useState(0),rn=b.useRef(null),[Mn,wt]=b.useState(null),[Mt,an]=b.useState(null),[or,In]=b.useState(null),Gn=b.useRef(null),At=b.useRef(pbe()??mv()),Ft=b.useRef(""),[lr,cr]=b.useState([]),[zl,Tt]=b.useState(!0),[ya,pn]=b.useState(""),[Xs,sn]=b.useState(null),[ba,Kr]=b.useState(""),[_r,xa]=b.useState([]),[wa,qn]=b.useState(null),[Gi,qi]=b.useState(!1),Qs=b.useRef(null),Qa=b.useRef(null),[et,Zs]=b.useState(null),[ka,Sa]=b.useState(null),[Za,Ki]=b.useState([]),[Ja,Vi]=b.useState(""),[Yi,Vr]=b.useState(""),[Cr,ja]=b.useState(!1),[W,ne]=b.useState(""),[je,Se]=b.useState([]),[on,Kn]=b.useState(null),[En,Ar]=b.useState(!1),[Xi,Js]=b.useState([]),[md,Yr]=b.useState([]),[Fl,Ul]=b.useState(""),ei=b.useRef(null),He=b.useRef(null),eo=b.useRef(null),at=b.useRef(null),[It,Xr]=b.useState(null),[Qi,Wl]=b.useState(new Set),[Qr,gd]=b.useState("");b.useEffect(()=>{K.fetchAdminAuthStatus().then(A=>{n(A?{configured:A.configured,authenticated:A.authenticated,role:A.role??null}:{configured:!1,authenticated:!1,role:null})})},[r]),b.useEffect(()=>{var A,H;try{(H=(A=eo.current)==null?void 0:A.scrollTo)==null||H.call(A,{top:eo.current.scrollHeight})}catch{}},[o,d,O]),b.useEffect(()=>()=>{var A;(A=He.current)==null||A.call(He),He.current=null},[]);const Im=b.useCallback(async A=>{var he,Re;(he=He.current)==null||he.call(He),He.current=null;const H=await K.getChatSession(A);if(!H)return;At.current=A,gv(A),l(H.turns.map(ue=>({role:ue.role,content:ue.content,...ue.role==="assistant"?{followups:[],artifacts:wf(ue.content)}:{}}))),J([]),ge.current=[],L([]),Ie.current=[],fe(null),me.current=null,Ee(null),Qe.current=null,Q(null),De.current=null,ce([]),_e.current=[],lt.current="",We(""),Z(null),p(""),z(null),Xr(null),Tt(!0),B(H.pinnedProvider&&H.pinnedModel?{provider:H.pinnedProvider,model:H.pinnedModel}:null),I(H.pinnedStrict===!0);const Y=H.projectPath;if(Y){if(Sa(Y),(et==null?void 0:et.path)===Y)return;(Re=at.current)==null||Re.call(at,Y)}else Sa(null)},[et]),Hl=b.useCallback(()=>{var A;(A=He.current)==null||A.call(He),He.current=null,At.current=mv(),gv(At.current),Sa(null),B(null),l([]),J([]),ge.current=[],L([]),Ie.current=[],fe(null),me.current=null,Ee(null),Qe.current=null,Q(null),De.current=null,ce([]),_e.current=[],lt.current="",We(""),Z(null),p(""),z(null),Xr(null),xa([]),qn(null),u(""),Tt(!0)},[]),Zr=b.useCallback(A=>{xa(H=>[...H,A].slice(-10))},[]),$m=b.useCallback(A=>{xa(H=>H.filter((Y,he)=>he!==A))},[]),Gl=b.useCallback(async A=>{if(!A)return;if(A.size>a){p(`Attachment "${A.name}" is too large (max ${Math.round(a/1024)} KB). Raise the cap in Admin → Process Environment (NUVIRA_ATTACHMENT_MAX_BYTES).`);return}const H=new Uint8Array(await A.slice(0,8192).arrayBuffer()),Y=Jye(A.name,H);if(Y.how==="unsupported"){p(Y.reason);return}if(Y.how==="binary"){const Re=new Uint8Array(await A.arrayBuffer());Zr({name:A.name,content:Zye(Re),kind:"file",encoding:"base64"});return}const he=await A.text();Zr({name:A.name,content:he,kind:"file",encoding:"text"})},[Zr]),Lm=b.useCallback(A=>{const H=A.currentTarget,Y=A.clipboardData.getData("text")||"";Y.length>=Vye&&(Qa.current={start:H.selectionStart,end:H.selectionEnd},qn({text:Y}))},[]),vd=b.useCallback(()=>{const A=wa;if(!A)return;const H=Qa.current;u(Y=>H?Y.slice(0,H.start)+Y.slice(H.end):Y),Zr({name:"pasted-text.txt",content:A.text,kind:"paste",encoding:"text"}),qn(null),Qa.current=null},[wa,Zr]),yd=b.useCallback(A=>{sn(A.id),Kr(A.title==="(untitled conversation)"?"":A.title)},[]),to=b.useCallback(async A=>{const H=await K.renameChatSession(A,ba);H.ok?cr(Y=>Y.map(he=>he.id===A?{...he,title:ba.trim()||he.title}:he)):p(H.error||"Could not rename the session."),sn(null),Kr("")},[ba]),ql=b.useCallback(async A=>{const H=await K.deleteChatSession(A);H.ok?(cr(Y=>Y.filter(he=>he.id!==A)),At.current===A&&Hl()):p(H.error||"Could not delete the session.")},[Hl]),ti=(t==null?void 0:t.authenticated)===!0&&(t.role==="admin"||t.role==="operator"),bd=b.useRef(!1);b.useEffect(()=>{if(!ti||bd.current)return;bd.current=!0;const A=At.current;let H=!1,Y=null;const he=async()=>{const Re=await K.getChatSession(A);H||Re&&(Yt.current||l(Re.turns.map(ue=>({role:ue.role,content:ue.content,...ue.role==="assistant"?{followups:[],artifacts:wf(ue.content)}:{}}))),f(Re.busy===!0),Re.busy===!0&&(rn.current=Re.busySince??Date.now()),pe(Re.busy===!0),Re.pendingQuestion?Xr(Re.pendingQuestion):Re.busy||Xr(null),Re.busy&&(Y=setTimeout(()=>void he(),2500)))};return he(),()=>{H=!0,Y&&clearTimeout(Y)}},[ti]),b.useEffect(()=>{if(!se){Le(0),rn.current=null;return}const A=()=>Date.now()-(rn.current??Date.now());Le(A());const H=setInterval(()=>Le(A()),Kye);return()=>clearInterval(H)},[se]),b.useEffect(()=>{ti&&(K.listChatSessions().then(A=>{Array.isArray(A)&&cr(A)}),K.listProjects().then(A=>{Array.isArray(A)&&Ki(A)}))},[ti]);const Tr=b.useCallback(async A=>{const H=A.trim();if(!H)return;Vr("");const Y=await K.attachProject(H);if(Y.ok&&Y.project){Zs(Y.project),Vi("");const he=await K.listProjects();Array.isArray(he)&&Ki(he)}else Vr(Y.error||"Could not attach that directory.")},[]);at.current=Tr;const Na=b.useCallback(async A=>{ja(!0),Ar(!0),Ul("");const H=await K.browseDirectories(A,{showDrives:!A});H.ok&&(ne(H.path),Se(H.entries),Kn(H.parent),H.drives&&Js(H.drives),H.breadcrumbs&&Yr(H.breadcrumbs)),Ar(!1)},[]),Kl=b.useCallback(async A=>{Ar(!0),Ul("");const H=await K.browseDirectories(A);H.ok&&(ne(H.path),Se(H.entries),Kn(H.parent),H.breadcrumbs&&Yr(H.breadcrumbs)),Ar(!1)},[]),no=b.useCallback(async()=>{if(!W)return;const A=await K.browseDirectories(W);A.ok&&Se(A.entries)},[W]);b.useEffect(()=>K.onChatRetryEvent(H=>{if(H.sessionId!==At.current){K.listChatSessions().then(Y=>{Array.isArray(Y)&&cr(Y)});return}l(Y=>[...Y,{role:"assistant",content:H.content}]),H.kind==="answer"&&Z(null)}),[]),b.useEffect(()=>(Cr&&W&&(ei.current=setInterval(()=>{no()},5e3)),()=>{ei.current&&clearInterval(ei.current)}),[Cr,W,no]);const xd=b.useCallback(async()=>{if(typeof window<"u"&&"showDirectoryPicker"in window)try{const Y=(await window.showDirectoryPicker({mode:"read"})).name;if(!Y){Na();return}Vr(""),f(!0);const he=await K.resolveFolder(Y);f(!1),he.ok&&he.path?(Vi(he.path),Tr(he.path)):Vr('Folder "'+Y+'" found — selecting it now. If this is wrong, type the full path below.');return}catch(H){if((H==null?void 0:H.name)==="AbortError")return}Na()},[Na,Tr]),Zi=b.useCallback(A=>{if($e.current)return;$e.current=!0,ke.current=!1;const H=A.content||"(the agent produced no text — try rephrasing)";l(Y=>[...Y,{role:"assistant",content:H,error:A.generationFailed===!0,followups:A.followups??[],steps:ge.current,tools:Ie.current,plan:me.current,diff:Qe.current,draft:De.current,findings:_e.current,artifacts:wf(H)}]),lt.current="",We(""),p(""),Z(null),pe(!1),f(!1),Tt(!0)},[]),Vl=b.useCallback(async(A,H)=>{const Y=(e==null?void 0:e.pollMs)??Gye,he=(e==null?void 0:e.maxMisses)??qye;let Re=0;for(;;){if(await new Promise(ur=>setTimeout(ur,Y)),$e.current||!ke.current)return;const ue=await K.getChatSession(A);if(!ue){if(++Re>=he){ke.current=!1,pe(!1),f(!1),p("Lost contact with the server while this turn was running. The turn itself was not cancelled — its answer is in this conversation (reopen it) or in Traces.");return}continue}if(Re=0,ue.busy===!0){ue.pendingQuestion&&Xr(ue.pendingQuestion),typeof ue.busySince=="number"&&(rn.current=ue.busySince);continue}const Ne=[...ue.turns].reverse().find(ur=>ur.role==="assistant");Ne?Zi({content:Ne.content,followups:[]}):(ke.current=!1,pe(!1),f(!1),Z(H));return}},[Zi,e==null?void 0:e.pollMs,e==null?void 0:e.maxMisses]),ln=b.useCallback(async(A,H)=>{var ur,ro,W0;const Y=A.trim(),he=Array.isArray(H)?H:_r;if(!Y&&he.length===0||d)return;p(""),z(null),J([]),ge.current=[],L([]),Ie.current=[],fe(null),me.current=null,Ee(null),Qe.current=null,Q(null),De.current=null,ce([]),_e.current=[],l(Ae=>[...Ae,{role:"user",content:Y,attachments:he.length>0?he:void 0}]),u(""),xa([]),qn(null),Ft.current=Y||`[${he.length} attachment(s)]`,rn.current=Date.now(),f(!0),Tt(!1);const Re=At.current,ue=new AbortController;Yt.current=ue,Z(null),ke.current=!1,$e.current=!1,pe(!1),(ur=He.current)==null||ur.call(He),He.current=K.subscribeChat(Re,{onToken:Ae=>{lt.current+=Ae,We(lt.current)},onProgress:Ae=>{ge.current=[...ge.current,Ae],J(ge.current)},onQuestion:Ae=>{Xr(Ae),Wl(new Set)},onTool:Ae=>{const jt=[...Ie.current],Ji=jt.findIndex(N$=>N$.id===Ae.id),es={id:Ae.id,tool:Ae.tool,phase:Ae.phase,args:Ae.args,ok:Ae.ok,result:Ae.result,error:Ae.error,durationMs:Ae.durationMs};Ji>=0?jt[Ji]=es:jt.push(es),Ie.current=jt,L(jt)},onPlan:Ae=>{const jt={goal:Ae.goal,steps:Ae.steps.map(ebe),revision:Ae.revision};me.current=jt,fe(jt)},onDiff:Ae=>{const jt={files:Ae.files,summary:Ae.summary};Qe.current=jt,Ee(jt)},onSkillDraft:Ae=>{const jt={name:Ae.name,description:Ae.description,markdown:Ae.markdown,updatedAt:Ae.updatedAt,status:"pending"};De.current=jt,Q(jt)},onFinding:Ae=>{_e.current=[..._e.current,Ae],ce(_e.current)},onSecretRequest:Ae=>{xe(jt=>{const Ji=jt.findIndex(es=>es.skillName===Ae.skillName);if(Ji>=0){const es=[...jt];return es[Ji]=Ae,es}return[...jt,Ae]})},onExecutionResult:Ae=>{Pe(jt=>[...jt,Ae])},onTurnDone:Ae=>{ke.current&&Zi(Ae)}});const Ne=await K.chatSend(Re,Y||`(see ${he.length} attachment${he.length===1?"":"s"})`,{...T?{provider:T.provider,model:T.model}:{},...T&&$?{strict:!0}:{},projectPath:et==null?void 0:et.path,attachments:he.map(Ae=>({name:Ae.name,content:Ae.content,kind:Ae.kind,encoding:Ae.encoding??"text"})),...y?{worktree:!0,keepWorktree:k}:{},...j?{resume:x.trim()||!0}:{}},ue.signal);if(Yt.current=null,(ro=He.current)==null||ro.call(He),He.current=null,lt.current="",We(""),Ne.ok){z(Ne.generationFailed?null:`${Ne.provider??"provider"}${Ne.model?` / ${Ne.model}`:" (auto-routed)"}`),wt(Ne.routingNotice??null),an(Ne.workspaceNotice??null);const Ae=Ne.workspaceSource==="scratch"?Ne.workspacePath??null:null;In(Ae),!Ae&&Ne.workspacePath&&Ne.workspacePath!==(et==null?void 0:et.path)&&((W0=at.current)==null||W0.call(at,Ne.workspacePath)),Z(Ne.generationFailed&&!Ne.retryQueued&&!Ne.refused?Y:null);const jt=Ne.content||"(the agent produced no text — try rephrasing)";l(Ji=>[...Ji,{role:"assistant",content:jt,error:Ne.generationFailed,followups:Ne.followups,steps:ge.current,tools:Ie.current,plan:me.current,diff:Qe.current,draft:De.current,findings:Ne.findings??_e.current,worktree:Ne.worktree,resume:Ne.resume,turnReport:Ne.turnReport,refused:Ne.refused,needsProject:Ne.needsProject,artifacts:wf(jt)}])}else ue.signal.aborted?(p(""),Z(null)):Ne.turnStillRunning?(p(""),Z(null),pe(!0),ke.current=!0,$e.current=!1,Vl(Re,Y)):Ne.unauthorized?(n(Ae=>Ae&&{...Ae,authenticated:!1}),p("Session expired — log in again to chat.")):(p(Ne.error||"The agent could not answer — check that a provider API key is set for the dashboard process."),Z(Y));Ne.ok===!1&&Ne.turnStillRunning||(f(!1),Tt(!0))},[d,et,_r,y,k,j,x,T,Zi,Vl]),wd=b.useCallback(()=>{var A;(A=Yt.current)==null||A.abort(),K.chatCancel(At.current)},[]),kd=b.useCallback(async()=>{const A=E==="max"?"balanced":"max";R("");const H=await K.saveProcessEnvVar("NUVIRA_CAPABILITY_MODE",A);H.ok?(P(A),R(A==="max"?"⚡ Max capability is on for the next turn.":"⚖️ Back to balanced.")):R(H.error||"Could not change the capability mode.")},[E]),Sd=b.useCallback(async()=>{g(null);const A=await K.chatSupportBundle(At.current);g(A.ok?{kind:"ok",text:"Support bundle downloaded — attach it to your bug report."}:{kind:"err",text:A.error||"Could not build the support bundle."})},[]),Yl=b.useCallback(async A=>{Q(Y=>Y&&{...Y,status:"saving"});const H=await K.skillDraftAccept(A);Q(Y=>Y&&{...Y,status:H.ok?"saved":"error"}),H.ok||p(H.error||"Could not accept the draft.")},[]),Xl=b.useCallback(async A=>{const H=await K.skillDraftReject(A);H.ok?Q(Y=>Y&&{...Y,status:"rejected"}):p(H.error||"Could not reject the draft.")},[]),Ql=b.useCallback(A=>{ln(`Revise the skill draft "${A}" — improve it per your best judgment and present it again.`)},[ln]),jd=b.useCallback(async A=>{const H=await K.saveSecrets(A);if(!H.ok){p(H.error||"Could not save secrets.");return}const Y=H.refused??[];Y.length>0&&p(Y.map(he=>he.reason==="provider-credential"?`${he.name} is a provider credential — set it up as a provider, skills never receive it.`:`${he.name} was not saved (${he.reason}).`).join(" "))},[]),Zl=b.useCallback(A=>{if(A.length===0)return;const H=et?` in the attached project ${et.path}`:"";ln(`Commit exactly these files that I accepted on the diff card (and nothing else)${H}: ${A.join(", ")}. Show me a short confirmation before finishing.`)},[ln,et]),Jr=b.useCallback(async A=>{const H=It;if(!H)return;Xr(null),gd(""),Wl(new Set);const Y=await K.chatRespond(At.current,H.questionId,A);Y.ok||p(Y.error||"The question could not be answered — try sending your message again.")},[It]),Jl=b.useCallback(()=>{if(!It)return;const A=Qr.trim(),H=It.multiSelect?[...Qi]:[...Qi][0];It.multiSelect?Jr({index:[...Qi],...A?{custom:A}:{}}):Jr(A?{index:-1,custom:A}:H!==void 0?{index:H}:{index:-1})},[It,Qi,Qr,Jr]),Nd=b.useCallback(()=>{It&&Jr({index:-1})},[It,Jr]),Ed=b.useCallback(A=>{Wl(H=>{const Y=new Set(H);return It!=null&&It.multiSelect?Y.has(A)?Y.delete(A):Y.add(A):(Y.clear(),Y.add(A)),Y})},[It]),C=b.useCallback(async()=>{var H;(H=He.current)==null||H.call(He),He.current=null,At.current=mv(),gv(At.current),l([]),J([]),ge.current=[],L([]),Ie.current=[],fe(null),me.current=null,Ee(null),Qe.current=null,Q(null),De.current=null,ce([]),_e.current=[],lt.current="",We(""),Z(null),p(""),z(null),Xr(null);const A=await K.listChatSessions();Array.isArray(A)&&cr(A)},[]),V=((re=[...o].reverse().find(A=>{var H;return A.role==="assistant"&&!A.error&&(((H=A.followups)==null?void 0:H.length)??0)>0}))==null?void 0:re.followups)??[];return i.jsxs("div",{className:"panel",children:[i.jsx(Oe,{icon:"💬",title:"Chat with the agent",actions:i.jsxs("div",{className:"chat-head-actions",children:[M?i.jsx("span",{className:"admin-hint",children:M}):null,i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:()=>void C(),disabled:d||o.length===0,children:"🗑 New conversation"})]})}),t!=null&&t.authenticated?ti?i.jsxs(i.Fragment,{children:[i.jsx("div",{className:"chat-project-bar",children:et?i.jsxs("div",{className:"chat-project-attached",children:[i.jsx("span",{className:"chat-project-icon",children:"📁"}),i.jsx("span",{className:"chat-project-name",children:et.name}),i.jsxs("span",{className:"chat-project-meta",children:[et.fileCount," files · ",et.symbolCount," symbols",et.truncated?" · truncated map":""]}),i.jsx("span",{className:"chat-project-path",title:et.path,children:et.path}),i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>Zs(null),children:"✕ detach"})]}):i.jsxs("div",{className:"chat-project-pick",children:[i.jsx("span",{className:"chat-project-icon",children:"📁"}),i.jsx("span",{className:"chat-project-hint",children:"Select Project Folder"}),Za.find(A=>A.kind==="cwd")?i.jsxs("span",{className:"chat-project-cwd",title:"Working directory used when no folder is attached",children:["⚙️ ",Za.find(A=>A.kind==="cwd").path]}):null,Za.length>0?i.jsx("span",{className:"chat-project-chips",children:Za.filter(A=>A.kind!=="cwd").slice(0,3).map(A=>i.jsx("button",{type:"button",className:"chat-chip",onClick:()=>void Tr(A.path),children:A.name},A.path))}):null,i.jsx("input",{className:"chat-project-input",ref:Gn,value:Ja,onChange:A=>Vi(A.target.value),onKeyDown:A=>{A.key==="Enter"&&(A.preventDefault(),Tr(Ja))},placeholder:"or type a path, e.g. ~/code/my-app",disabled:d}),i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>void Tr(Ja),disabled:d||!Ja.trim(),children:"Attach"}),i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>void xd(),title:"Pick a project folder using your system's folder picker (Finder / Explorer)",children:"🗂️ Browse"}),Yi?i.jsx("span",{className:"chat-project-error",children:Yi}):null,Cr?i.jsxs("div",{className:"chat-browse-popover",children:[i.jsxs("div",{className:"chat-browse-head",children:[i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>ja(!1),title:"Close",children:"✕"}),i.jsx("div",{className:"chat-browse-breadcrumbs",children:Xi.length>0&&!W?i.jsx("span",{className:"admin-hint",children:"Select a drive or home folder:"}):i.jsxs(i.Fragment,{children:[i.jsx("button",{type:"button",className:"chat-breadcrumb",onClick:()=>void Na(),children:"🏠"}),md.map((A,H)=>i.jsxs("span",{children:[i.jsx("span",{className:"chat-breadcrumb-sep",children:"/"}),i.jsx("button",{type:"button",className:"chat-breadcrumb",onClick:()=>void Kl(A.path),children:A.name})]},A.path))]})})]}),Xi.length>0&&!W?i.jsx("div",{className:"chat-browse-drives",children:Xi.map(A=>i.jsx("button",{type:"button",className:"chat-browse-drive",onClick:()=>void Kl(A.path),children:A.name},A.path))}):null,je.length>5?i.jsx("div",{className:"chat-browse-search",children:i.jsx("input",{type:"text",className:"chat-browse-filter",placeholder:"🔍 Filter folders…",value:Fl,onChange:A=>Ul(A.target.value),autoFocus:!0})}):null,i.jsx("div",{className:"chat-browse-list",children:En?i.jsx("span",{className:"admin-hint",children:"Loading…"}):je.length===0?i.jsx("span",{className:"admin-hint",children:"No subdirectories found"}):je.filter(A=>!Fl||A.name.toLowerCase().includes(Fl.toLowerCase())).map(A=>i.jsxs("button",{type:"button",className:"chat-browse-entry",onClick:()=>void Kl(A.path),children:[i.jsx("span",{className:"chat-browse-entry-icon",children:"📁"}),i.jsx("span",{className:"chat-browse-entry-name",children:A.name}),A.modified?i.jsx("span",{className:"chat-browse-entry-date",children:new Date(A.modified).toLocaleDateString()}):null]},A.path))}),i.jsxs("div",{className:"chat-browse-foot",children:[i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>void no(),title:"Refresh folder list",children:"🔄"}),i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>{ja(!1),Tr(W)},disabled:!W,children:"📁 Select this folder"})]})]}):null]})}),ka&&(!et||et.path!==ka)?i.jsxs("div",{className:"chat-session-project-banner",children:[i.jsxs("span",{children:["⚠️ This conversation was working in ",i.jsx("code",{children:ka})]}),et?i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>void Tr(ka),children:"📁 Switch to it"}):i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>void Tr(ka),children:"📁 Attach it"})]}):null,i.jsxs("div",{className:"chat-layout",children:[zl?i.jsxs("div",{className:"chat-sidebar",children:[i.jsxs("div",{className:"chat-sidebar-head",children:[i.jsx("span",{children:"📁 Sessions"}),i.jsxs("div",{className:"chat-sidebar-head-actions",children:[i.jsx("button",{type:"button",className:"chat-mini-action",title:"New chat",onClick:Hl,children:"+ New"}),i.jsx("button",{type:"button",className:"chat-mini-action",title:"Collapse history",onClick:()=>Tt(!1),children:"▸"})]})]}),i.jsx("input",{className:"chat-session-search",placeholder:"Search conversations…",value:ya,onChange:A=>pn(A.target.value)}),lr.length===0?i.jsx("div",{className:"chat-sidebar-empty",children:"No past conversations yet."}):i.jsx("div",{className:"chat-sidebar-list",children:mbe(lr,ya).map(({label:A,items:H})=>i.jsxs("div",{className:"chat-session-group",children:[i.jsx("div",{className:"chat-session-group-label",children:A}),H.map(Y=>i.jsx("div",{className:`chat-session-item${Y.id===At.current?" chat-session-active":""}`,children:Xs===Y.id?i.jsxs("div",{className:"chat-session-rename",children:[i.jsx("input",{autoFocus:!0,value:ba,onChange:he=>Kr(he.target.value),onKeyDown:he=>{he.key==="Enter"&&to(Y.id),he.key==="Escape"&&sn(null)},placeholder:"Session title"}),i.jsx("button",{type:"button",className:"chat-mini-action",onClick:()=>void to(Y.id),children:"✓"})]}):i.jsxs(i.Fragment,{children:[i.jsxs("button",{type:"button",className:"chat-session-main",onClick:()=>void Im(Y.id),title:Y.preview||Y.title,children:[i.jsx("span",{className:"chat-session-title",children:Y.title}),i.jsx("span",{className:"chat-session-preview",children:Y.firstUser||Y.preview}),i.jsxs("span",{className:"chat-session-meta",children:[Y.projectPath?`📁 ${Y.projectPath.split("/").pop()} · `:"",Y.turnCount," msg",Y.turnCount===1?"":"s"," · ",new Date(Y.updatedAt).toLocaleString()]})]}),i.jsxs("span",{className:"chat-session-actions",children:[i.jsx("button",{type:"button",className:"chat-mini-action",title:"Rename",onClick:()=>yd(Y),children:"✏️"}),i.jsx("button",{type:"button",className:"chat-mini-action",title:"Delete",onClick:()=>void ql(Y.id),children:"🗑"})]})]})},Y.id))]},A))})]}):i.jsx("div",{className:"chat-rail",children:i.jsx("button",{type:"button",className:"chat-rail-btn",onClick:()=>Tt(!0),title:"Show history",children:"📁"})}),i.jsxs("div",{className:"chat-main",children:[i.jsxs("div",{className:"chat-thread",ref:eo,role:"log","aria-live":"polite",children:[o.length===0?i.jsxs("div",{className:"empty-state",children:[i.jsx("p",{className:"empty-state-title",children:"Say anything — the agent decides what to do (answer, fix code, plan, run the pipeline)."}),i.jsxs("div",{className:"empty-state-chips",children:[i.jsx("button",{type:"button",className:"chat-chip",onClick:()=>void ln("what's the state of this project?"),children:"📋 assess this project"}),i.jsx("button",{type:"button",className:"chat-chip",onClick:()=>void ln("run the test suite"),children:"🧪 run the tests"}),i.jsx("button",{type:"button",className:"chat-chip",onClick:()=>void ln("stop the gateway"),children:"⏹ stop the gateway"}),i.jsx("button",{type:"button",className:"chat-chip",onClick:()=>void ln("load the code-assessment skill and assess this project"),children:"🧠 load the code-assessment skill"}),i.jsx("button",{type:"button",className:"chat-chip",onClick:()=>void ln("learn the workflow I just did as a skill"),children:"📚 learn a workflow as a skill"}),i.jsx("button",{type:"button",className:"chat-chip",onClick:()=>void ln("publish the current version"),children:"🚀 publish the release"})]})]}):o.map((A,H)=>i.jsxs("div",{className:`chat-bubble chat-${A.role}${A.error?" chat-error":""}`,children:[i.jsx("div",{className:"chat-bubble-role",children:A.role==="user"?"You":"🤖 Agent"}),A.role==="assistant"?i.jsx("div",{className:"chat-bubble-text",children:i.jsx(q_,{text:A.content})}):i.jsx("div",{className:"chat-bubble-text",children:A.content}),A.role==="user"&&A.attachments&&A.attachments.length>0?i.jsxs("details",{className:"chat-steps",open:A.attachments.length===1,children:[i.jsxs("summary",{children:["📎 ",A.attachments.length," attachment",A.attachments.length===1?"":"s",":"," ",A.attachments.map(Y=>Y.name).join(", ")]}),A.attachments.map((Y,he)=>i.jsxs("div",{className:"chat-attach-content",children:[i.jsxs("div",{className:"admin-hint",children:[Y.name," — ",bt(Y.content.length)," chars"]}),i.jsx("pre",{children:Y.content})]},he))]}):null,A.role==="assistant"&&A.diff?i.jsxs("details",{className:"chat-steps",open:!0,children:[i.jsxs("summary",{children:["Changes: ",A.diff.summary]}),i.jsx(Cc,{diff:A.diff,selectable:!0,onCommitAccepted:Zl})]}):null,A.role==="assistant"&&A.artifacts&&(A.artifacts.diffs.length>0||A.artifacts.results.length>0||A.artifacts.deploys.length>0)?i.jsxs(ibe,{children:[A.artifacts.diffs.map((Y,he)=>i.jsx("div",{"data-artifact-card":!0,tabIndex:0,role:"group","aria-label":`Diff: ${Y.summary}`,className:"chat-artifact-item",children:et?i.jsx(Cc,{diff:Y,selectable:!0,onCommitAccepted:Zl}):i.jsx(Cc,{diff:Y,lockedHint:"Attach a project to review and commit these changes."})},`diff-${he}`)),A.artifacts.results.map((Y,he)=>i.jsx("div",{"data-artifact-card":!0,tabIndex:0,role:"group","aria-label":`Result: ${Y.title}`,className:"chat-artifact-item",children:i.jsx(rbe,{result:Y})},`result-${he}`)),A.artifacts.deploys.map((Y,he)=>i.jsx("div",{"data-artifact-card":!0,tabIndex:0,role:"group","aria-label":`Deployment: ${Y.url}`,className:"chat-artifact-item",children:i.jsx(abe,{deploy:Y})},`deploy-${he}`))]}):null,A.role==="assistant"&&A.draft?i.jsxs("details",{className:"chat-steps",open:!0,children:[i.jsxs("summary",{children:["Skill draft: ",A.draft.name]}),i.jsx(X_,{draft:A.draft,onAccept:Yl,onReject:Xl,onEdit:Ql})]}):null,A.role==="assistant"&&A.plan?i.jsxs("details",{className:"chat-steps",open:!0,children:[i.jsxs("summary",{children:["Plan: ",A.plan.goal]}),i.jsx(Q_,{plan:A.plan})]}):null,A.role==="assistant"&&A.refused?i.jsx("div",{className:"chat-refused-line",children:"⛔ This turn did not run — the isolation it asked for could not be made. Nothing was written, and the reason is above."}):null,A.role==="assistant"&&A.needsProject?i.jsx("div",{className:"chat-refused-line",children:"📁 Nothing was run — attach a project folder above, then send the message again."}):null,A.role==="assistant"&&A.worktree?i.jsx(dbe,{worktree:A.worktree}):null,A.role==="assistant"&&A.resume?i.jsx(fbe,{resume:A.resume}):null,A.role==="assistant"&&A.turnReport?i.jsx(hbe,{report:A.turnReport}):null,A.role==="assistant"&&A.findings&&A.findings.length>0?i.jsx(J_,{findings:A.findings}):null,A.role==="assistant"&&A.tools&&A.tools.length>0?i.jsxs("details",{className:"chat-steps chat-tool-details",children:[i.jsxs("summary",{children:[A.tools.length," tool call",A.tools.length===1?"":"s"]}),i.jsx(Z_,{tools:A.tools})]}):null,A.role==="assistant"&&A.steps&&A.steps.length>0?i.jsxs("details",{className:"chat-steps",children:[i.jsxs("summary",{children:[A.steps.length," step",A.steps.length===1?"":"s"]}),i.jsx("div",{className:"chat-step-line",children:A.steps.map((Y,he)=>i.jsx("div",{children:Y.trim()},he))})]}):null]},H)),d?i.jsxs("div",{className:"chat-bubble chat-assistant",children:[i.jsx("div",{className:"chat-bubble-role",children:"🤖 Agent"}),ie?i.jsx(Q_,{plan:ie}):null,ve?i.jsx(Cc,{diff:ve}):null,y&&d?i.jsx("div",{className:"chat-resume-line",children:"🌿 this turn is running in its own git worktree — the diff arrives with the answer"}):null,j&&d?i.jsx("div",{className:"chat-resume-line",children:"↩️ this turn is replaying the recorded steps of this ask that are unchanged — the count arrives with the answer"}):null,ae.length>0?i.jsx(J_,{findings:ae}):null,ee?i.jsx(X_,{draft:ee,onAccept:Yl,onReject:Xl,onEdit:Ql}):null,G.map(A=>i.jsx(sbe,{request:A,onSave:jd},A.skillName)),we.map((A,H)=>i.jsx(obe,{result:A},`${A.skillName}-${H}`)),i.jsx(Z_,{tools:F,live:!0}),pt?i.jsx("div",{className:"chat-bubble-text chat-streaming",children:i.jsx(q_,{text:pt})}):null,i.jsx("div",{className:"chat-working",children:O.length>0?i.jsx("span",{className:"chat-working-lines",children:O.map((A,H)=>i.jsx("div",{className:"chat-step-line",children:A.trim()},H))}):i.jsxs(i.Fragment,{children:["💭 thinking… ",i.jsx("span",{className:"chat-dots"})]})})]}):null]}),h?i.jsx("div",{className:"admin-row-msg admin-row-msg-err",children:h}):null,se&&It?i.jsxs("div",{className:"admin-row-msg chat-routing-notice",children:["❓ Waiting for ",i.jsx("strong",{children:"your"})," answer — choose one of the options above and the turn continues where it stopped. Nothing is stuck: the server is holding this turn open for you, and the agent has not been told anything yet (its own words: it asked instead of guessing)."]}):se?i.jsxs("div",{className:"admin-row-msg chat-routing-notice",children:["⏳ Still working on the server — ",Gb(zt)," elapsed on this turn, counted from when it started (not from when this page stopped waiting for the reply). This is a long-running turn, not a failure: the answer will appear here by itself when it lands, and you can close this page and come back."]}):null,Mn?i.jsxs("div",{className:"admin-row-msg chat-routing-notice",children:[i.jsxs("span",{children:["ℹ️ ",Mn]})," ",i.jsx("button",{className:"chat-routing-notice-dismiss",type:"button","aria-label":"Dismiss routing notice",onClick:()=>wt(null),children:"✕"})]}):null,Mt?i.jsxs("div",{className:"admin-row-msg chat-routing-notice",children:[i.jsxs("span",{children:["📁 ",Mt]})," ",i.jsx("button",{className:"chat-routing-notice-dismiss",type:"button","aria-label":"Dismiss workspace notice",onClick:()=>an(null),children:"✕"})]}):null,or?i.jsxs("div",{className:"admin-row-msg chat-scratch-notice","data-testid":"chat-scratch-notice",children:[i.jsxs("span",{children:["🗂️ No folder was attached, so this turn used a temporary workspace:"," ",i.jsx("code",{className:"chat-scratch-path",children:or})]})," ",i.jsx("button",{type:"button",className:"admin-mini-btn",title:"Attach this folder to the chat and keep working in it",onClick:()=>{var H;const A=or;In(null),(H=at.current)==null||H.call(at,A)},children:"✓ Use as my project path"})," ",i.jsx("button",{type:"button",className:"admin-mini-btn",title:"Attach a folder of your own — the next turn runs inside it",onClick:()=>{var A;In(null),(A=Gn.current)==null||A.focus()},children:"📁 Attach my own folder"})," ",i.jsx("button",{type:"button",className:"chat-routing-notice-dismiss","aria-label":"Dismiss temporary workspace notice",onClick:()=>In(null),children:"✕"})]}):null,m?i.jsx("div",{className:`admin-row-msg${m.kind==="err"?" admin-row-msg-err":""}`,children:m.text}):null,q&&!d?i.jsxs("div",{className:"chat-retry-row",children:[i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:()=>void ln(q),children:"↻ Retry"}),i.jsx("span",{className:"admin-hint",children:"Re-send the last message — the turn failed."})]}):null,It?i.jsxs("div",{className:"chat-resolve-card chat-question-card",children:[i.jsx("div",{className:"chat-resolve-head",children:i.jsxs("strong",{children:["🤔 ",It.question]})}),i.jsx("div",{className:"chat-resolve-options",children:It.choices.map((A,H)=>i.jsxs("button",{type:"button",className:`chat-chip${Qi.has(H)?" chat-chip-selected":""}`,onClick:()=>Ed(H),children:[A.label,A.description?i.jsxs("span",{className:"admin-hint",children:[" — ",A.description]}):null]},`${A.label}-${H}`))}),i.jsx("input",{className:"chat-question-custom",type:"text",placeholder:"✏️ Or type your own answer…",value:Qr,onChange:A=>gd(A.target.value),onKeyDown:A=>{A.key==="Enter"&&!A.shiftKey&&(A.preventDefault(),Jl())}}),i.jsxs("div",{className:"chat-resolve-foot",children:[i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:Jl,children:Qr.trim()?"Send answer":It.multiSelect?"Submit":"Choose"}),i.jsx("button",{className:"admin-mini-btn",type:"button",onClick:Nd,children:"Skip — best judgment"})]})]}):null,V.length>0&&!d?i.jsxs("div",{className:"chat-followups",children:[i.jsx("span",{className:"admin-hint",children:"Next steps:"}),V.map((A,H)=>i.jsx("button",{className:"chat-chip",type:"button",onClick:()=>void ln(A.prompt),children:A.label||A.prompt},H))]}):null,i.jsxs("form",{className:`chat-composer${Gi?" chat-composer-drag":""}`,onSubmit:A=>{A.preventDefault(),ln(c)},onDragOver:A=>{A.preventDefault(),qi(!0)},onDragLeave:()=>qi(!1),onDrop:A=>{var Y;A.preventDefault(),qi(!1);const H=Array.from(((Y=A.dataTransfer)==null?void 0:Y.files)??[]);for(const he of H.slice(0,10))Gl(he)},children:[wa?i.jsxs("div",{className:"chat-paste-offer",children:[i.jsxs("span",{className:"admin-hint",children:["📄 You pasted ",bt(wa.text.length)," characters. Attach it as a file instead?"]}),i.jsx("button",{type:"button",className:"chat-chip",onClick:vd,children:"Attach as text"}),i.jsx("button",{type:"button",className:"chat-mini-action",onClick:()=>{qn(null),Qa.current=null},children:"Keep inline"})]}):null,_r.length>0?i.jsx("div",{className:"chat-attach-row",children:_r.map((A,H)=>i.jsxs("span",{className:"chat-attach-chip",title:A.encoding==="base64"?`${A.name} (${bt(A.content.length)} base64 chars — read on the server)`:`${A.name} (${bt(A.content.length)} chars)`,children:["📎 ",A.name,i.jsx("span",{className:"admin-hint",children:A.encoding==="base64"?`${Math.round(A.content.length*3/4096)} KB`:`${bt(A.content.length)}c`}),i.jsx("button",{type:"button",className:"chat-mini-action",onClick:()=>$m(H),children:"✕"})]},`${A.name}-${H}`))}):null,i.jsxs("div",{className:"chat-controls",children:[i.jsx("input",{ref:Qs,type:"file",accept:".pdf,.docx,.xlsx,.pptx,.txt,.md,.markdown,.text,.log,.csv,.tsv,.json,.xml,.yaml,.yml,.html,.htm,text/*",style:{display:"none"},onChange:A=>{var Y;const H=(Y=A.target.files)==null?void 0:Y[0];H&&Gl(H),A.target.value=""}}),i.jsx("button",{type:"button",className:"chat-attach-btn",title:"Attach a file (up to 300 KB): PDF, DOCX, XLSX, PPTX or text — documents are read on the server",disabled:d||_r.length>=10,onClick:()=>{var A;return(A=Qs.current)==null?void 0:A.click()},children:"📎 attach"}),i.jsx("button",{type:"button",className:"chat-attach-btn","aria-label":"Download support bundle",title:"Download a support bundle for this chat: the session debug log (which backend served each turn) plus the conversation. Needs NUVIRA_DEBUG_LOG=1 in the dashboard process.",onClick:()=>void Sd(),children:"🐞 debug"}),i.jsxs("button",{type:"button",className:`chat-attach-btn${y?" chat-attach-btn-on":""}`,"aria-label":"Run turns in an isolated git worktree","aria-pressed":y,title:y?"Turns run in their own git worktree and report the diff — click to run in the project tree again":"Run turns in their own git worktree of the attached project, and report the diff against the base commit. Refuses rather than running in your tree when the directory cannot be isolated. Needs an attached project (or the server's own git working directory).",onClick:()=>{v(A=>!A),g(null)},children:["🌿",y?" isolated":" isolate"]}),i.jsxs("button",{type:"button",className:`chat-attach-btn${j?" chat-attach-btn-on":""}`,"aria-label":"Replay this ask's recorded steps instead of paying for them again","aria-pressed":j,title:j?"Recorded steps whose input is unchanged are replayed instead of paid for — click to run fresh again":"Replay the steps of an earlier run of this same ask whose input is unchanged, instead of paying for them again. The record is keyed by the ask and the directory; name a checkpoint id below to resume a specific one. A step whose input CHANGED is paid for again.",onClick:()=>{S(A=>!A),g(null)},children:["↩️",j?" resuming":" resume"]}),j?i.jsx("input",{className:"chat-resume-input",value:x,onChange:A=>N(A.target.value),placeholder:"checkpoint id (blank = this ask's record)",title:"Resume this specific checkpoint record. Blank resumes the record for this ask in this directory.","aria-label":"Checkpoint id to resume",disabled:d}):null,y?i.jsxs("button",{type:"button",className:`chat-attach-btn${k?" chat-attach-btn-on":""}`,"aria-pressed":k,title:k?"The worktree is KEPT after the turn so you can look inside it":"The worktree is measured and removed after each turn",onClick:()=>w(A=>!A),children:["📌",k?" keep":" drop"]}):null,i.jsxs("select",{className:"chat-model-picker","aria-label":"Model: Auto or a specific routable model",title:T?`Pinned to ${T.provider}/${T.model} for this chat. Choose Auto to let the agent route again.`:"Auto (default): the agent picks the best routable model each turn. Choose one to pin it for this chat.",value:T?`${T.provider}|${T.model}`:"",disabled:d,onChange:A=>{const H=A.target.value;if(!H){B(null);return}const Y=H.indexOf("|");B({provider:H.slice(0,Y),model:H.slice(Y+1)})},children:[i.jsx("option",{value:"",children:"🤖 Auto (agent decides)"}),T&&!D.some(A=>A.provider===T.provider&&A.model===T.model)?i.jsxs("option",{value:`${T.provider}|${T.model}`,children:[T.provider,"/",T.model," · pinned"]}):null,D.map(A=>i.jsxs("option",{value:`${A.provider}|${A.model}`,children:[A.provider,"/",A.model," · ",A.band," (",A.capability.toFixed(2),")"]},`${A.provider}|${A.model}`))]}),T?i.jsx("button",{type:"button",className:`chat-attach-btn${$?" chat-attach-btn-on":""}`,"aria-label":"Strict model pin: use this model only","aria-pressed":$,disabled:d,title:$?`Strict: this chat runs on ${T.provider}/${T.model} only. If it is unavailable the turn stops instead of substituting another model.`:`Auto routing may substitute another model if ${T.provider}/${T.model} is unavailable. Turn on strict mode to work with this model only.`,onClick:()=>I(A=>!A),children:$?"🔒 strict":"🔓 auto-fallback"}):null,i.jsx("button",{type:"button",className:`chat-attach-btn${E==="max"?" chat-attach-btn-on":""}`,"aria-label":"Capability mode: balanced or max","aria-pressed":E==="max",disabled:d,title:E==="max"?"Max capability: every turn routes to a strong model (a reasoning floor — not merely “paid”), cost ceilings are lifted, paid models are always allowed, and the loop gets its longest reasoning budget. Click to return to balanced.":"Balanced (default): the best model for complex/critical work and cheaper models for simple work, escalating when a stall is detected. Click for max capability — cost is not a concern.",onClick:()=>void kd(),children:E==="max"?"⚡ max":"⚖️ balanced"}),_?i.jsx("span",{className:"admin-hint",children:_}):null]}),i.jsxs("div",{className:"chat-input-row",children:[i.jsx("textarea",{className:"chat-input-box",value:c,onChange:A=>u(A.target.value),onPaste:Lm,onKeyDown:A=>{A.key==="Enter"&&!A.shiftKey?(A.preventDefault(),ln(c)):A.key==="ArrowUp"&&c===""&&Ft.current&&(A.preventDefault(),u(Ft.current))},placeholder:"Message the agent… (Enter to send · Shift+Enter for a new line · ↑ recalls last · 📎 attach a file or paste a large document)",disabled:d,maxLength:8e3,rows:1,autoFocus:!0}),d?i.jsx("button",{className:"admin-mini-btn chat-cancel-btn",type:"button",onClick:wd,children:"⏹ Cancel"}):null,i.jsx("button",{className:"admin-refresh-btn",type:"submit",disabled:d||!c.trim()&&_r.length===0,children:d?"⏳ Working…":"➤ Send"})]})]}),i.jsxs("p",{className:"admin-hint",children:["Each message runs the full agent loop in the dashboard process (same engine as"," ",i.jsx("code",{children:'nuvira chat "<prompt>"'}),") — the provider API keys must be configured in the dashboard process. Clarifications (",i.jsx("code",{children:"ask_user"}),") appear as a question card here — choose an answer or skip (best judgment)."]})]})]})]}):i.jsx("div",{className:"admin-login-hint",children:i.jsx("p",{children:"Your role can view the dashboard but not chat (requires admin or operator)."})}):i.jsxs("div",{className:"admin-login-hint",children:[i.jsx("p",{children:"Log in (admin or operator) to chat with the agent. Configure the dashboard admin credential first if this is a fresh setup."}),(t==null?void 0:t.configured)===!1?i.jsxs("p",{className:"admin-hint",children:["Run ",i.jsx("code",{children:"nuvira dashboard"})," once, or set ",i.jsx("code",{children:"NUVIRA_DASHBOARD_ADMIN_USER"})," / ",i.jsx("code",{children:"NUVIRA_DASHBOARD_ADMIN_PASSWORD"}),"."]}):null]})]})}const vbe={running:"⏳ running",done:"✅ done",failed:"❌ failed",cancelled:"⏹ cancelled",timeout:"⏰ timed out",error:"💥 error",hung:"🚫 stopped (hung)"},ybe=0;function j$({presets:e,customPlaceholder:t,timeoutMs:n=ybe,hint:r}){const[a,s]=b.useState(null),o=qr(),[l,c]=b.useState(!1),[u,d]=b.useState(""),[f,h]=b.useState(""),[p,m]=b.useState(null),[g,y]=b.useState([]),[v,k]=b.useState(0),w=b.useRef(null),j=b.useRef(null),S=b.useRef(Date.now());b.useEffect(()=>{K.fetchAdminAuthStatus().then(P=>{s(P?{authenticated:P.authenticated,role:P.role??null}:{authenticated:!1,role:null})})},[o]),b.useEffect(()=>{var P,_;try{(_=(P=w.current)==null?void 0:P.scrollIntoView)==null||_.call(P,{block:"end"})}catch{}},[g]),b.useEffect(()=>()=>{var P;(P=j.current)==null||P.call(j)},[]);const x=(a==null?void 0:a.authenticated)===!0&&(a.role==="admin"||a.role==="operator"),N=b.useCallback(async(P,_)=>{var $;if(l)return;c(!0),d(""),y([]),S.current=Date.now(),k(0);const R=await K.startTask(P,_??n);if(!R.ok||!R.task){d(R.error||"Could not start the command."),c(!1);return}const T=R.task;m(T);const B=await K.getTask(T.id);B!=null&&B.task&&y(B.task.logs.map(I=>({stream:I.stream,text:I.text}))),($=j.current)==null||$.call(j),j.current=K.subscribeTask(T.id,{onLog:I=>y(D=>[...D,{stream:I.stream,text:I.text}]),onStatus:I=>{m(D=>D&&{...D,status:I}),I!=="running"&&c(!1)}})},[l,n]),E=b.useCallback(async()=>{p&&await K.cancelTask(p.id)},[p]);return b.useEffect(()=>{if(!l)return;const P=setInterval(()=>k(Date.now()-S.current),1e3);return()=>clearInterval(P)},[l]),i.jsxs("div",{className:"ops-console",children:[a!=null&&a.authenticated?x?i.jsxs(i.Fragment,{children:[i.jsx("div",{className:"ops-presets",children:e.map(P=>i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:()=>void N(P.args,P.timeoutMs),disabled:l,children:P.label},P.label))}),i.jsxs("div",{className:"ops-custom-row",children:[i.jsx("input",{type:"text",value:f,onChange:P=>h(P.target.value),placeholder:t,disabled:l,maxLength:160}),i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:()=>void N(f.trim().split(/\s+/)),disabled:l||!f.trim(),children:"Run"})]}),r?i.jsx("p",{className:"admin-hint",children:r}):null]}):i.jsx("div",{className:"admin-login-hint",children:"Your role can view but not run commands (requires admin or operator)."}):i.jsx("div",{className:"admin-login-hint",children:"Log in (admin or operator) to run commands."}),u?i.jsx("div",{className:"admin-row-msg admin-row-msg-err",children:u}):null,p?i.jsxs("div",{className:"ops-console-box",children:[i.jsxs("div",{className:"ops-console-head",children:[i.jsxs("span",{children:[p.command," · ",i.jsx("span",{className:p.status==="running"?"task-status-running":"",children:vbe[p.status]})," · ",i.jsx("span",{className:"task-elapsed",children:p.status==="running"?Gb(v):Gb(p.durationMs??v)})]}),p.status==="running"?i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:()=>void E(),children:"⏹ Cancel"}):null]}),i.jsxs("pre",{className:"ops-console",role:"log",children:[g.length>0?g.map((P,_)=>i.jsx("div",{children:P.text},_)):i.jsx("div",{className:"admin-hint",children:"Waiting for output…"}),i.jsx("div",{ref:w})]})]}):null]})}const bbe=[{label:"⚡ Quick smoke",args:["eval","run","--tasks","quick","--format","text"]},{label:"⏱ Medium suite",args:["eval","run","--tasks","medium","--format","text"]},{label:"🐢 Slow suite",args:["eval","run","--tasks","slow","--format","text"]},{label:"🏆 M2B parity",args:["eval","run","--suite","m2b","--format","text"]},{label:"📦 Full suite",args:["eval","run","--suite","full","--format","text"]}];function eC(e){return typeof e!="number"?"—":`${Math.round(e*100)}%`}function xbe(e){return new Date(e).toLocaleString()}function wbe({data:e}){var n;const t=((n=e==null?void 0:e.evals)==null?void 0:n.runs)??[];return i.jsxs("div",{className:"panel",children:[i.jsx(Oe,{icon:"🏆",title:"Evals — run nuvira eval from the GUI"}),i.jsx(j$,{presets:bbe,customPlaceholder:"e.g. eval run --tasks my-task --provider groq --model llama",timeoutMs:9e5,hint:i.jsxs(i.Fragment,{children:["Runs the real ",i.jsx("code",{children:"nuvira eval run"})," as an isolated process — same engine, same ledger, same results as the CLI. Long suites can take minutes; you can cancel mid-run."]})}),i.jsx("h2",{className:"section-subtitle",children:"📜 Past runs (auto-refreshes)"}),t.length>0?i.jsx("div",{className:"admin-table-wrapper",children:i.jsxs("table",{className:"admin-table",children:[i.jsx("thead",{children:i.jsxs("tr",{children:[i.jsx("th",{children:"Started"}),i.jsx("th",{children:"Provider"}),i.jsx("th",{children:"Model"}),i.jsx("th",{children:"Tasks"}),i.jsx("th",{children:"Pass"}),i.jsx("th",{children:"Completion"}),i.jsx("th",{children:"Composite"}),i.jsx("th",{children:"Cost"})]})}),i.jsx("tbody",{children:t.map(r=>i.jsxs("tr",{children:[i.jsx("td",{children:xbe(r.startedAt)}),i.jsx("td",{className:"admin-provider-type",children:r.provider}),i.jsx("td",{children:r.model}),i.jsx("td",{children:r.summary.totalTasks}),i.jsxs("td",{children:[r.summary.tasksPassed,"/",r.summary.totalTasks]}),i.jsx("td",{children:eC(r.summary.completionRate)}),i.jsx("td",{children:eC(r.summary.avgCompositeScore)}),i.jsxs("td",{children:["$",(r.summary.totalCostUsd??0).toFixed(4)]})]},r.id))})]})}):i.jsx("div",{className:"empty-state",children:"No eval runs yet — start one above (or `nuvira eval run` from the CLI)."})]})}const kbe=[{label:"🌐 Gateway status",args:["gateway","status"]},{label:"📮 Delivery ledger",args:["gateway","delivery"]},{label:"▶️ Start gateway (foreground)",args:["gateway","start","--no-events"],timeoutMs:0},{label:"⏰ Cron jobs",args:["admin","cron","list"]}];function Sbe(){return i.jsxs("div",{className:"panel",children:[i.jsx(Oe,{icon:"🌐",title:"Gateway ops — run nuvira gateway from the GUI"}),i.jsx(j$,{presets:kbe,customPlaceholder:"e.g. admin cron run nightly or gateway alias add ops email:team@example.com",timeoutMs:0,hint:i.jsxs(i.Fragment,{children:["Each command runs as the real CLI in an isolated process (the P1 task runner) — the same engine as your terminal — and runs ",i.jsx("strong",{children:"until it finishes or you press Cancel"})," (no 5-minute cutoff). The elapsed time is shown beside the status, and work continues after you switch tabs (the process lives on the dashboard server, not the page). The delivery ledger also has its own view in"," ",i.jsx("strong",{children:"Agent Hub → Channels"}),"."]})})]})}const vv={telegram:{icon:"✈️",category:"Chat",steps:["Open Telegram and search for @BotFather","Send /newbot and follow the prompts",'Give your bot a name (e.g. "My Agent Bot")','Give your bot a username ending in "bot"',"BotFather gives you a token — paste it in Step 2","Open your bot in Telegram and send /start"],testTarget:"telegram:"},discord:{icon:"🎮",category:"Chat",steps:["Go to discord.com/developers/applications",'Click "New Application" and give it a name','Go to Bot tab and click "Add Bot"',"Copy the bot token",'Enable "Message Content Intent"',"Invite bot to your server (OAuth2 URL generator)"],testTarget:"discord:"},slack:{icon:"💬",category:"Chat",steps:["Go to api.slack.com/apps","Create New App from scratch","Add Bot Token Scopes: chat:write, im:read, im:write","Install to workspace","Copy the Bot User OAuth Token (xoxb-...)"],testTarget:"slack:"},whatsapp:{icon:"📱",category:"Chat",steps:["Run: nuvira whatsapp pair (or from Gateway tab)","Scan the QR code with WhatsApp","Pairing completes automatically"],testTarget:""},whatsapp_cloud:{icon:"☁️",category:"Chat",steps:["Go to developers.facebook.com","Set up WhatsApp Cloud API","Copy token + Phone ID"],testTarget:"whatsapp_cloud:"},email:{icon:"📧",category:"Chat",steps:["Get SMTP credentials (Gmail, SendGrid, etc.)","For Gmail: use App Password at smtp.gmail.com:587","Paste SMTP host + user below"],testTarget:""},signal:{icon:"🔒",category:"Chat",steps:["Run signal-cli-rest-api Docker container","Register a Signal account","Paste account number below"],testTarget:""},dingtalk:{icon:"🔔",category:"Webhooks",steps:["Open DingTalk and create a group","Add custom robot and copy webhook URL","Paste URL below"],testTarget:""},feishu:{icon:"🐦",category:"Webhooks",steps:["Open Feishu and create a bot","Copy webhook URL and paste below"],testTarget:""},wecom:{icon:"🏢",category:"Webhooks",steps:["Open WeCom and create a group bot","Copy webhook URL and paste below"],testTarget:""},mattermost:{icon:"📋",category:"Webhooks",steps:["Open Mattermost, go to Integrations","Create incoming webhook and copy URL"],testTarget:""},matrix:{icon:"🔗",category:"Chat",steps:["Get your Matrix homeserver URL","Create a bot user and get access token","Paste URL + token below"],testTarget:""},webhook:{icon:"🪝",category:"Webhooks",steps:["Enter your webhook URL","The agent sends outbound webhooks to this URL"],testTarget:""},bluebubbles:{icon:"💙",category:"Chat",steps:["Set up BlueBubbles server","Copy server URL + password"],testTarget:""},ntfy:{icon:"📢",category:"Notifications",steps:["Choose an ntfy topic (or use ntfy.sh)","Paste the topic below"],testTarget:""},teams:{icon:"👥",category:"Webhooks",steps:["Open Microsoft Teams, go to channel","Connectors, Incoming Webhook, create","Copy webhook URL"],testTarget:""},google_chat:{icon:"💬",category:"Webhooks",steps:["Open Google Chat, space settings","Create webhook and copy URL"],testTarget:""},weixin:{icon:"🔴",category:"Chat",steps:["Get Weixin iLink bot token","Paste token below"],testTarget:""},sms:{icon:"📲",category:"Chat",steps:["Get Twilio account SID + auth token","Register a phone number","Paste credentials below"],testTarget:""},irc:{icon:"💻",category:"Chat",steps:["Choose an IRC server (e.g. irc.libera.chat)","Set nickname + channel and paste below"],testTarget:""},simplex:{icon:"📨",category:"Chat",steps:["Run local simplex-chat daemon","Paste WebSocket URL (ws://127.0.0.1:5225)"],testTarget:""},homeassistant:{icon:"🏠",category:"IoT",steps:["Open Home Assistant Profile","Create long-lived access token and paste below"],testTarget:""}};function jbe(){const[e,t]=b.useState(null),[n,r]=b.useState("all"),[a,s]=b.useState(null),[o,l]=b.useState(0),[c,u]=b.useState({}),[d,f]=b.useState(!1),[h,p]=b.useState(null),[m,g]=b.useState({status:"idle"}),[y,v]=b.useState(""),[k,w]=b.useState("Hello from agent-nuvira!"),[j,S]=b.useState(!1),[x,N]=b.useState(null),E=b.useRef(!0),P=b.useCallback(async()=>{const M=await K.getPlatformConfigs();E.current&&t(M)},[]);b.useEffect(()=>(P(),()=>{E.current=!1}),[P]);const _=M=>{s(M),l(0),u(Object.fromEntries(M.envVars.map(O=>[O.varName,O.value]))),p(null),g({status:"idle"});const z=vv[M.platform];v((z==null?void 0:z.testTarget)??""),w("Hello from agent-nuvira!"),N(null)},R=async()=>{if(!a)return;g({status:"checking"});const M=await K.verifyPlatformConfig(a.platform,c);M.ok?(g({status:"ok",info:M.info}),p({kind:"ok",text:"Verified! "+(M.info?"Connected as "+M.info+".":"Token is valid.")})):(g({status:"err",error:M.error}),p({kind:"err",text:M.error||"Verification failed."}))},T=async()=>{if(!a)return;f(!0),p(null);const M=await K.setPlatformConfig(a.platform,c);f(!1),M.ok?(p({kind:"ok",text:"Token saved! Verifying..."}),P(),l(2),R()):p({kind:"err",text:M.error||"Save failed."})},B=async()=>{if(!a||!y)return;S(!0),N(null);const M=await K.sendChannelMessage(y,k);S(!1),M.ok?N({kind:"ok",text:"Message sent via "+M.platform+"! Check your "+a.label+" app."}):N({kind:"err",text:M.error||"Send failed. Make sure the gateway is running (Gateway tab)."})};if(e===null)return i.jsx("div",{className:"empty-state",children:"Loading platforms..."});const $=e.filter(M=>M.configured).length,I=e.filter(M=>n==="configured"?M.configured:n==="unconfigured"?!M.configured:!0),D=a?vv[a.platform]:null;function U(M){return o===M?"wizard-step-dot active":"wizard-step-dot"}return i.jsxs("div",{className:"panel",children:[i.jsx(Oe,{icon:"🌐",title:"Platforms — Messaging Gateway Onboarding"}),i.jsxs("div",{className:"platforms-summary",children:[i.jsxs("div",{className:"platforms-summary-stat",children:[i.jsx("span",{className:"platforms-summary-number",children:$}),i.jsx("span",{className:"platforms-summary-label",children:"configured"})]}),i.jsxs("div",{className:"platforms-summary-stat",children:[i.jsx("span",{className:"platforms-summary-number",children:e.length-$}),i.jsx("span",{className:"platforms-summary-label",children:"available"})]}),i.jsx("div",{className:"platforms-summary-filters",children:["all","configured","unconfigured"].map(M=>i.jsx("button",{type:"button",className:n===M?"platforms-filter-btn active":"platforms-filter-btn",onClick:()=>r(M),children:M==="all"?"All":M==="configured"?"Configured":"Not set up"},M))})]}),i.jsx("div",{className:"platforms-grid",children:I.map(M=>{const z=vv[M.platform];return i.jsxs("div",{className:M.configured?"platform-card configured":"platform-card",children:[i.jsxs("div",{className:"platform-card-head",children:[i.jsx("span",{className:"platform-card-icon",children:(z==null?void 0:z.icon)??"🔌"}),i.jsxs("div",{className:"platform-card-info",children:[i.jsx("span",{className:"platform-card-name",children:M.label}),i.jsx("span",{className:"platform-card-category",children:(z==null?void 0:z.category)??"Platform"})]}),i.jsx("span",{className:M.configured?"status-dot connected":"status-dot reconnecting"})]}),i.jsx("div",{className:"platform-card-vars",children:M.envVars.map(O=>i.jsxs("span",{className:O.set?"platform-var-chip set":"platform-var-chip",children:[O.varName," ",O.set?"done":"--"]},O.varName))}),i.jsxs("div",{className:"platform-card-actions",children:[M.configured?i.jsx("span",{className:"platform-card-badge",children:"Active"}):i.jsx("button",{type:"button",className:"wizard-start-btn",onClick:()=>_(M),children:"Setup"}),M.setupUrl?i.jsx("a",{href:M.setupUrl,target:"_blank",rel:"noopener noreferrer",className:"admin-mini-btn platform-docs-link",children:"Docs"}):null]}),!M.configured&&M.setupHint?i.jsx("div",{className:"platform-card-hint",children:M.setupHint}):null]},M.platform)})}),i.jsxs("div",{className:"platforms-cli-hint",children:[i.jsx("span",{className:"admin-hint",children:"Prefer the terminal? "}),i.jsx("code",{children:"nuvira gateway setup telegram"}),i.jsx("span",{className:"admin-hint",children:" — same wizard from your CLI"})]}),a&&D?i.jsx("div",{className:"wizard-overlay",onClick:()=>s(null),children:i.jsxs("div",{className:"wizard-modal",onClick:M=>M.stopPropagation(),children:[i.jsxs("div",{className:"wizard-header",children:[i.jsx("span",{className:"wizard-icon",children:D.icon}),i.jsxs("span",{className:"wizard-title",children:["Getting Started: ",a.label]}),i.jsxs("div",{className:"wizard-steps-indicator",children:[i.jsx("span",{className:U(0),children:"1"}),i.jsx("span",{className:U(1),children:"2"}),i.jsx("span",{className:U(2),children:"3"})]}),i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>s(null),children:"X"})]}),i.jsxs("div",{className:"wizard-body",children:[o===0&&i.jsxs(i.Fragment,{children:[i.jsxs("p",{className:"wizard-section-title",children:["Step 1: Create your bot on ",a.label]}),i.jsx("ol",{className:"wizard-steps",children:D.steps.map((M,z)=>i.jsx("li",{children:M},z))}),i.jsxs("div",{className:"wizard-nav",children:[i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>l(1),children:"I have my token — Step 2"}),a.setupUrl?i.jsx("a",{href:a.setupUrl,target:"_blank",rel:"noopener noreferrer",className:"admin-mini-btn platform-docs-link",children:"Open docs"}):null]})]}),o===1&&i.jsxs(i.Fragment,{children:[i.jsx("p",{className:"wizard-section-title",children:"Step 2: Paste your token"}),a.envVars.map(M=>i.jsxs("label",{className:"hub-send-target",children:[i.jsx("span",{className:"admin-hint",children:M.prompt}),i.jsx("input",{type:M.secret?"password":"text",value:c[M.varName]??"",onChange:z=>u(O=>({...O,[M.varName]:z.target.value})),placeholder:M.secret?"paste your token here":"value",autoComplete:"off",spellCheck:!1,autoFocus:!0})]},M.varName)),h?i.jsx("div",{className:h.kind==="ok"?"admin-row-msg":"admin-row-msg admin-row-msg-err",children:h.text}):null,i.jsxs("div",{className:"wizard-nav",children:[i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>l(0),children:"Back"}),i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>void T(),disabled:d,children:d?"Saving...":"Save & Verify"})]})]}),o===2&&i.jsxs(i.Fragment,{children:[i.jsx("p",{className:"wizard-section-title",children:"Step 3: Verify and test"}),m.status==="checking"&&i.jsx("div",{className:"wizard-verify-status",children:"Verifying token..."}),m.status==="ok"&&i.jsxs("div",{className:"wizard-verify-status ok",children:["Connected as ",m.info]}),m.status==="err"&&i.jsx("div",{className:"wizard-verify-status err",children:m.error}),m.status==="idle"&&(h==null?void 0:h.kind)==="ok"&&i.jsx("div",{className:"wizard-verify-status ok",children:h.text}),y&&i.jsxs("div",{className:"wizard-test-section",children:[i.jsx("p",{className:"wizard-section-title",children:"Send a test message:"}),i.jsx("div",{className:"wizard-test-row",children:i.jsx("input",{className:"wizard-test-input",value:y,onChange:M=>v(M.target.value),placeholder:"telegram:YOUR_CHAT_ID"})}),i.jsxs("div",{className:"wizard-test-row",children:[i.jsx("input",{className:"wizard-test-input",value:k,onChange:M=>w(M.target.value),placeholder:"Hello from agent-nuvira!"}),i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>void B(),disabled:j||!y,children:j?"Sending...":"Send test"})]}),x?i.jsx("div",{className:x.kind==="ok"?"admin-row-msg":"admin-row-msg admin-row-msg-err",children:x.text}):null]}),i.jsxs("div",{className:"wizard-nav",children:[i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>l(1),children:"Edit token"}),i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>s(null),children:"Done"})]}),!y&&i.jsxs("p",{className:"wizard-hint",children:["Token saved! Start the gateway from the Gateway tab, then send a message from your ",a.label," app."]})]})]})]})}):null]})}const Nbe=[{value:"us-east-1",label:"us-east-1 (N. Virginia) — most models"},{value:"us-west-2",label:"us-west-2 (Oregon) — most models"},{value:"eu-west-1",label:"eu-west-1 (Ireland) — EU coverage"},{value:"ap-southeast-1",label:"ap-southeast-1 (Singapore)"},{value:"ap-northeast-1",label:"ap-northeast-1 (Tokyo)"}],tC=[{name:"Anthropic Claude",models:["claude-haiku-4.5","claude-sonnet-4.6","claude-fable-5","claude-opus-4.6"],checked:!0},{name:"Meta Llama",models:["llama3-1-8b","llama3-1-70b","llama3-3-70b","llama4-scout","llama4-maverick"],checked:!0},{name:"Mistral AI",models:["mistral-large-3","devstral-2","ministral-3"],checked:!1},{name:"DeepSeek",models:["deepseek-v3.2","deepseek-r1"],checked:!1},{name:"Amazon Nova",models:["nova-pro","nova-lite"],checked:!1},{name:"OpenAI on Bedrock",models:["gpt-5.6-terra","gpt-oss-120b"],checked:!1},{name:"Qwen",models:["qwen3-coder-next","qwen3-32b"],checked:!1},{name:"Google Gemma",models:["gemma-3-12b"],checked:!1},{name:"xAI",models:["grok-4.6"],checked:!1}];function Ebe({canWrite:e,sessionExpired:t}){const[n,r]=b.useState(null),[a,s]=b.useState(null),[o,l]=b.useState(!1),[c,u]=b.useState("overview"),d=b.useRef(!0),[f,h]=b.useState("bearer"),[p,m]=b.useState(""),[g,y]=b.useState(""),[v,k]=b.useState(""),[w,j]=b.useState("us-east-1"),[S,x]=b.useState(tC.filter($=>$.checked).map($=>$.name)),[N,E]=b.useState(!1),[P,_]=b.useState(null),R=b.useCallback(async()=>{const $=await K.getBedrockStatus();d.current&&r($)},[]);b.useEffect(()=>(R(),()=>{d.current=!1}),[R]);const T=async()=>{l(!0),s(null);try{const $=await K.probeBedrock((n==null?void 0:n.region)||"us-east-1");if(!d.current)return;$.ok&&$.models&&(s($.models),u("test"))}catch{}finally{d.current&&l(!1)}},B=async()=>{E(!0),_(null);try{const $={BEDROCK_REGION:w};f==="bearer"&&p?$.AWS_BEARER_TOKEN=p:f==="iam"&&(g&&($.AWS_ACCESS_KEY_ID=g),v&&($.AWS_SECRET_ACCESS_KEY=v));const I=await K.setupBedrock($);if(!d.current)return;I.ok?(_({kind:"ok",text:"✅ Configuration saved! Running connectivity test…"}),u("overview"),await R(),setTimeout(()=>void T(),500)):_({kind:"err",text:I.error||"Save failed"})}catch{d.current&&_({kind:"err",text:"Could not reach the dashboard server."})}finally{d.current&&E(!1)}};return n===null?i.jsx("div",{className:"empty-state",children:"Loading Bedrock status…"}):i.jsxs("div",{className:"bedrock-onboarding",children:[i.jsx(Oe,{icon:"🟠",title:"AWS Bedrock"}),i.jsxs("p",{className:"admin-subtitle",children:["Bedrock gives you access to Claude, Llama, Mistral, DeepSeek, and more — all through a single AWS account. Unlike other providers, Bedrock requires a ",i.jsx("strong",{children:"region"}),", ",i.jsx("strong",{children:"AWS credentials"}),", and explicit ",i.jsx("strong",{children:"model access approval"}),"."]}),P?i.jsx("div",{className:`admin-row-msg${P.kind==="ok"?"":" admin-row-msg-err"}`,children:P.text}):null,i.jsxs("div",{className:"bedrock-status-bar",children:[i.jsxs("div",{className:"bedrock-status-item",children:[i.jsx("span",{className:`status-dot ${n.configured?"connected":"reconnecting"}`}),i.jsx("span",{children:n.configured?"Configured":"Not configured"})]}),i.jsxs("div",{className:"bedrock-status-item",children:[i.jsx("span",{className:"bedrock-status-label",children:"Region:"}),i.jsx("code",{children:n.region})]}),i.jsxs("div",{className:"bedrock-status-item",children:[i.jsx("span",{className:"bedrock-status-label",children:"Auth:"}),i.jsx("code",{children:n.authMethod==="bearer"?"API Key":n.authMethod==="iam"?"IAM":"None"})]}),i.jsxs("div",{className:"bedrock-status-actions",children:[e?i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>u(c==="setup"?"overview":"setup"),children:c==="setup"?"✕ Cancel":"⚙ Setup Wizard"}):null,n.configured?i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>void T(),disabled:o,children:o?"⏳ Probing…":"🔍 Test Models"}):null]})]}),c==="setup"&&i.jsxs("div",{className:"bedrock-setup-wizard",children:[i.jsx("h2",{className:"section-subtitle",children:"🚀 Bedrock Setup Wizard"}),i.jsxs("div",{className:"bedrock-wizard-step",children:[i.jsx("h4",{children:"Step 1: Authentication"}),i.jsxs("div",{className:"bedrock-auth-options",children:[i.jsxs("label",{className:`bedrock-auth-option ${f==="bearer"?"selected":""}`,children:[i.jsx("input",{type:"radio",name:"authMethod",checked:f==="bearer",onChange:()=>h("bearer")}),i.jsxs("div",{children:[i.jsx("strong",{children:"Bedrock API Key"}),i.jsx("span",{children:"Simpler — get from Bedrock → Settings → API keys"})]})]}),i.jsxs("label",{className:`bedrock-auth-option ${f==="iam"?"selected":""}`,children:[i.jsx("input",{type:"radio",name:"authMethod",checked:f==="iam",onChange:()=>h("iam")}),i.jsxs("div",{children:[i.jsx("strong",{children:"IAM Credentials"}),i.jsx("span",{children:"Full AWS SDK auth — AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY"})]})]})]}),f==="bearer"?i.jsxs("div",{className:"bedrock-wizard-fields",children:[i.jsxs("div",{className:"bedrock-setup-hint",children:[i.jsx("strong",{children:"How to get a Bedrock API key:"}),i.jsxs("ol",{children:[i.jsxs("li",{children:["Open ",i.jsx("a",{href:"https://console.aws.amazon.com/bedrock/",target:"_blank",rel:"noopener noreferrer",children:"AWS Bedrock Console"})]}),i.jsxs("li",{children:["Go to ",i.jsx("strong",{children:"Settings"})," → ",i.jsx("strong",{children:"API keys"})]}),i.jsx("li",{children:"Create a new key and paste it below"})]})]}),i.jsxs("label",{className:"hub-send-target",children:[i.jsx("span",{className:"admin-hint",children:"Bedrock API Key (Bearer token)"}),i.jsx("input",{type:"password",value:p,onChange:$=>m($.target.value),placeholder:"••••••••••••",autoComplete:"off",spellCheck:!1})]})]}):i.jsxs("div",{className:"bedrock-wizard-fields",children:[i.jsxs("div",{className:"bedrock-setup-hint",children:[i.jsx("strong",{children:"IAM credentials"})," give full AWS SDK access. Create an IAM user with Bedrock permissions."]}),i.jsxs("label",{className:"hub-send-target",children:[i.jsx("span",{className:"admin-hint",children:"AWS_ACCESS_KEY_ID"}),i.jsx("input",{type:"text",value:g,onChange:$=>y($.target.value),placeholder:"AKIA...",autoComplete:"off",spellCheck:!1})]}),i.jsxs("label",{className:"hub-send-target",children:[i.jsx("span",{className:"admin-hint",children:"AWS_SECRET_ACCESS_KEY"}),i.jsx("input",{type:"password",value:v,onChange:$=>k($.target.value),placeholder:"••••••••••••",autoComplete:"off",spellCheck:!1})]})]})]}),i.jsxs("div",{className:"bedrock-wizard-step",children:[i.jsx("h4",{children:"Step 2: AWS Region"}),i.jsxs("p",{className:"admin-hint",children:["Models vary by region. ",i.jsx("strong",{children:"us-east-1"})," and ",i.jsx("strong",{children:"us-west-2"})," have the most models. ⚠️ Do NOT use eu-north-1 unless models are explicitly enabled there."]}),i.jsx("select",{className:"bedrock-region-select",value:w,onChange:$=>j($.target.value),children:Nbe.map($=>i.jsx("option",{value:$.value,children:$.label},$.value))})]}),i.jsxs("div",{className:"bedrock-wizard-step",children:[i.jsx("h4",{children:"Step 3: Model Access"}),i.jsx("p",{className:"admin-hint",children:"Bedrock requires you to request access for each model family."}),i.jsx("div",{className:"bedrock-model-access-hint",children:i.jsx("a",{href:`https://console.aws.amazon.com/bedrock/home?region=${w}#/modelaccess`,target:"_blank",rel:"noopener noreferrer",className:"admin-mini-btn",children:"📖 Open Model Access in AWS Console"})}),i.jsx("div",{className:"bedrock-family-grid",children:tC.map($=>i.jsxs("label",{className:`bedrock-family-card ${S.includes($.name)?"selected":""}`,children:[i.jsx("input",{type:"checkbox",checked:S.includes($.name),onChange:I=>{I.target.checked?x(D=>[...D,$.name]):x(D=>D.filter(U=>U!==$.name))}}),i.jsxs("div",{children:[i.jsx("strong",{children:$.name}),i.jsxs("span",{children:[$.models.length," model(s)"]})]})]},$.name))}),i.jsx("p",{className:"admin-hint",style:{marginTop:8},children:"In the AWS Console, select the families above and submit. Approval is usually instant for Anthropic and Meta models."})]}),i.jsxs("div",{className:"bedrock-wizard-actions",children:[i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>void B(),disabled:N||f==="bearer"&&!p||f==="iam"&&(!g||!v),children:N?"⏳ Saving…":"💾 Save & Test"}),i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>u("overview"),children:"Cancel"})]})]}),c==="test"&&a&&i.jsxs("div",{className:"bedrock-probe-results",children:[i.jsxs("h2",{className:"section-subtitle",children:["🔍 Model Probe Results (",n.region,")"]}),i.jsx("div",{className:"bedrock-probe-grid",children:a.map($=>i.jsxs("div",{className:`bedrock-probe-card bedrock-probe-${$.status}`,children:[i.jsx("span",{className:"bedrock-probe-icon",children:$.status==="accessible"?"✅":$.status==="permission-denied"?"🔒":$.status==="not-found"?"⚫":"❌"}),i.jsx("span",{className:"bedrock-probe-id",children:$.modelId}),i.jsx("span",{className:"bedrock-probe-status",children:$.status==="accessible"?"Ready":$.status==="permission-denied"?`Need access (HTTP ${$.httpStatus})`:$.status==="not-found"?"Not in this region":"Error"})]},$.modelId))}),a.some($=>$.status==="permission-denied")&&i.jsxs("div",{className:"bedrock-probe-action",children:[i.jsxs("p",{children:["Some models exist in ",n.region," but access is not approved."]}),i.jsx("a",{href:`https://console.aws.amazon.com/bedrock/home?region=${n.region}#/modelaccess`,target:"_blank",rel:"noopener noreferrer",className:"admin-mini-btn",children:"🔓 Request Model Access in AWS Console →"})]}),i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>u("overview"),style:{marginTop:12},children:"← Back"})]}),!n.configured&&c==="overview"&&i.jsxs("div",{className:"bedrock-getting-started",children:[i.jsx("h2",{className:"section-subtitle",children:"📋 Getting Started with Bedrock"}),i.jsxs("div",{className:"bedrock-steps",children:[i.jsxs("div",{className:"bedrock-step",children:[i.jsx("span",{className:"bedrock-step-num",children:"1"}),i.jsxs("div",{children:[i.jsx("strong",{children:"Create an AWS account"})," (or use existing)",i.jsxs("span",{children:["New to AWS? Sign up at ",i.jsx("a",{href:"https://aws.amazon.com/",target:"_blank",rel:"noopener noreferrer",children:"aws.amazon.com"})]})]})]}),i.jsxs("div",{className:"bedrock-step",children:[i.jsx("span",{className:"bedrock-step-num",children:"2"}),i.jsxs("div",{children:[i.jsx("strong",{children:"Get Bedrock API key"}),i.jsx("span",{children:"Bedrock → Settings → API keys → Create key"})]})]}),i.jsxs("div",{className:"bedrock-step",children:[i.jsx("span",{className:"bedrock-step-num",children:"3"}),i.jsxs("div",{children:[i.jsx("strong",{children:"Request model access"}),i.jsx("span",{children:"Bedrock → Model access → Select Claude, Llama, etc. → Submit"})]})]}),i.jsxs("div",{className:"bedrock-step",children:[i.jsx("span",{className:"bedrock-step-num",children:"4"}),i.jsxs("div",{children:[i.jsx("strong",{children:"Configure in this wizard"}),i.jsx("span",{children:'Click "Setup Wizard" above to enter your credentials'})]})]})]})]}),n.configured&&c==="overview"&&!a&&i.jsx("div",{className:"bedrock-quick-status",children:i.jsxs("p",{className:"admin-hint",children:["Bedrock is configured. Click ",i.jsx("strong",{children:"🔍 Test Models"})," to verify connectivity and discover which models are accessible in ",n.region,"."]})})]})}const yv=["whatsapp","whatsapp_cloud","telegram","signal","slack","discord","email"];function _be(){const[e,t]=b.useState([]),[n,r]=b.useState(!0),[a,s]=b.useState("all"),[o,l]=b.useState(null),[c,u]=b.useState(""),[d,f]=b.useState(""),[h,p]=b.useState(null),[m,g]=b.useState({}),[y,v]=b.useState({}),[k,w]=b.useState({}),[j,S]=b.useState(null),[x,N]=b.useState(!1),[E,P]=b.useState(!1),[_,R]=b.useState(!1),[T,B]=b.useState(12e4),$=b.useCallback(async()=>{r(!0);const ee=await K.getContacts();ee.ok&&ee.contacts&&t(ee.contacts);const Q=await K.gatewayPolicies();if(Q.ok&&Q.policies){const ae={};for(const ce of yv){const G=Q.policies[ce];G&&(ae[ce]={...G.outboundSenders!==void 0?{outboundSenders:G.outboundSenders}:{},...G.requireApprovedTarget!==void 0?{requireApprovedTarget:G.requireApprovedTarget}:{}})}g(ae),v(ae)}P(Q.askUserWait===!0),R(Q.askUserWait===!0),typeof Q.askUserTimeoutMs=="number"&&B(Q.askUserTimeoutMs),r(!1)},[]);b.useEffect(()=>{$()},[$]);const I=e.filter(ee=>a==="all"||ee.status===a),D=async ee=>{p(null);const Q=await K.approveContact(ee.platform,ee.name);p(Q.ok?{kind:"ok",text:`✅ ${ee.name} approved.`}:{kind:"err",text:Q.error||"Failed."}),$()},U=async ee=>{p(null);const Q=await K.rejectContact(ee.platform,ee.name);p(Q.ok?{kind:"ok",text:`🚫 ${ee.name} rejected.`}:{kind:"err",text:Q.error||"Failed."}),$()},M=async ee=>{p(null);const Q=await K.deleteContact(ee.platform,ee.name);p(Q.ok?{kind:"ok",text:`🗑️ ${ee.name} deleted.`}:{kind:"err",text:Q.error||"Failed."}),$()},z=async()=>{if(!o)return;p(null);const ee=await K.updateContact(o.platform,o.id,{name:c,phone:d});p(ee.ok?{kind:"ok",text:`✅ ${c} updated.`}:{kind:"err",text:ee.error||"Failed."}),l(null),$()},O=ee=>ee==="approved"?i.jsx("span",{className:"contact-status-badge approved",children:"✅ Approved"}):ee==="pending"?i.jsx("span",{className:"contact-status-badge pending",children:"⏳ Pending"}):i.jsx("span",{className:"contact-status-badge rejected",children:"🚫 Rejected"}),J=ee=>({telegram:"✈️",whatsapp:"📱",whatsapp_cloud:"📱",email:"📧",slack:"💬",discord:"🎮"})[ee]||"🔌",F=ee=>ee?new Date(ee).toLocaleString():"—",L=ee=>{const Q=(k[ee]??"").trim();Q&&(g(ae=>{var xe;const ce={...ae[ee]??{}},G=ce.outboundSenders??((xe=y[ee])==null?void 0:xe.outboundSenders)??[];return G.some(we=>we.toLowerCase()===Q.toLowerCase())||(ce.outboundSenders=[...G,Q]),{...ae,[ee]:ce}}),w(ae=>({...ae,[ee]:""})))},ie=(ee,Q)=>{g(ae=>{var xe;const ce={...ae[ee]??{}},G=ce.outboundSenders??((xe=y[ee])==null?void 0:xe.outboundSenders)??[];return ce.outboundSenders=G.filter(we=>we.toLowerCase()!==Q.toLowerCase()),{...ae,[ee]:ce}})},fe=ee=>{g(Q=>{const ae={...Q[ee]??{}};return ae.requireApprovedTarget=ae.requireApprovedTarget!==!0,{...Q,[ee]:ae}})},ve=ee=>{g(Q=>{const ae={...Q[ee]??{}};return delete ae.outboundSenders,{...Q,[ee]:ae}})},Ee=async()=>{N(!0),S(null);const ee={};for(const ce of yv){const G=m[ce]??{},xe=y[ce]??{};(JSON.stringify(G.outboundSenders??null)!==JSON.stringify(xe.outboundSenders??null)||!!G.requireApprovedTarget!=!!xe.requireApprovedTarget)&&(ee[ce]={...G.outboundSenders!==void 0?{outboundSenders:G.outboundSenders}:{outboundSenders:null},requireApprovedTarget:!!G.requireApprovedTarget})}const Q=E!==_;if(Object.keys(ee).length===0&&!Q){N(!1),S({kind:"ok",text:"No changes to save."});return}const ae=await K.saveGatewayPolicies(ee,void 0,void 0,{wait:E,timeoutMs:T});ae.ok?(S({kind:"ok",text:"✅ Send authority saved."}),$()):S({kind:"err",text:ae.error||"Failed to save send authority."}),N(!1)};return i.jsxs("div",{className:"panel contacts-page",children:[i.jsx(Oe,{icon:"📇",title:"Contacts — Outbound Messaging Directory",description:"Manage who the bot can send messages to. Users auto-register on first Telegram message."}),h&&i.jsxs("div",{className:`admin-row-msg ${h.kind==="err"?"admin-row-msg-err":""}`,children:[h.text,i.jsx("button",{className:"admin-mini-btn",onClick:()=>p(null),children:"✕"})]}),i.jsxs("div",{className:"contacts-filters",children:[["all","approved","pending","rejected"].map(ee=>i.jsx("button",{type:"button",className:a===ee?"platforms-filter-btn active":"platforms-filter-btn",onClick:()=>s(ee),children:ee==="all"?`All (${e.length})`:ee==="approved"?`✅ Approved (${e.filter(Q=>Q.status==="approved").length})`:ee==="pending"?`⏳ Pending (${e.filter(Q=>Q.status==="pending").length})`:`🚫 Rejected (${e.filter(Q=>Q.status==="rejected").length})`},ee)),i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>void $(),children:"🔄 Refresh"})]}),n?i.jsx("div",{className:"empty-state",children:"Loading contacts..."}):I.length===0?i.jsxs("div",{className:"empty-state",children:[i.jsxs("p",{children:["No contacts",a!=="all"?` with status "${a}"`:"","."]}),i.jsx("p",{className:"admin-hint",children:'Contacts auto-register when users message the bot on Telegram. They appear here as "Pending" until you approve them.'})]}):i.jsx("div",{className:"contacts-table-wrapper",children:i.jsxs("table",{className:"contacts-table",children:[i.jsx("thead",{children:i.jsxs("tr",{children:[i.jsx("th",{children:"Platform"}),i.jsx("th",{children:"Name"}),i.jsx("th",{children:"ID"}),i.jsx("th",{children:"Phone"}),i.jsx("th",{children:"Status"}),i.jsx("th",{children:"Registered"}),i.jsx("th",{children:"Actions"})]})}),i.jsx("tbody",{children:I.map(ee=>i.jsxs("tr",{className:`contact-row status-${ee.status}`,children:[i.jsxs("td",{children:[J(ee.platform)," ",ee.platform]}),i.jsx("td",{className:"contact-name",children:ee.name}),i.jsx("td",{className:"contact-id",children:i.jsx("code",{children:ee.id})}),i.jsx("td",{className:"contact-phone",children:ee.phone||"—"}),i.jsx("td",{children:O(ee.status)}),i.jsx("td",{className:"contact-date",children:F(ee.registeredAt||ee.addedAt)}),i.jsxs("td",{className:"contact-actions",children:[ee.status!=="approved"&&i.jsx("button",{className:"admin-mini-btn contact-approve-btn",onClick:()=>void D(ee),children:"✅ Approve"}),ee.status!=="rejected"&&i.jsx("button",{className:"admin-mini-btn contact-reject-btn",onClick:()=>void U(ee),children:"🚫 Reject"}),i.jsx("button",{className:"admin-mini-btn",onClick:()=>{l(ee),u(ee.name),f(ee.phone||"")},children:"✏️ Edit"}),i.jsx("button",{className:"admin-mini-btn contact-delete-btn",onClick:()=>void M(ee),children:"🗑️"})]})]},`${ee.platform}:${ee.id}`))})]})}),i.jsxs("div",{className:"panel-header",style:{marginTop:28},children:[i.jsx("h2",{children:"🔐 Send authority — who may message others"}),i.jsxs("p",{className:"admin-hint",children:["Controls who can ask the agent to send a message to ",i.jsx("strong",{children:"someone else"})," through the gateway (e.g. “send this poem to my brother on WhatsApp”). This is separate from a contact’s approval status above, which only gates sending ",i.jsx("em",{children:"to"})," that person. Left empty, a platform ",i.jsx("strong",{children:"inherits"})," its allowed-users list (open). Add ",i.jsx("code",{children:"Allow-All"})," to allow everyone, or list specific senders to restrict it."]})]}),j&&i.jsxs("div",{className:`admin-row-msg ${j.kind==="err"?"admin-row-msg-err":""}`,children:[j.text,i.jsx("button",{className:"admin-mini-btn",onClick:()=>S(null),children:"✕"})]}),i.jsx("div",{className:"hub-permissions",children:yv.map(ee=>{const Q=m[ee]??{},ae=Q.outboundSenders??[],ce=Q.outboundSenders===void 0;return i.jsxs("div",{className:"hub-card",children:[i.jsxs("div",{className:"hub-card-top",children:[i.jsxs("span",{className:"hub-chip",children:[J(ee)," ",ee]}),ce?i.jsx("span",{className:"hub-chip",children:"open"}):i.jsx("span",{className:"hub-chip",children:"restricted"})]}),i.jsx("div",{className:"hub-alias-list",children:ce?i.jsx("span",{className:"admin-hint",children:"Open — anyone who can trigger the agent may send to others."}):ae.length===0?i.jsx("span",{className:"admin-hint",children:"(empty — nobody may send to others)"}):ae.map(G=>i.jsxs("div",{className:"hub-alias-row",children:[i.jsx("span",{className:"hub-chip",children:G}),i.jsx("button",{className:"admin-refresh-btn",disabled:x,onClick:()=>ie(ee,G),children:"✕"})]},`sa-${ee}-${G}`))}),i.jsxs("div",{className:"hub-send-form",children:[i.jsx("input",{type:"text","aria-label":`Allowed sender for ${ee}`,value:k[ee]??"",onChange:G=>w(xe=>({...xe,[ee]:G.target.value})),placeholder:"sender id, or Allow-All",disabled:x}),i.jsx("button",{className:"admin-refresh-btn",disabled:x||!(k[ee]??"").trim(),onClick:()=>L(ee),children:"+ Sender"}),ce?null:i.jsx("button",{className:"admin-refresh-btn",disabled:x,onClick:()=>ve(ee),children:"↺ Reset to open"})]}),i.jsxs("label",{style:{display:"inline-flex",alignItems:"center",gap:6,marginTop:6},children:[i.jsx("input",{type:"checkbox",checked:!!Q.requireApprovedTarget,disabled:x,onChange:()=>fe(ee)}),i.jsx("span",{className:"admin-hint",children:"Require approved recipients"})]})]},`sa-${ee}`)})}),i.jsxs("div",{className:"hub-card",style:{marginTop:16},children:[i.jsxs("div",{className:"hub-card-top",children:[i.jsx("span",{className:"hub-chip",children:"🧠 Clarifying questions"}),E?i.jsx("span",{className:"hub-chip",children:"wait for reply"}):i.jsx("span",{className:"hub-chip",children:"assume option 1"}),E!==_?i.jsx("span",{className:"hub-chip",children:"· unsaved"}):null]}),i.jsxs("label",{style:{display:"inline-flex",alignItems:"center",gap:6,marginTop:6},children:[i.jsx("input",{type:"checkbox",checked:E,disabled:x,onChange:()=>P(ee=>!ee)}),i.jsxs("span",{className:"admin-hint",children:["When the agent asks a question on a channel, ",i.jsx("strong",{children:"wait for the sender's reply"})," before acting. Off (default): the question is sent and the ",i.jsx("em",{children:"first"})," option is assumed immediately — so a reply typed afterwards arrives too late to change anything."]})]}),E?i.jsxs("label",{style:{display:"inline-flex",alignItems:"center",gap:6,marginTop:6},children:[i.jsx("span",{className:"admin-hint",children:"Reply window (seconds)"}),i.jsx("input",{type:"number",min:5,max:600,value:Math.round(T/1e3),disabled:x,onChange:ee=>B(Math.max(5,Math.min(600,Number(ee.target.value)||120))*1e3),style:{width:90}}),i.jsx("span",{className:"admin-hint",children:"then the first option is used, and the timeout is logged."})]}):null]}),i.jsx("div",{style:{marginTop:12},children:i.jsx("button",{className:"admin-refresh-btn",disabled:x,onClick:()=>void Ee(),children:"💾 Save send authority"})}),o&&i.jsx("div",{className:"wizard-overlay",onClick:()=>l(null),children:i.jsxs("div",{className:"wizard-modal",onClick:ee=>ee.stopPropagation(),children:[i.jsxs("div",{className:"wizard-header",children:[i.jsx("span",{className:"wizard-icon",children:"✏️"}),i.jsxs("span",{className:"wizard-title",children:["Edit Contact: ",o.name]}),i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>l(null),children:"✕"})]}),i.jsxs("div",{className:"wizard-body",children:[i.jsxs("label",{className:"hub-send-target",children:[i.jsx("span",{className:"admin-hint",children:"Name"}),i.jsx("input",{type:"text",value:c,onChange:ee=>u(ee.target.value)})]}),i.jsxs("label",{className:"hub-send-target",children:[i.jsx("span",{className:"admin-hint",children:"Phone (optional, for flexible lookup)"}),i.jsx("input",{type:"text",value:d,onChange:ee=>f(ee.target.value),placeholder:"+918800123456"})]}),i.jsxs("p",{className:"admin-hint",children:["Platform: ",i.jsx("strong",{children:o.platform})," | ID: ",i.jsx("code",{children:o.id})]}),i.jsxs("div",{className:"wizard-nav",children:[i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>l(null),children:"Cancel"}),i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>void z(),children:"Save"})]})]})]})})]})}const nC=["proven-dead","proof-expired","parked","never-verified"];function Wo(e){if(e<=0)return"never";const t=Math.floor(e/1e3),n=Math.floor(t/60),r=Math.floor(n/60),a=Math.floor(r/24);return a>30?`${a}d ago`:a>0?`${a}d ${r%24}h ago`:r>0?`${r}h ${n%60}m ago`:n>0?`${n}m ago`:`${t}s ago`}function Cbe(e){if(e<=0)return"never";const t=(Date.now()-e)/(24*60*60*1e3);return t<1?`${(t*24).toFixed(1)}h`:`${t.toFixed(2)}d`}function Abe({entry:e}){const t=Date.now(),n=t-e.lastProbedAt,r=t-e.lastVerifiedAt,a=t-e.lastUsedAt,s=Math.min(100,n/(30*24*60*60*1e3)*100),o=e.lastVerifiedAt>0?Math.min(100,r/(30*24*60*60*1e3)*100):-1,l=e.lastUsedAt>0?Math.min(100,a/(30*24*60*60*1e3)*100):-1;return i.jsxs("div",{className:"timeline-bar-container",children:[i.jsx("div",{className:"timeline-bar",title:`Last probed: ${Wo(n)}`,children:i.jsx("div",{className:"timeline-bar-fill probe",style:{width:`${s}%`}})}),o>=0&&i.jsx("div",{className:"timeline-bar small",title:`Last verified: ${Wo(r)}`,children:i.jsx("div",{className:"timeline-bar-fill verify",style:{width:`${o}%`}})}),l>=0&&i.jsx("div",{className:"timeline-bar small",title:`Last used: ${Wo(a)}`,children:i.jsx("div",{className:"timeline-bar-fill use",style:{width:`${l}%`}})})]})}function rC(e){return{fontSize:11,padding:"2px 8px",borderRadius:4,background:`${e}20`,color:e,border:`1px solid ${e}40`,whiteSpace:"nowrap"}}function Tbe(){const[e,t]=b.useState(null),[n,r]=b.useState(!0),[a,s]=b.useState(null),[o,l]=b.useState("all"),[c,u]=b.useState("provider"),d=b.useRef(!0),f=h0(),h=b.useCallback(async()=>{try{const z=await fetch("/api/model-timeline");if(!z.ok)throw new Error("Failed to fetch timeline data");const O=await z.json();d.current&&(t(O),s(null))}catch(z){d.current&&s(z instanceof Error?z.message:"Failed to load timeline")}finally{d.current&&r(!1)}},[]),[p,m]=b.useState(null),[g,y]=b.useState(10),[v,k]=b.useState(!1),[w,j]=b.useState(null),S=b.useRef(!1),x=b.useCallback(async()=>{const z=await K.fetchVerifyBacklog();if(!d.current)return;m(z);const O=(z==null?void 0:z.status)==="running";S.current&&!O&&h(),S.current=O},[h]);b.useEffect(()=>{d.current=!0,h(),x();const z=setInterval(()=>void h(),3e4);return()=>{d.current=!1,clearInterval(z)}},[h,x]);const N=(p==null?void 0:p.status)==="running";b.useEffect(()=>{if(!N)return;const z=setInterval(()=>void x(),1e3);return()=>clearInterval(z)},[N,x]);const E=b.useCallback(async()=>{k(!0),j(null);const z=await K.startVerifyBacklog(g);if(d.current){if(z.state&&m(z.state),!z.ok){const O=z.refusal??z.error??"Could not start the run.";j({text:O,kind:z.refusal?"info":"error"})}k(!1)}},[g]);if(n)return i.jsxs("div",{className:"admin-header",children:[i.jsx(Oe,{icon:"📅",title:"Model Discovery Timeline"}),i.jsxs("div",{className:"loading-state",children:[i.jsx("div",{className:"loading-spinner"}),i.jsx("p",{children:"Loading timeline..."})]})]});if(a)return i.jsxs("div",{className:"admin-header",children:[i.jsx(Oe,{icon:"📅",title:"Model Discovery Timeline"}),i.jsx("div",{className:"admin-row-msg admin-row-msg-err",children:a})]});if(e&&!e.counts)return i.jsxs("div",{className:"admin-header",children:[i.jsx(Oe,{icon:"📅",title:"Model Discovery Timeline"}),i.jsxs("div",{className:"admin-row-msg admin-row-msg-err",children:["This dashboard server predates the reachability view. Restart it (",i.jsx("code",{children:"nuvira dashboard stop"}),", then start it again) and reload this page."]})]});const P=(e==null?void 0:e.entries)??[],_=e==null?void 0:e.counts,R=e==null?void 0:e.reachabilityCopy,T=e==null?void 0:e.freshnessCopy,B=_?nC.reduce((z,O)=>z+(_[O]??0),0):0,$=[{key:"tracked-models",icon:"🧠",value:tt((e==null?void 0:e.totalModels)??0),label:"Tracked models (registry)",tone:"accent"},{key:"tracked-providers",icon:"🏢",value:tt((f==null?void 0:f.trackedProviders)??0),label:"Tracked providers (registry)",tone:"accent"}];f&&$.push({key:"listed-models",icon:"📡",value:tt(f.listedModels),label:"Listed models (live probe)",tone:"warn"},{key:"listed-providers",icon:"🛰️",value:tt(f.listedProviders),label:"Listed providers (live probe)",tone:"warn"}),$.push({key:"routable",icon:"✅",value:tt((_==null?void 0:_.routable)??0),label:"Routable now",tone:"ok"},{key:"not-routable",icon:"🚫",value:tt(B),label:"Not routable",tone:"danger"});const I=P.filter(z=>o==="routable"?z.reachability==="routable":o==="not-routable"?z.reachability!=="routable":!0),D=[...I].sort((z,O)=>c==="provider"?z.provider.localeCompare(O.provider)||z.model.localeCompare(O.model):O.lastProbedAt-z.lastProbedAt),U=new Map;for(const z of D){const O=U.get(z.provider);O?O.push(z):U.set(z.provider,[z])}const M=z=>({background:z?"var(--accent-green)":"var(--bg-hover)",border:`1px solid ${z?"var(--accent-green)":"var(--border)"}`,padding:"4px 12px",fontSize:12,cursor:"pointer"});return i.jsxs(i.Fragment,{children:[i.jsx(Oe,{icon:"📅",title:"Model Discovery Timeline"}),i.jsxs("p",{className:"section-description",children:["The registry's age profile: when each tracked model was last probed, last ",i.jsx("em",{children:"verified"}),", and last used — and which ones routing can actually reach. The Models page answers “is it usable right now”; this one answers “what is ageing out”."]}),i.jsx(Wi,{tiles:$}),_?i.jsx("div",{style:{display:"flex",gap:14,flexWrap:"wrap",marginBottom:14,fontSize:11},children:nC.map(z=>{const O=R==null?void 0:R[z];return i.jsxs("span",{title:O==null?void 0:O.blurb,children:[i.jsx("span",{style:{color:(O==null?void 0:O.color)??"var(--text-secondary)"},children:"■"})," ",i.jsxs("span",{style:{color:"var(--text-secondary)"},children:[(O==null?void 0:O.label)??z,": ",i.jsx("strong",{style:{color:"var(--text-primary)"},children:_[z]??0})]})]},z)})}):null,p?i.jsxs("div",{style:{background:"var(--bg-card)",border:"1px solid var(--border)",borderRadius:8,padding:"12px 14px",marginBottom:16},"data-testid":"verify-backlog-panel",children:[i.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[i.jsx("span",{style:{fontWeight:600,color:"var(--text-primary)"},children:"Work the backlog down"}),i.jsxs("span",{style:{fontSize:11,color:"var(--text-secondary)",flex:1,minWidth:260},children:["Each check is a real 1-token generation against one of your provider keys — not a listing lookup. A never-verified model is an ",i.jsx("em",{children:"unknown"}),", not a broken one: a check either proves it routable or marks it proven dead. Runs are bounded and one at a time."]}),i.jsxs("label",{style:{fontSize:11,color:"var(--text-secondary)",display:"flex",alignItems:"center",gap:6},children:["How many",i.jsx("input",{type:"number",min:1,max:p.maxCount??25,value:g,disabled:v||N,"aria-label":"how many models to verify",onChange:z=>y(Number(z.target.value)),style:{width:64,background:"var(--bg-primary)",color:"var(--text-primary)",border:"1px solid var(--border)",borderRadius:4,padding:"3px 6px",fontSize:12}})]}),i.jsx("button",{className:"admin-refresh-btn",type:"button",disabled:v||N||!(g>0),onClick:()=>void E(),style:{background:"var(--accent-green)",border:"1px solid var(--accent-green)",padding:"4px 12px",fontSize:12,cursor:v||N?"default":"pointer"},"data-testid":"verify-backlog-start",children:N?"⏳ Verifying…":v?"Starting…":`▶ Verify next ${g} now`})]}),N?i.jsxs("div",{className:"env-var-notice","data-testid":"verify-backlog-progress",children:["Probing"," ",i.jsx("code",{children:p.current?`${p.current.provider}/${p.current.model}`:"…"})," ","— ",p.processed,"/",p.planned," done · ",p.verified," verified · ",p.unavailable," proven dead"]}):null,!N&&p.status==="done"?i.jsxs("div",{className:"env-var-notice","data-testid":"verify-backlog-summary",children:["✅ ",p.verified," verified · ⛔ ",p.unavailable," proven unavailable · ⚠️ ",p.errored," errored · ⏭"," ",p.skipped," skipped",p.remaining!==null?` — ${p.remaining} still never verified`:""]}):null,(p.results??[]).length>0?i.jsx("div",{style:{display:"flex",gap:10,flexWrap:"wrap",marginTop:8},children:(p.results??[]).map(z=>i.jsxs("span",{style:{fontSize:11,color:"var(--text-secondary)"},title:z.outcome==="verified"?"Proven routable — a 1-token call succeeded":z.outcome==="unavailable"?"Proven dead — the provider refused it (403/404), re-probing will not help":z.outcome==="skipped"?"Skipped — verified recently enough":"Errored — transient, still unknown, will be retried next run",children:[z.outcome==="verified"?"✅":z.outcome==="unavailable"?"⛔":z.outcome==="skipped"?"⏭":"⚠️"," ",i.jsxs("code",{children:[z.provider,"/",z.model]})]},`${z.provider}:${z.model}`))}):null,w?i.jsx("div",{className:`env-var-notice${w.kind==="error"?" env-var-notice-error":""}`,"data-testid":"verify-backlog-message",children:w.text}):p.status==="idle"&&p.refusal?i.jsx("div",{className:"env-var-notice","data-testid":"verify-backlog-message",children:p.refusal}):null]}):null,i.jsxs("div",{style:{display:"flex",gap:8,marginBottom:16,flexWrap:"wrap"},children:[i.jsx("div",{style:{display:"flex",gap:4},children:["all","routable","not-routable"].map(z=>i.jsx("button",{className:`admin-refresh-btn ${o===z?"active":""}`,onClick:()=>l(z),style:M(o===z),children:z==="all"?"All":z==="routable"?"Routable":"Not routable"},z))}),i.jsx("div",{style:{display:"flex",gap:4},children:["provider","lastProbed"].map(z=>i.jsxs("button",{className:`admin-refresh-btn ${c===z?"active":""}`,onClick:()=>u(z),style:M(c===z),children:["Sort: ",z==="lastProbed"?"Last seen":"Provider"]},z))}),i.jsx("button",{className:"admin-refresh-btn",onClick:()=>void h(),style:{background:"var(--bg-hover)",border:"1px solid var(--border)",padding:"4px 12px",fontSize:12,cursor:"pointer"},children:"🔄 Refresh"})]}),i.jsxs("div",{style:{display:"flex",gap:16,marginBottom:4,fontSize:11,color:"var(--text-secondary)",flexWrap:"wrap"},children:[i.jsxs("span",{children:[i.jsx("span",{style:{color:"var(--accent-blue)"},children:"■"})," Probe (last seen in the provider's catalog)"]}),i.jsxs("span",{children:[i.jsx("span",{style:{color:"var(--accent-green)"},children:"■"})," Verified (last success)"]}),i.jsxs("span",{children:[i.jsx("span",{style:{color:"var(--accent-yellow)"},children:"■"})," Used (last invocation)"]})]}),i.jsxs("div",{style:{marginBottom:12,fontSize:11,color:"var(--text-secondary)"},children:[i.jsx("strong",{style:{color:"var(--text-primary)"},children:"Fresh"})," means the provider still lists it."," ",i.jsx("strong",{style:{color:"var(--text-primary)"},children:"Routable"})," means a turn has been proven to work on it within"," ",(e==null?void 0:e.freshDays)??7," days. A fresh model that was never verified is an unknown, not a failure — background spot-checks work through those a few at a time."]}),i.jsx("div",{style:{display:"flex",flexDirection:"column",gap:8},children:Array.from(U.entries()).map(([z,O])=>{const J=O.filter(F=>F.reachability==="routable").length;return i.jsxs("div",{style:{background:"var(--bg-card)",borderRadius:8,border:"1px solid var(--border)",overflow:"hidden"},children:[i.jsxs("div",{style:{padding:"10px 14px",borderBottom:"1px solid var(--border)",display:"flex",alignItems:"center",gap:8},children:[i.jsx("span",{style:{fontSize:16},children:z==="groq"?"⚡":z==="gemini"?"🌀":z==="local"?"💻":"🤖"}),i.jsx("span",{style:{fontWeight:600,color:"var(--text-primary)"},children:z}),i.jsxs("span",{style:{fontSize:12,color:"var(--text-secondary)"},children:["(",O.length," shown · ",J," routable)"]})]}),i.jsx("div",{style:{padding:"8px 14px"},children:O.map(F=>{const L=Date.now(),ie=R==null?void 0:R[F.reachability],fe=T==null?void 0:T[F.freshness],ve=(ie==null?void 0:ie.color)??"var(--text-secondary)";return i.jsxs("div",{"data-testid":`timeline-row-${F.provider}-${F.model}`,style:{display:"flex",alignItems:"center",gap:12,padding:"6px 0",borderBottom:"1px solid var(--border-light)"},children:[i.jsxs("div",{style:{flex:1,minWidth:0},children:[i.jsx("div",{style:{fontSize:13,color:"var(--text-primary)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:F.model}),i.jsxs("div",{style:{fontSize:11,color:"var(--text-secondary)",display:"flex",gap:12,flexWrap:"wrap"},children:[i.jsxs("span",{children:["Probed: ",Wo(L-F.lastProbedAt)]}),i.jsxs("span",{children:["Verified: ",F.lastVerifiedAt>0?Wo(L-F.lastVerifiedAt):"never"]}),F.lastUsedAt>0&&i.jsxs("span",{children:["Used: ",Wo(L-F.lastUsedAt)]}),F.latencyMs!==void 0&&i.jsxs("span",{children:[F.latencyMs,"ms"]}),F.errorRate>0&&i.jsxs("span",{style:{color:F.errorRate>.5?"var(--accent-red)":"var(--accent-yellow)"},children:["err ",(F.errorRate*100).toFixed(0),"%"]}),F.daysSinceVerify!==null&&F.daysSinceVerify>7&&i.jsxs("span",{style:{color:"var(--accent-yellow)"},children:["proof ",Cbe(F.lastVerifiedAt)," old"]})]})]}),i.jsx(Abe,{entry:F}),fe&&i.jsx("span",{style:rC(fe.color),title:fe.blurb,children:fe.label}),i.jsx("span",{style:rC(ve),title:(ie==null?void 0:ie.blurb)??F.reachability,"data-testid":`reachability-${F.provider}-${F.model}`,children:((ie==null?void 0:ie.label)??F.reachability).toUpperCase()})]},F.model)})})]},z)})}),I.length===0&&i.jsx("div",{style:{textAlign:"center",padding:"40px 20px",color:"var(--text-secondary)"},children:o==="routable"&&P.length>0?"No model is routable right now — every tracked model is unverified, parked, expired or dead. The Models page shows what each provider would offer live.":"No models match the current filter"})]})}const aC=7*24*60*60*1e3;function iC(e){const t=Math.max(0,Math.round((Date.now()-e)/6e4));if(t<1)return"just now";if(t<60)return`${t}m ago`;const n=Math.round(t/60);return n<24?`${n}h ago`:`${Math.round(n/24)}d ago`}function sC(e){return(e||"").split(/[\\/]/).filter(Boolean).slice(-2).join("/")||e}function Obe(){const[e,t]=b.useState(null),[n,r]=b.useState(!1),[a,s]=b.useState(!1),[o,l]=b.useState(null),c=b.useCallback(async()=>{const p=await K.fetchContinuity();t(p),r(!0)},[]);b.useEffect(()=>{let p=!0;return K.fetchContinuity().then(m=>{p&&(t(m),r(!0))}),()=>{p=!1}},[]);const u=b.useCallback(async(p,m,g)=>{s(!0),l(null);const y=await K.clearContinuity(p,m,g);y.ok?l(`Removed ${y.removed??0} record(s).`):l(y.error||"Could not clear that."),await c(),s(!1)},[c]);if(!n)return i.jsxs(i.Fragment,{children:[i.jsx("h2",{className:"section-subtitle",children:"🔗 Continuity"}),i.jsx("div",{className:"loading-state",children:i.jsx("p",{children:"Loading continuity data…"})})]});const d=e===null,f=(e==null?void 0:e.sessions)??[],h=(e==null?void 0:e.recall)??[];return i.jsxs(i.Fragment,{children:[i.jsx("h2",{className:"section-subtitle",children:"🔗 Continuity"}),i.jsx("p",{className:"memory-namespace-note",children:"The conversation snapshots that let a crashed or killed turn be resumed, and the index of past asks used for semantic recall. Both are history — they never decide that work is done. Turn the switches on or off on the Process Environment page."}),d?i.jsxs("p",{className:"memory-namespace-note",children:["Continuity data is unavailable — this dashboard server has no ",i.jsx("code",{children:"/api/continuity"})," endpoint."]}):i.jsxs(i.Fragment,{children:[i.jsxs("p",{className:"memory-backend",children:["Session store: ",i.jsx("code",{children:e.toggles.sessionStore?"ON":"OFF"})," · ","Semantic recall: ",i.jsx("code",{children:e.toggles.sessionRecall?"ON":"OFF"})]}),o?i.jsx("div",{className:"env-var-notice",children:o}):null,i.jsxs("h3",{className:"section-subtitle",children:["Stored sessions (",f.length,")"]}),f.length===0?i.jsx("p",{className:"memory-namespace-note",children:"No session snapshots yet."}):i.jsxs(i.Fragment,{children:[i.jsx("div",{className:"memory-list",children:f.map(p=>i.jsxs("div",{className:"memory-item",children:[i.jsxs("span",{className:"memory-project",children:[p.open?"↩️ OPEN":"✓ closed"," · ",p.goal]}),i.jsxs("span",{className:"memory-count",children:[sC(p.cwd)," · ",p.steps," step(s) · ",iC(p.savedAt)]}),i.jsx("button",{className:"admin-mini-btn admin-mini-btn-danger",type:"button",disabled:a,"aria-label":`Forget session ${p.goal}`,onClick:()=>void u("session",p.id),children:"🗑️ Forget"})]},p.id))}),i.jsxs("div",{className:"admin-row-actions",children:[i.jsx("button",{className:"admin-mini-btn admin-mini-btn-danger",type:"button",disabled:a,title:"Delete only session snapshots saved more than 7 days ago",onClick:()=>void u("sessions",void 0,aC),children:"🗑️ Forget older than a week"}),i.jsx("button",{className:"admin-mini-btn admin-mini-btn-danger",type:"button",disabled:a||f.length===0,onClick:()=>void u("sessions"),children:"🗑️ Forget all sessions"})]})]}),i.jsxs("h3",{className:"section-subtitle",children:["Recalled past asks (",h.length,")"]}),h.length===0?i.jsx("p",{className:"memory-namespace-note",children:"Nothing indexed for recall yet."}):i.jsxs(i.Fragment,{children:[i.jsx("div",{className:"memory-list",children:h.map(p=>i.jsxs("div",{className:"memory-item",children:[i.jsxs("span",{className:"memory-project",children:[p.outcome,": ",p.goal]}),i.jsxs("span",{className:"memory-count",children:[sC(p.projectPath)," · ",iC(p.savedAt)]}),i.jsx("button",{className:"admin-mini-btn admin-mini-btn-danger",type:"button",disabled:a,"aria-label":`Forget recall entry ${p.goal}`,onClick:()=>void u("recall-entry",p.id),children:"🗑️ Forget"})]},p.id))}),i.jsxs("div",{className:"admin-row-actions",children:[i.jsx("button",{className:"admin-mini-btn admin-mini-btn-danger",type:"button",disabled:a,title:"Delete only recall entries indexed more than 7 days ago",onClick:()=>void u("recall",void 0,aC),children:"🗑️ Forget older than a week"}),i.jsx("button",{className:"admin-mini-btn admin-mini-btn-danger",type:"button",disabled:a||h.length===0,onClick:()=>void u("recall"),children:"🗑️ Forget all recall entries"})]})]})]})]})}function as(e){return e==null?"0":e>=1e6?(e/1e6).toFixed(1)+"M":e>=1e3?(e/1e3).toFixed(1)+"K":bt(e)}function Pbe(e){return e==null?"0%":(e*100).toFixed(1)+"%"}const oC={"faiss-native":"native FAISS","faiss-ivf":"FAISS-style IVF-flat ANN",json:"exact flat cosine (JSON)"};function Rbe({data:e}){var c,u;if(!e)return i.jsxs(i.Fragment,{children:[i.jsx(Oe,{icon:"💾",title:"Memory Store"}),i.jsx("div",{className:"loading-state",children:i.jsx("p",{children:"Loading memory data..."})})]});const{memory:t,health:n}=e,r=Object.entries(t.byFingerprint||{}).sort(([,d],[,f])=>f-d),a=Object.entries(((c=t.facts)==null?void 0:c.byProject)||{}).sort(([,d],[,f])=>f-d),s=[...t.vectorNamespaces||[]].sort((d,f)=>f.entries-d.entries),o=t.recall||{total:0,today:0,last7d:0},l=[{key:"trajectories",icon:"🧭",value:as(t.total),label:"Trajectories",tone:"accent"},{key:"avg-score",icon:"⭐",value:Pbe(t.avgScore),label:"Avg Score",tone:"ok"},{key:"facts",icon:"📌",value:as((u=t.facts)==null?void 0:u.total),label:"Facts",tone:"warn"},{key:"recall",icon:"🔁",value:as(o.total),label:"Recall Hits",tone:"ok"},{key:"patterns",icon:"🧩",value:as(n==null?void 0:n.patterns),label:"Coding Patterns",tone:"warn"},{key:"feedback",icon:"👍",value:as(n==null?void 0:n.feedback),label:"Feedback Ratings",tone:"ok"}];return i.jsxs(i.Fragment,{children:[i.jsx(Oe,{icon:"💾",title:"Memory Store"}),i.jsx(Wi,{tiles:l}),i.jsxs("p",{className:"memory-backend",children:["Memory tier: ",i.jsx("code",{children:t.backend||"local"})," · ","Vector index: ",i.jsx("code",{children:t.vectorBackend||"unknown"}),t.vectorBackend&&oC[t.vectorBackend]?` (${oC[t.vectorBackend]})`:"",o.last7d>0?` · ${as(o.last7d)} recall(s) this week, ${as(o.today)} today`:" · no recalls yet"]}),i.jsx(Obe,{}),r.length>0&&i.jsxs(i.Fragment,{children:[i.jsx("h2",{className:"section-subtitle",children:"By Project Type"}),i.jsx("div",{className:"memory-list",children:r.map(([d,f])=>i.jsxs("div",{className:"memory-item",children:[i.jsx("span",{className:"memory-project",children:d}),i.jsxs("span",{className:"memory-count",children:[f," trajectory(ies)"]})]},d))})]}),a.length>0&&i.jsxs(i.Fragment,{children:[i.jsx("h2",{className:"section-subtitle",children:"Facts by Project"}),i.jsx("div",{className:"memory-list",children:a.map(([d,f])=>i.jsxs("div",{className:"memory-item",children:[i.jsx("span",{className:"memory-project",children:d}),i.jsxs("span",{className:"memory-count",children:[f," fact(s)"]})]},d))})]}),s.length>0&&i.jsxs(i.Fragment,{children:[i.jsx("h2",{className:"section-subtitle",children:"Vector Index by Namespace"}),i.jsxs("p",{className:"memory-namespace-note",children:["Each namespace is its own index file. ",i.jsx("code",{children:"default"})," holds only successful trajectories and indexed sessions — facts, repo chunks and the model registry have their own namespaces — so a small ",i.jsx("code",{children:"default"})," count is corpus size, not a broken index."]}),i.jsx("div",{className:"memory-list",children:s.map(d=>i.jsxs("div",{className:"memory-item",children:[i.jsx("span",{className:"memory-project",children:d.name}),i.jsxs("span",{className:"memory-count",children:[d.entries," vector(s)"]})]},d.name))})]})]})}function bv(e){const t=e.replace(/[\\/]+$/,""),n=Math.max(t.lastIndexOf("/"),t.lastIndexOf("\\"));return n>=0?t.slice(n+1):t}function Mbe(){const[e,t]=b.useState({configured:!1,authenticated:!1,role:null}),n=qr(),[r,a]=b.useState(null),[s,o]=b.useState(null),[l,c]=b.useState(null),[u,d]=b.useState(""),[f,h]=b.useState(""),[p,m]=b.useState(!1),[g,y]=b.useState(""),[v,k]=b.useState(""),[w,j]=b.useState(null),[S,x]=b.useState(!1),N=e.authenticated&&(e.role==="admin"||e.role==="operator"),E=b.useCallback(async()=>{const T=await K.fetchKnowledge();a(T)},[]);b.useEffect(()=>{K.fetchAdminAuthStatus().then(T=>{t(T?{configured:T.configured,authenticated:T.authenticated,role:T.role??null}:{configured:!1,authenticated:!1,role:null})}),E()},[E,n]);const P=b.useCallback(async()=>{var B;o(null),c(null);const T=f.split(`
205
+ `);return i.jsxs("div",{className:`chat-draft-card${a==="saved"?" chat-draft-saved":""}${a==="rejected"?" chat-draft-rejected":""}`,children:[i.jsxs("div",{className:"chat-draft-head",children:[i.jsx("span",{className:"chat-draft-icon",children:"🧠"}),i.jsxs("span",{className:"chat-draft-title",children:["New skill draft: ",e.name]}),i.jsx("span",{className:"chat-draft-meta",children:"pending your review"})]}),i.jsx("p",{className:"chat-draft-desc",children:e.description}),i.jsx("pre",{className:"chat-draft-body",children:l}),a==="saving"?i.jsx("div",{className:"admin-hint",children:"Saving…"}):a==="saved"?i.jsx("div",{className:"admin-hint",children:"✅ Saved — the skill is live: load it in chat or see it in the Agent Hub Skills tab."}):a==="rejected"?i.jsx("div",{className:"admin-hint",children:"🗑️ Rejected — the draft was discarded, nothing was saved."}):i.jsxs("div",{className:"chat-draft-actions",children:[i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:()=>t(e.name),children:"✅ Accept"}),i.jsx("button",{className:"admin-mini-btn",type:"button",onClick:()=>r(e.name),children:"✏️ Edit"}),i.jsx("button",{className:"admin-mini-btn",type:"button",onClick:()=>n(e.name),children:"↩ Reject"})]})]})}function sbe({request:e,onSave:t}){const[n,r]=b.useState({}),[a,s]=b.useState(!1),o=e.missing.every(u=>{var d;return(d=n[u])==null?void 0:d.trim()}),l=e.missing.filter(u=>e.persisted[u]),c=e.missing.filter(u=>!e.persisted[u]);return i.jsxs("div",{className:"chat-secret-card",children:[i.jsxs("div",{className:"chat-secret-head",children:[i.jsx("span",{className:"chat-secret-icon",children:"🔐"}),i.jsxs("span",{className:"chat-secret-title",children:[e.skillName," needs environment variables"]})]}),l.length>0?i.jsxs("div",{className:"chat-secret-persisted",children:["Already configured: ",l.map(u=>i.jsx("code",{children:u},u)).join(", ")]}):null,c.length>0&&!a?i.jsxs("div",{className:"chat-secret-fields",children:[c.map(u=>i.jsxs("div",{className:"chat-secret-row",children:[i.jsxs("label",{className:"chat-secret-label",htmlFor:`secret-${u}`,children:[u,":"]}),i.jsx("input",{id:`secret-${u}`,className:"chat-secret-input",type:"password",placeholder:`Enter ${u} value…`,value:n[u]??"",onChange:d=>r(f=>({...f,[u]:d.target.value}))})]},u)),i.jsx("button",{className:"admin-refresh-btn",type:"button",disabled:!o,onClick:()=>{t(n),s(!0)},children:"💾 Save to ~/.nuvira/.env"})]}):a?i.jsx("div",{className:"admin-hint",children:"✅ Saved — the skill will pick up these values on next load."}):i.jsx("div",{className:"admin-hint",children:"All required env vars are already configured."})]})}function obe({result:e}){const[t,n]=b.useState(!1),r=e.success?"✅":"❌",a=e.success?"Success":`Failed (exit ${e.exitCode})`,s=e.success?"chat-exec-success":"chat-exec-failure",o=new Date(e.timestamp).toLocaleTimeString();return i.jsxs("div",{className:`chat-exec-card ${s}`,children:[i.jsxs("div",{className:"chat-exec-head",onClick:()=>n(!t),style:{cursor:"pointer"},children:[i.jsx("span",{className:"chat-exec-icon",children:"📜"}),i.jsx("span",{className:"chat-exec-title",children:e.skillName}),i.jsxs("span",{className:"chat-exec-status",children:[r," ",a]}),i.jsxs("span",{className:"chat-exec-meta",children:[e.runtime," · ",e.durationMs,"ms · ",o]}),i.jsx("span",{className:"chat-exec-expand",children:t?"▼":"▶"})]}),t&&i.jsxs("div",{className:"chat-exec-body",children:[e.stdout&&i.jsxs("div",{className:"chat-exec-section",children:[i.jsx("div",{className:"chat-exec-section-title",children:"stdout"}),i.jsx("pre",{className:"chat-exec-output",children:e.stdout})]}),e.stderr&&i.jsxs("div",{className:"chat-exec-section chat-exec-stderr",children:[i.jsx("div",{className:"chat-exec-section-title",children:"stderr"}),i.jsx("pre",{className:"chat-exec-output",children:e.stderr})]}),i.jsxs("div",{className:"chat-exec-details",children:[i.jsxs("span",{children:["Runtime: ",e.runtime]}),i.jsxs("span",{children:["Exit code: ",e.exitCode]}),i.jsxs("span",{children:["Duration: ",e.durationMs,"ms"]})]})]})]})}function lbe(e){return e==="done"?"✅":e==="running"?"🔄":e==="blocked"?"⛔":"⬜"}function cbe(e){return e==="done"?"done":e==="running"?"in progress":e==="blocked"?"blocked":"pending"}function Q_({plan:e}){const t=e.steps.length,n=e.steps.filter(c=>c.status==="done").length,r=e.steps.filter(c=>c.status==="blocked").length,a=t===0?0:Math.round(n/t*100),s=t>0&&n===t,o=t>0&&e.steps.every(c=>c.status==="done"||c.status==="blocked"),l=e.steps.some(c=>c.note);return i.jsxs("div",{className:`chat-plan-card${s?" chat-plan-complete":""}`,children:[i.jsxs("div",{className:"chat-plan-head",children:[i.jsx("span",{className:"chat-plan-icon",children:"🗂️"}),i.jsx("span",{className:"chat-plan-goal",children:e.goal}),i.jsxs("span",{className:"chat-plan-count",children:[n,"/",t," done · ",a,"%"]})]}),i.jsx("div",{className:"chat-plan-bar",role:"progressbar","aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":a,children:i.jsx("span",{className:"chat-plan-bar-fill",style:{width:`${a}%`}})}),i.jsxs("table",{className:"chat-plan-table",children:[i.jsx("thead",{children:i.jsxs("tr",{children:[i.jsx("th",{className:"chat-plan-col-n",children:"#"}),i.jsx("th",{children:"Step"}),i.jsx("th",{className:"chat-plan-col-status",children:"Status"}),l?i.jsx("th",{children:"Notes"}):null]})}),i.jsx("tbody",{children:e.steps.map((c,u)=>i.jsxs("tr",{className:`chat-plan-row chat-plan-row-${c.status}`,children:[i.jsx("td",{className:"chat-plan-col-n",children:u+1}),i.jsx("td",{className:"chat-plan-step-text",children:c.description}),i.jsxs("td",{className:"chat-plan-col-status",children:[i.jsx("span",{className:"chat-plan-step-icon",children:lbe(c.status)})," ",cbe(c.status)]}),l?i.jsx("td",{className:"chat-plan-note",children:c.note??""}):null]},c.id))})]}),o?i.jsx("div",{className:"chat-plan-settled",children:s?`✅ Plan complete — ${n}/${t} steps achieved`:`📋 Plan settled — ${n}/${t} achieved, ${r} blocked`}):null]})}function Z_({tools:e,live:t}){return!e||e.length===0?null:i.jsx("div",{className:`chat-tool-cards${t?" chat-tool-cards-live":""}`,children:e.map(n=>{const r=n.phase==="started"||n.ok===void 0,a=n.ok===!1;return i.jsxs("div",{className:`chat-tool-card${r?" chat-tool-running":a?" chat-tool-err":" chat-tool-ok"}`,children:[i.jsxs("div",{className:"chat-tool-head",children:[i.jsx("span",{className:"chat-tool-icon",children:tbe(n.tool)}),i.jsx("span",{className:"chat-tool-name",children:n.tool}),n.args?i.jsx("code",{className:"chat-tool-args",children:n.args}):null,i.jsx("span",{className:"chat-tool-status",title:r?"running":a?"failed":"done",children:r?"⏳":a?"✗":"✓"}),n.durationMs!==void 0&&!r?i.jsxs("span",{className:"chat-tool-dur",children:[n.durationMs,"ms"]}):null]}),n.error||n.result?i.jsxs("details",{className:"chat-tool-detail",children:[i.jsx("summary",{children:a?"Error":"Result"}),i.jsx("pre",{className:"chat-tool-body",children:n.error||n.result})]}):null]},n.id)})})}function k$(e){return(e.evidence??[]).filter(t=>typeof(t==null?void 0:t.ref)=="string"&&t.ref.trim().length>0)}function ube(e){const t=e.filter(n=>n.verdict==="CONFIRMED"&&k$(n).length>0).length;return`${e.length} finding${e.length===1?"":"s"}: ${t} confirmed, ${e.length-t} plausible`}function J_({findings:e}){return!e||e.length===0?null:i.jsxs("details",{className:"chat-steps chat-findings",children:[i.jsx("summary",{children:`🔎 ${ube(e)}`}),i.jsx("div",{className:"chat-finding-cards",children:e.map((t,n)=>{const r=k$(t),a=t.verdict==="CONFIRMED"&&r.length>0;return i.jsxs("div",{className:`chat-finding-card ${a?"chat-finding-confirmed":"chat-finding-plausible"}`,children:[i.jsxs("div",{className:"chat-finding-head",children:[i.jsx("span",{className:"chat-finding-icon","aria-hidden":"true",children:a?"✅":"🔎"}),i.jsx("span",{className:"chat-finding-claim",children:t.claim}),i.jsx("span",{className:`chat-finding-verdict ${a?"chat-finding-verdict-ok":"chat-finding-verdict-guess"}`,title:a?"a check was performed and is shown below":"reasoned, not verified",children:a?"CONFIRMED":"PLAUSIBLE"})]}),t.outcome?i.jsx("div",{className:"chat-finding-outcome",children:t.outcome}):null,r.length>0?i.jsx("ul",{className:"chat-finding-evidence",children:r.map((s,o)=>i.jsxs("li",{children:[i.jsx("span",{className:"chat-finding-kind",children:s.kind}),i.jsx("code",{className:"chat-finding-ref",children:s.ref}),s.detail?i.jsxs("span",{className:"chat-finding-detail",children:["(",s.detail,")"]}):null]},o))}):i.jsx("div",{className:"chat-finding-noevidence",children:"no evidence — reported as PLAUSIBLE, not verified"}),t.source?i.jsxs("div",{className:"chat-finding-source",children:["source: ",t.source]}):null]},`${n}-${t.claim}`)})})]})}function dbe({worktree:e}){return i.jsxs("div",{className:"chat-worktree-card",children:[i.jsxs("div",{className:"chat-worktree-head",children:[i.jsx("span",{className:"chat-worktree-icon","aria-hidden":"true",children:"🌿"}),i.jsx("span",{className:"chat-worktree-title",children:"Ran in an isolated worktree"}),i.jsx("span",{className:`chat-worktree-state ${e.removed?"chat-worktree-gone":"chat-worktree-kept"}`,children:e.removed?"removed":"kept"})]}),i.jsxs("div",{className:"chat-worktree-meta",children:[i.jsx("code",{className:"chat-worktree-dir",title:e.dir,children:e.dir}),i.jsxs("span",{className:"admin-hint",children:["base ",e.base.slice(0,7)]})]}),i.jsx("div",{className:"chat-worktree-note admin-hint",children:e.removed?"the diff below is what is left of it — nothing was written into the project tree":"the directory above is still on disk"}),i.jsx(Cc,{diff:e.diff.payload})]})}function fbe({resume:e}){return i.jsxs("details",{className:"chat-resume-card",children:[i.jsxs("summary",{className:"chat-resume-head",children:[i.jsx("span",{className:"chat-resume-icon","aria-hidden":"true",children:"↩️"}),i.jsx("span",{className:"chat-resume-title",children:"Resumed a recorded run"}),i.jsxs("span",{className:"chat-resume-count",children:[i.jsxs("span",{children:[e.replayed," step",e.replayed===1?"":"s"," replayed"]}),i.jsxs("span",{children:[e.modelCalls," model call",e.modelCalls===1?"":"s"," made"]})]}),i.jsx("span",{className:`chat-resume-state ${e.saved?"chat-resume-saved":"chat-resume-unsaved"}`,title:e.saved?"the record was written back, so a later resume can replay this run":"the record could NOT be written — a later resume will replay nothing from this run",children:e.saved?"recorded":"not recorded"}),i.jsx("span",{className:"chat-card-caret","aria-hidden":"true",children:"▸"})]}),i.jsxs("div",{className:"chat-resume-meta",children:[typeof e.callsAvoided=="number"&&e.callsAvoided>0&&i.jsxs("span",{className:"chat-resume-saved-calls",title:"model calls the resume did not re-pay for",children:[e.callsAvoided," model call",e.callsAvoided===1?"":"s"," saved"]}),i.jsx("code",{className:"chat-resume-id",title:"the checkpoint record this run used",children:e.id})]}),i.jsx("div",{className:"chat-resume-note",children:e.notice})]})}function hbe({report:e}){const t=e.verification==="verified"?"VERIFIED":e.verification==="unverified"?"UNVERIFIED":e.verification==="blocked"?"BLOCKED":"no changes",n=[];return e.flags.unverifiedActionClaim&&n.push("claimed an action no tool ran"),e.flags.unverifiedEditClaim&&n.push("claimed a fix nothing verified"),e.flags.unverifiedBuildClaim&&n.push("claimed a failing build worked"),e.flags.unverifiedEdit&&n.push("edited without verifying"),e.flags.undeliveredArtifact&&n.push("deliverable never written"),e.flags.unfulfilledPromise&&n.push("promised an action it did not take"),e.flags.noActionTaken&&n.push("no action taken"),e.flags.undeliveredChange&&n.push("asked for a change, delivered a plan"),e.flags.unbackedHealthClaim&&n.push("verdict on the product nothing exercised"),i.jsxs("details",{className:`chat-turn-card chat-turn-${e.verification}`,children:[i.jsxs("summary",{className:"chat-turn-head",children:[i.jsx("span",{className:"chat-turn-icon","aria-hidden":"true",children:"📋"}),i.jsx("span",{className:"chat-turn-title",children:"Turn report"}),e.planned?i.jsxs("span",{className:"chat-turn-count",title:e.planCarried?"the tracked plan was carried from an earlier turn — THIS turn did not advance it":"plan steps recorded as done this turn",children:[e.stepCounts.done,"/",e.stepCounts.total," steps",e.planCarried?" · carried":""]}):null,e.summary?i.jsx("span",{className:"chat-turn-headline",title:e.summary,children:e.summary}):null,i.jsx("span",{className:"chat-turn-verdict",title:"derived from recorded evidence, never the model's own narration",children:t}),i.jsx("span",{className:"chat-card-caret","aria-hidden":"true",children:"▸"})]}),i.jsxs("div",{className:"chat-turn-body",children:[e.steps.length>0?i.jsx("ul",{className:"chat-turn-steps",children:e.steps.map(r=>i.jsxs("li",{className:`chat-turn-step chat-turn-step-${r.status}`,children:[i.jsx("span",{className:"chat-turn-step-icon","aria-hidden":"true",children:r.status==="done"?"✅":r.status==="running"?"🔄":r.status==="blocked"?"⛔":"⬜"}),i.jsx("span",{className:"chat-turn-step-text",children:r.description}),r.note?i.jsx("span",{className:"chat-turn-step-note",children:r.note}):null,r.evidence?i.jsx("span",{className:"chat-turn-step-evidence",children:r.evidence}):null]},r.id))}):null,e.changedPaths.length>0?i.jsxs("div",{className:"chat-turn-files",children:[e.changedPaths.length," file",e.changedPaths.length===1?"":"s"," changed:"," ",i.jsxs("code",{children:[e.changedPaths.slice(0,6).join(", "),e.changedPaths.length>6?` +${e.changedPaths.length-6} more`:""]})]}):null,e.planCarried?i.jsx("div",{className:"chat-turn-carried",children:"📋 that plan is carried from an earlier turn — THIS turn did not advance it."}):null,e.unverifiedPaths&&e.unverifiedPaths.length>0?i.jsxs("div",{className:"chat-turn-owed",children:["⚠️ ",e.unverifiedPaths.length," changed path",e.unverifiedPaths.length===1?"":"s"," no check exercised:"," ",i.jsxs("code",{children:[e.unverifiedPaths.slice(0,6).join(", "),e.unverifiedPaths.length>6?` +${e.unverifiedPaths.length-6} more`:""]})]}):null,n.length>0?i.jsx("div",{className:"chat-turn-flags",children:n.map(r=>i.jsxs("span",{className:"chat-turn-flag",children:["⚠️ ",r]},r))}):null]})]})}function mv(){try{if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch{}return`chat-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}const S$="nuvira.dashboard.chat.activeSession";function pbe(){try{const e=sessionStorage.getItem(S$);return e&&e.length>0&&e.length<=64?e:null}catch{return null}}function gv(e){try{sessionStorage.setItem(S$,e)}catch{}}function mbe(e,t){const n=t.trim().toLowerCase(),r=n?e.filter(u=>`${u.title} ${u.preview} ${u.firstUser}`.toLowerCase().includes(n)):e,a=[],s=new Date,o=new Date(s.getFullYear(),s.getMonth(),s.getDate()).getTime(),l=864e5,c=[{label:"Today",match:u=>u>=o},{label:"Yesterday",match:u=>u>=o-l&&u<o},{label:"This week",match:u=>u>=o-7*l&&u<o-l},{label:"Older",match:()=>!0}];for(const u of c){const d=r.filter(f=>u.match(f.updatedAt));d.length>0&&a.push({label:u.label,items:d})}return a}function gbe({ceilingRecovery:e}={}){var re;const[t,n]=b.useState(null),r=qr(),[a,s]=b.useState(Hye);b.useEffect(()=>{K.fetchLimits().then(A=>{A&&A.attachmentMaxBytes>0&&s(A.attachmentMaxBytes)})},[]),b.useEffect(()=>{K.fetchProcessEnv().then(A=>{const H=A.find(Y=>Y.name==="NUVIRA_CAPABILITY_MODE");H&&P(nbe(H.processValue??H.fileValue))})},[]),b.useEffect(()=>{K.listRoutableModels().then(A=>U(A))},[]);const[o,l]=b.useState([]),[c,u]=b.useState(""),[d,f]=b.useState(!1),[h,p]=b.useState(""),[m,g]=b.useState(null),[y,v]=b.useState(!1),[k,w]=b.useState(!1),[j,S]=b.useState(!1),[x,N]=b.useState(""),[E,P]=b.useState("balanced"),[_,R]=b.useState(""),[T,B]=b.useState(null),[$,I]=b.useState(!0),[D,U]=b.useState([]),[M,z]=b.useState(null),[O,J]=b.useState([]),[F,L]=b.useState([]),[ie,fe]=b.useState(null),[ve,Ee]=b.useState(null),[ee,Q]=b.useState(null),[ae,ce]=b.useState([]),[G,xe]=b.useState([]),[we,Pe]=b.useState([]),ge=b.useRef([]),Ie=b.useRef([]),me=b.useRef(null),Qe=b.useRef(null),De=b.useRef(null),_e=b.useRef([]),[pt,We]=b.useState(""),lt=b.useRef(""),Yt=b.useRef(null),[q,Z]=b.useState(null),[se,pe]=b.useState(!1),ke=b.useRef(!1),$e=b.useRef(!1),[zt,Le]=b.useState(0),rn=b.useRef(null),[Mn,wt]=b.useState(null),[Mt,an]=b.useState(null),[or,In]=b.useState(null),Gn=b.useRef(null),At=b.useRef(pbe()??mv()),Ft=b.useRef(""),[lr,cr]=b.useState([]),[zl,Tt]=b.useState(!0),[ya,pn]=b.useState(""),[Xs,sn]=b.useState(null),[ba,Kr]=b.useState(""),[_r,xa]=b.useState([]),[wa,qn]=b.useState(null),[Gi,qi]=b.useState(!1),Qs=b.useRef(null),Qa=b.useRef(null),[et,Zs]=b.useState(null),[ka,Sa]=b.useState(null),[Za,Ki]=b.useState([]),[Ja,Vi]=b.useState(""),[Yi,Vr]=b.useState(""),[Cr,ja]=b.useState(!1),[W,ne]=b.useState(""),[je,Se]=b.useState([]),[on,Kn]=b.useState(null),[En,Ar]=b.useState(!1),[Xi,Js]=b.useState([]),[md,Yr]=b.useState([]),[Fl,Ul]=b.useState(""),ei=b.useRef(null),He=b.useRef(null),eo=b.useRef(null),at=b.useRef(null),[It,Xr]=b.useState(null),[Qi,Wl]=b.useState(new Set),[Qr,gd]=b.useState("");b.useEffect(()=>{K.fetchAdminAuthStatus().then(A=>{n(A?{configured:A.configured,authenticated:A.authenticated,role:A.role??null}:{configured:!1,authenticated:!1,role:null})})},[r]),b.useEffect(()=>{var A,H;try{(H=(A=eo.current)==null?void 0:A.scrollTo)==null||H.call(A,{top:eo.current.scrollHeight})}catch{}},[o,d,O]),b.useEffect(()=>()=>{var A;(A=He.current)==null||A.call(He),He.current=null},[]);const Im=b.useCallback(async A=>{var he,Re;(he=He.current)==null||he.call(He),He.current=null;const H=await K.getChatSession(A);if(!H)return;At.current=A,gv(A),l(H.turns.map(ue=>({role:ue.role,content:ue.content,...ue.role==="assistant"?{followups:[],artifacts:wf(ue.content)}:{}}))),J([]),ge.current=[],L([]),Ie.current=[],fe(null),me.current=null,Ee(null),Qe.current=null,Q(null),De.current=null,ce([]),_e.current=[],lt.current="",We(""),Z(null),p(""),z(null),Xr(null),Tt(!0),B(H.pinnedProvider&&H.pinnedModel?{provider:H.pinnedProvider,model:H.pinnedModel}:null),I(H.pinnedStrict===!0);const Y=H.projectPath;if(Y){if(Sa(Y),(et==null?void 0:et.path)===Y)return;(Re=at.current)==null||Re.call(at,Y)}else Sa(null)},[et]),Hl=b.useCallback(()=>{var A;(A=He.current)==null||A.call(He),He.current=null,At.current=mv(),gv(At.current),Sa(null),B(null),l([]),J([]),ge.current=[],L([]),Ie.current=[],fe(null),me.current=null,Ee(null),Qe.current=null,Q(null),De.current=null,ce([]),_e.current=[],lt.current="",We(""),Z(null),p(""),z(null),Xr(null),xa([]),qn(null),u(""),Tt(!0)},[]),Zr=b.useCallback(A=>{xa(H=>[...H,A].slice(-10))},[]),$m=b.useCallback(A=>{xa(H=>H.filter((Y,he)=>he!==A))},[]),Gl=b.useCallback(async A=>{if(!A)return;if(A.size>a){p(`Attachment "${A.name}" is too large (max ${Math.round(a/1024)} KB). Raise the cap in Admin → Process Environment (NUVIRA_ATTACHMENT_MAX_BYTES).`);return}const H=new Uint8Array(await A.slice(0,8192).arrayBuffer()),Y=Jye(A.name,H);if(Y.how==="unsupported"){p(Y.reason);return}if(Y.how==="binary"){const Re=new Uint8Array(await A.arrayBuffer());Zr({name:A.name,content:Zye(Re),kind:"file",encoding:"base64"});return}const he=await A.text();Zr({name:A.name,content:he,kind:"file",encoding:"text"})},[Zr]),Lm=b.useCallback(A=>{const H=A.currentTarget,Y=A.clipboardData.getData("text")||"";Y.length>=Vye&&(Qa.current={start:H.selectionStart,end:H.selectionEnd},qn({text:Y}))},[]),vd=b.useCallback(()=>{const A=wa;if(!A)return;const H=Qa.current;u(Y=>H?Y.slice(0,H.start)+Y.slice(H.end):Y),Zr({name:"pasted-text.txt",content:A.text,kind:"paste",encoding:"text"}),qn(null),Qa.current=null},[wa,Zr]),yd=b.useCallback(A=>{sn(A.id),Kr(A.title==="(untitled conversation)"?"":A.title)},[]),to=b.useCallback(async A=>{const H=await K.renameChatSession(A,ba);H.ok?cr(Y=>Y.map(he=>he.id===A?{...he,title:ba.trim()||he.title}:he)):p(H.error||"Could not rename the session."),sn(null),Kr("")},[ba]),ql=b.useCallback(async A=>{const H=await K.deleteChatSession(A);H.ok?(cr(Y=>Y.filter(he=>he.id!==A)),At.current===A&&Hl()):p(H.error||"Could not delete the session.")},[Hl]),ti=(t==null?void 0:t.authenticated)===!0&&(t.role==="admin"||t.role==="operator"),bd=b.useRef(!1);b.useEffect(()=>{if(!ti||bd.current)return;bd.current=!0;const A=At.current;let H=!1,Y=null;const he=async()=>{const Re=await K.getChatSession(A);H||Re&&(Yt.current||l(Re.turns.map(ue=>({role:ue.role,content:ue.content,...ue.role==="assistant"?{followups:[],artifacts:wf(ue.content)}:{}}))),f(Re.busy===!0),Re.busy===!0&&(rn.current=Re.busySince??Date.now()),pe(Re.busy===!0),Re.pendingQuestion?Xr(Re.pendingQuestion):Re.busy||Xr(null),Re.busy&&(Y=setTimeout(()=>void he(),2500)))};return he(),()=>{H=!0,Y&&clearTimeout(Y)}},[ti]),b.useEffect(()=>{if(!se){Le(0),rn.current=null;return}const A=()=>Date.now()-(rn.current??Date.now());Le(A());const H=setInterval(()=>Le(A()),Kye);return()=>clearInterval(H)},[se]),b.useEffect(()=>{ti&&(K.listChatSessions().then(A=>{Array.isArray(A)&&cr(A)}),K.listProjects().then(A=>{Array.isArray(A)&&Ki(A)}))},[ti]);const Tr=b.useCallback(async A=>{const H=A.trim();if(!H)return;Vr("");const Y=await K.attachProject(H);if(Y.ok&&Y.project){Zs(Y.project),Vi("");const he=await K.listProjects();Array.isArray(he)&&Ki(he)}else Vr(Y.error||"Could not attach that directory.")},[]);at.current=Tr;const Na=b.useCallback(async A=>{ja(!0),Ar(!0),Ul("");const H=await K.browseDirectories(A,{showDrives:!A});H.ok&&(ne(H.path),Se(H.entries),Kn(H.parent),H.drives&&Js(H.drives),H.breadcrumbs&&Yr(H.breadcrumbs)),Ar(!1)},[]),Kl=b.useCallback(async A=>{Ar(!0),Ul("");const H=await K.browseDirectories(A);H.ok&&(ne(H.path),Se(H.entries),Kn(H.parent),H.breadcrumbs&&Yr(H.breadcrumbs)),Ar(!1)},[]),no=b.useCallback(async()=>{if(!W)return;const A=await K.browseDirectories(W);A.ok&&Se(A.entries)},[W]);b.useEffect(()=>K.onChatRetryEvent(H=>{if(H.sessionId!==At.current){K.listChatSessions().then(Y=>{Array.isArray(Y)&&cr(Y)});return}l(Y=>[...Y,{role:"assistant",content:H.content}]),H.kind==="answer"&&Z(null)}),[]),b.useEffect(()=>(Cr&&W&&(ei.current=setInterval(()=>{no()},5e3)),()=>{ei.current&&clearInterval(ei.current)}),[Cr,W,no]);const xd=b.useCallback(async()=>{if(typeof window<"u"&&"showDirectoryPicker"in window)try{const Y=(await window.showDirectoryPicker({mode:"read"})).name;if(!Y){Na();return}Vr(""),f(!0);const he=await K.resolveFolder(Y);f(!1),he.ok&&he.path?(Vi(he.path),Tr(he.path)):Vr('Folder "'+Y+'" found — selecting it now. If this is wrong, type the full path below.');return}catch(H){if((H==null?void 0:H.name)==="AbortError")return}Na()},[Na,Tr]),Zi=b.useCallback(A=>{if($e.current)return;$e.current=!0,ke.current=!1;const H=A.content||"(the agent produced no text — try rephrasing)";l(Y=>[...Y,{role:"assistant",content:H,error:A.generationFailed===!0,followups:A.followups??[],steps:ge.current,tools:Ie.current,plan:me.current,diff:Qe.current,draft:De.current,findings:_e.current,artifacts:wf(H)}]),lt.current="",We(""),p(""),Z(null),pe(!1),f(!1),Tt(!0)},[]),Vl=b.useCallback(async(A,H)=>{const Y=(e==null?void 0:e.pollMs)??Gye,he=(e==null?void 0:e.maxMisses)??qye;let Re=0;for(;;){if(await new Promise(ur=>setTimeout(ur,Y)),$e.current||!ke.current)return;const ue=await K.getChatSession(A);if(!ue){if(++Re>=he){ke.current=!1,pe(!1),f(!1),p("Lost contact with the server while this turn was running. The turn itself was not cancelled — its answer is in this conversation (reopen it) or in Traces.");return}continue}if(Re=0,ue.busy===!0){ue.pendingQuestion&&Xr(ue.pendingQuestion),typeof ue.busySince=="number"&&(rn.current=ue.busySince);continue}const Ne=[...ue.turns].reverse().find(ur=>ur.role==="assistant");Ne?Zi({content:Ne.content,followups:[]}):(ke.current=!1,pe(!1),f(!1),Z(H));return}},[Zi,e==null?void 0:e.pollMs,e==null?void 0:e.maxMisses]),ln=b.useCallback(async(A,H)=>{var ur,ro,W0;const Y=A.trim(),he=Array.isArray(H)?H:_r;if(!Y&&he.length===0||d)return;p(""),z(null),J([]),ge.current=[],L([]),Ie.current=[],fe(null),me.current=null,Ee(null),Qe.current=null,Q(null),De.current=null,ce([]),_e.current=[],l(Ae=>[...Ae,{role:"user",content:Y,attachments:he.length>0?he:void 0}]),u(""),xa([]),qn(null),Ft.current=Y||`[${he.length} attachment(s)]`,rn.current=Date.now(),f(!0),Tt(!1);const Re=At.current,ue=new AbortController;Yt.current=ue,Z(null),ke.current=!1,$e.current=!1,pe(!1),(ur=He.current)==null||ur.call(He),He.current=K.subscribeChat(Re,{onToken:Ae=>{lt.current+=Ae,We(lt.current)},onProgress:Ae=>{ge.current=[...ge.current,Ae],J(ge.current)},onQuestion:Ae=>{Xr(Ae),Wl(new Set)},onTool:Ae=>{const jt=[...Ie.current],Ji=jt.findIndex(N$=>N$.id===Ae.id),es={id:Ae.id,tool:Ae.tool,phase:Ae.phase,args:Ae.args,ok:Ae.ok,result:Ae.result,error:Ae.error,durationMs:Ae.durationMs};Ji>=0?jt[Ji]=es:jt.push(es),Ie.current=jt,L(jt)},onPlan:Ae=>{const jt={goal:Ae.goal,steps:Ae.steps.map(ebe),revision:Ae.revision};me.current=jt,fe(jt)},onDiff:Ae=>{const jt={files:Ae.files,summary:Ae.summary};Qe.current=jt,Ee(jt)},onSkillDraft:Ae=>{const jt={name:Ae.name,description:Ae.description,markdown:Ae.markdown,updatedAt:Ae.updatedAt,status:"pending"};De.current=jt,Q(jt)},onFinding:Ae=>{_e.current=[..._e.current,Ae],ce(_e.current)},onSecretRequest:Ae=>{xe(jt=>{const Ji=jt.findIndex(es=>es.skillName===Ae.skillName);if(Ji>=0){const es=[...jt];return es[Ji]=Ae,es}return[...jt,Ae]})},onExecutionResult:Ae=>{Pe(jt=>[...jt,Ae])},onTurnDone:Ae=>{ke.current&&Zi(Ae)}});const Ne=await K.chatSend(Re,Y||`(see ${he.length} attachment${he.length===1?"":"s"})`,{...T?{provider:T.provider,model:T.model}:{},...T?{strict:$}:{},projectPath:et==null?void 0:et.path,attachments:he.map(Ae=>({name:Ae.name,content:Ae.content,kind:Ae.kind,encoding:Ae.encoding??"text"})),...y?{worktree:!0,keepWorktree:k}:{},...j?{resume:x.trim()||!0}:{}},ue.signal);if(Yt.current=null,(ro=He.current)==null||ro.call(He),He.current=null,lt.current="",We(""),Ne.ok){z(Ne.generationFailed?null:`${Ne.provider??"provider"}${Ne.model?` / ${Ne.model}`:" (auto-routed)"}`),wt(Ne.routingNotice??null),an(Ne.workspaceNotice??null);const Ae=Ne.workspaceSource==="scratch"?Ne.workspacePath??null:null;In(Ae),!Ae&&Ne.workspacePath&&Ne.workspacePath!==(et==null?void 0:et.path)&&((W0=at.current)==null||W0.call(at,Ne.workspacePath)),Z(Ne.generationFailed&&!Ne.retryQueued&&!Ne.refused?Y:null);const jt=Ne.content||"(the agent produced no text — try rephrasing)";l(Ji=>[...Ji,{role:"assistant",content:jt,error:Ne.generationFailed,followups:Ne.followups,steps:ge.current,tools:Ie.current,plan:me.current,diff:Qe.current,draft:De.current,findings:Ne.findings??_e.current,worktree:Ne.worktree,resume:Ne.resume,turnReport:Ne.turnReport,refused:Ne.refused,needsProject:Ne.needsProject,artifacts:wf(jt)}])}else ue.signal.aborted?(p(""),Z(null)):Ne.turnStillRunning?(p(""),Z(null),pe(!0),ke.current=!0,$e.current=!1,Vl(Re,Y)):Ne.unauthorized?(n(Ae=>Ae&&{...Ae,authenticated:!1}),p("Session expired — log in again to chat.")):(p(Ne.error||"The agent could not answer — check that a provider API key is set for the dashboard process."),Z(Y));Ne.ok===!1&&Ne.turnStillRunning||(f(!1),Tt(!0))},[d,et,_r,y,k,j,x,T,$,Zi,Vl]),wd=b.useCallback(()=>{var A;(A=Yt.current)==null||A.abort(),K.chatCancel(At.current)},[]),kd=b.useCallback(async()=>{const A=E==="max"?"balanced":"max";R("");const H=await K.saveProcessEnvVar("NUVIRA_CAPABILITY_MODE",A);H.ok?(P(A),R(A==="max"?"⚡ Max capability is on for the next turn.":"⚖️ Back to balanced.")):R(H.error||"Could not change the capability mode.")},[E]),Sd=b.useCallback(async()=>{g(null);const A=await K.chatSupportBundle(At.current);g(A.ok?{kind:"ok",text:"Support bundle downloaded — attach it to your bug report."}:{kind:"err",text:A.error||"Could not build the support bundle."})},[]),Yl=b.useCallback(async A=>{Q(Y=>Y&&{...Y,status:"saving"});const H=await K.skillDraftAccept(A);Q(Y=>Y&&{...Y,status:H.ok?"saved":"error"}),H.ok||p(H.error||"Could not accept the draft.")},[]),Xl=b.useCallback(async A=>{const H=await K.skillDraftReject(A);H.ok?Q(Y=>Y&&{...Y,status:"rejected"}):p(H.error||"Could not reject the draft.")},[]),Ql=b.useCallback(A=>{ln(`Revise the skill draft "${A}" — improve it per your best judgment and present it again.`)},[ln]),jd=b.useCallback(async A=>{const H=await K.saveSecrets(A);if(!H.ok){p(H.error||"Could not save secrets.");return}const Y=H.refused??[];Y.length>0&&p(Y.map(he=>he.reason==="provider-credential"?`${he.name} is a provider credential — set it up as a provider, skills never receive it.`:`${he.name} was not saved (${he.reason}).`).join(" "))},[]),Zl=b.useCallback(A=>{if(A.length===0)return;const H=et?` in the attached project ${et.path}`:"";ln(`Commit exactly these files that I accepted on the diff card (and nothing else)${H}: ${A.join(", ")}. Show me a short confirmation before finishing.`)},[ln,et]),Jr=b.useCallback(async A=>{const H=It;if(!H)return;Xr(null),gd(""),Wl(new Set);const Y=await K.chatRespond(At.current,H.questionId,A);Y.ok||p(Y.error||"The question could not be answered — try sending your message again.")},[It]),Jl=b.useCallback(()=>{if(!It)return;const A=Qr.trim(),H=It.multiSelect?[...Qi]:[...Qi][0];It.multiSelect?Jr({index:[...Qi],...A?{custom:A}:{}}):Jr(A?{index:-1,custom:A}:H!==void 0?{index:H}:{index:-1})},[It,Qi,Qr,Jr]),Nd=b.useCallback(()=>{It&&Jr({index:-1})},[It,Jr]),Ed=b.useCallback(A=>{Wl(H=>{const Y=new Set(H);return It!=null&&It.multiSelect?Y.has(A)?Y.delete(A):Y.add(A):(Y.clear(),Y.add(A)),Y})},[It]),C=b.useCallback(async()=>{var H;(H=He.current)==null||H.call(He),He.current=null,At.current=mv(),gv(At.current),l([]),J([]),ge.current=[],L([]),Ie.current=[],fe(null),me.current=null,Ee(null),Qe.current=null,Q(null),De.current=null,ce([]),_e.current=[],lt.current="",We(""),Z(null),p(""),z(null),Xr(null);const A=await K.listChatSessions();Array.isArray(A)&&cr(A)},[]),V=((re=[...o].reverse().find(A=>{var H;return A.role==="assistant"&&!A.error&&(((H=A.followups)==null?void 0:H.length)??0)>0}))==null?void 0:re.followups)??[];return i.jsxs("div",{className:"panel",children:[i.jsx(Oe,{icon:"💬",title:"Chat with the agent",actions:i.jsxs("div",{className:"chat-head-actions",children:[M?i.jsx("span",{className:"admin-hint",children:M}):null,i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:()=>void C(),disabled:d||o.length===0,children:"🗑 New conversation"})]})}),t!=null&&t.authenticated?ti?i.jsxs(i.Fragment,{children:[i.jsx("div",{className:"chat-project-bar",children:et?i.jsxs("div",{className:"chat-project-attached",children:[i.jsx("span",{className:"chat-project-icon",children:"📁"}),i.jsx("span",{className:"chat-project-name",children:et.name}),i.jsxs("span",{className:"chat-project-meta",children:[et.fileCount," files · ",et.symbolCount," symbols",et.truncated?" · truncated map":""]}),i.jsx("span",{className:"chat-project-path",title:et.path,children:et.path}),i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>Zs(null),children:"✕ detach"})]}):i.jsxs("div",{className:"chat-project-pick",children:[i.jsx("span",{className:"chat-project-icon",children:"📁"}),i.jsx("span",{className:"chat-project-hint",children:"Select Project Folder"}),Za.find(A=>A.kind==="cwd")?i.jsxs("span",{className:"chat-project-cwd",title:"Working directory used when no folder is attached",children:["⚙️ ",Za.find(A=>A.kind==="cwd").path]}):null,Za.length>0?i.jsx("span",{className:"chat-project-chips",children:Za.filter(A=>A.kind!=="cwd").slice(0,3).map(A=>i.jsx("button",{type:"button",className:"chat-chip",onClick:()=>void Tr(A.path),children:A.name},A.path))}):null,i.jsx("input",{className:"chat-project-input",ref:Gn,value:Ja,onChange:A=>Vi(A.target.value),onKeyDown:A=>{A.key==="Enter"&&(A.preventDefault(),Tr(Ja))},placeholder:"or type a path, e.g. ~/code/my-app",disabled:d}),i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>void Tr(Ja),disabled:d||!Ja.trim(),children:"Attach"}),i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>void xd(),title:"Pick a project folder using your system's folder picker (Finder / Explorer)",children:"🗂️ Browse"}),Yi?i.jsx("span",{className:"chat-project-error",children:Yi}):null,Cr?i.jsxs("div",{className:"chat-browse-popover",children:[i.jsxs("div",{className:"chat-browse-head",children:[i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>ja(!1),title:"Close",children:"✕"}),i.jsx("div",{className:"chat-browse-breadcrumbs",children:Xi.length>0&&!W?i.jsx("span",{className:"admin-hint",children:"Select a drive or home folder:"}):i.jsxs(i.Fragment,{children:[i.jsx("button",{type:"button",className:"chat-breadcrumb",onClick:()=>void Na(),children:"🏠"}),md.map((A,H)=>i.jsxs("span",{children:[i.jsx("span",{className:"chat-breadcrumb-sep",children:"/"}),i.jsx("button",{type:"button",className:"chat-breadcrumb",onClick:()=>void Kl(A.path),children:A.name})]},A.path))]})})]}),Xi.length>0&&!W?i.jsx("div",{className:"chat-browse-drives",children:Xi.map(A=>i.jsx("button",{type:"button",className:"chat-browse-drive",onClick:()=>void Kl(A.path),children:A.name},A.path))}):null,je.length>5?i.jsx("div",{className:"chat-browse-search",children:i.jsx("input",{type:"text",className:"chat-browse-filter",placeholder:"🔍 Filter folders…",value:Fl,onChange:A=>Ul(A.target.value),autoFocus:!0})}):null,i.jsx("div",{className:"chat-browse-list",children:En?i.jsx("span",{className:"admin-hint",children:"Loading…"}):je.length===0?i.jsx("span",{className:"admin-hint",children:"No subdirectories found"}):je.filter(A=>!Fl||A.name.toLowerCase().includes(Fl.toLowerCase())).map(A=>i.jsxs("button",{type:"button",className:"chat-browse-entry",onClick:()=>void Kl(A.path),children:[i.jsx("span",{className:"chat-browse-entry-icon",children:"📁"}),i.jsx("span",{className:"chat-browse-entry-name",children:A.name}),A.modified?i.jsx("span",{className:"chat-browse-entry-date",children:new Date(A.modified).toLocaleDateString()}):null]},A.path))}),i.jsxs("div",{className:"chat-browse-foot",children:[i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>void no(),title:"Refresh folder list",children:"🔄"}),i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>{ja(!1),Tr(W)},disabled:!W,children:"📁 Select this folder"})]})]}):null]})}),ka&&(!et||et.path!==ka)?i.jsxs("div",{className:"chat-session-project-banner",children:[i.jsxs("span",{children:["⚠️ This conversation was working in ",i.jsx("code",{children:ka})]}),et?i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>void Tr(ka),children:"📁 Switch to it"}):i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>void Tr(ka),children:"📁 Attach it"})]}):null,i.jsxs("div",{className:"chat-layout",children:[zl?i.jsxs("div",{className:"chat-sidebar",children:[i.jsxs("div",{className:"chat-sidebar-head",children:[i.jsx("span",{children:"📁 Sessions"}),i.jsxs("div",{className:"chat-sidebar-head-actions",children:[i.jsx("button",{type:"button",className:"chat-mini-action",title:"New chat",onClick:Hl,children:"+ New"}),i.jsx("button",{type:"button",className:"chat-mini-action",title:"Collapse history",onClick:()=>Tt(!1),children:"▸"})]})]}),i.jsx("input",{className:"chat-session-search",placeholder:"Search conversations…",value:ya,onChange:A=>pn(A.target.value)}),lr.length===0?i.jsx("div",{className:"chat-sidebar-empty",children:"No past conversations yet."}):i.jsx("div",{className:"chat-sidebar-list",children:mbe(lr,ya).map(({label:A,items:H})=>i.jsxs("div",{className:"chat-session-group",children:[i.jsx("div",{className:"chat-session-group-label",children:A}),H.map(Y=>i.jsx("div",{className:`chat-session-item${Y.id===At.current?" chat-session-active":""}`,children:Xs===Y.id?i.jsxs("div",{className:"chat-session-rename",children:[i.jsx("input",{autoFocus:!0,value:ba,onChange:he=>Kr(he.target.value),onKeyDown:he=>{he.key==="Enter"&&to(Y.id),he.key==="Escape"&&sn(null)},placeholder:"Session title"}),i.jsx("button",{type:"button",className:"chat-mini-action",onClick:()=>void to(Y.id),children:"✓"})]}):i.jsxs(i.Fragment,{children:[i.jsxs("button",{type:"button",className:"chat-session-main",onClick:()=>void Im(Y.id),title:Y.preview||Y.title,children:[i.jsx("span",{className:"chat-session-title",children:Y.title}),i.jsx("span",{className:"chat-session-preview",children:Y.firstUser||Y.preview}),i.jsxs("span",{className:"chat-session-meta",children:[Y.projectPath?`📁 ${Y.projectPath.split("/").pop()} · `:"",Y.turnCount," msg",Y.turnCount===1?"":"s"," · ",new Date(Y.updatedAt).toLocaleString()]})]}),i.jsxs("span",{className:"chat-session-actions",children:[i.jsx("button",{type:"button",className:"chat-mini-action",title:"Rename",onClick:()=>yd(Y),children:"✏️"}),i.jsx("button",{type:"button",className:"chat-mini-action",title:"Delete",onClick:()=>void ql(Y.id),children:"🗑"})]})]})},Y.id))]},A))})]}):i.jsx("div",{className:"chat-rail",children:i.jsx("button",{type:"button",className:"chat-rail-btn",onClick:()=>Tt(!0),title:"Show history",children:"📁"})}),i.jsxs("div",{className:"chat-main",children:[i.jsxs("div",{className:"chat-thread",ref:eo,role:"log","aria-live":"polite",children:[o.length===0?i.jsxs("div",{className:"empty-state",children:[i.jsx("p",{className:"empty-state-title",children:"Say anything — the agent decides what to do (answer, fix code, plan, run the pipeline)."}),i.jsxs("div",{className:"empty-state-chips",children:[i.jsx("button",{type:"button",className:"chat-chip",onClick:()=>void ln("what's the state of this project?"),children:"📋 assess this project"}),i.jsx("button",{type:"button",className:"chat-chip",onClick:()=>void ln("run the test suite"),children:"🧪 run the tests"}),i.jsx("button",{type:"button",className:"chat-chip",onClick:()=>void ln("stop the gateway"),children:"⏹ stop the gateway"}),i.jsx("button",{type:"button",className:"chat-chip",onClick:()=>void ln("load the code-assessment skill and assess this project"),children:"🧠 load the code-assessment skill"}),i.jsx("button",{type:"button",className:"chat-chip",onClick:()=>void ln("learn the workflow I just did as a skill"),children:"📚 learn a workflow as a skill"}),i.jsx("button",{type:"button",className:"chat-chip",onClick:()=>void ln("publish the current version"),children:"🚀 publish the release"})]})]}):o.map((A,H)=>i.jsxs("div",{className:`chat-bubble chat-${A.role}${A.error?" chat-error":""}`,children:[i.jsx("div",{className:"chat-bubble-role",children:A.role==="user"?"You":"🤖 Agent"}),A.role==="assistant"?i.jsx("div",{className:"chat-bubble-text",children:i.jsx(q_,{text:A.content})}):i.jsx("div",{className:"chat-bubble-text",children:A.content}),A.role==="user"&&A.attachments&&A.attachments.length>0?i.jsxs("details",{className:"chat-steps",open:A.attachments.length===1,children:[i.jsxs("summary",{children:["📎 ",A.attachments.length," attachment",A.attachments.length===1?"":"s",":"," ",A.attachments.map(Y=>Y.name).join(", ")]}),A.attachments.map((Y,he)=>i.jsxs("div",{className:"chat-attach-content",children:[i.jsxs("div",{className:"admin-hint",children:[Y.name," — ",bt(Y.content.length)," chars"]}),i.jsx("pre",{children:Y.content})]},he))]}):null,A.role==="assistant"&&A.diff?i.jsxs("details",{className:"chat-steps",open:!0,children:[i.jsxs("summary",{children:["Changes: ",A.diff.summary]}),i.jsx(Cc,{diff:A.diff,selectable:!0,onCommitAccepted:Zl})]}):null,A.role==="assistant"&&A.artifacts&&(A.artifacts.diffs.length>0||A.artifacts.results.length>0||A.artifacts.deploys.length>0)?i.jsxs(ibe,{children:[A.artifacts.diffs.map((Y,he)=>i.jsx("div",{"data-artifact-card":!0,tabIndex:0,role:"group","aria-label":`Diff: ${Y.summary}`,className:"chat-artifact-item",children:et?i.jsx(Cc,{diff:Y,selectable:!0,onCommitAccepted:Zl}):i.jsx(Cc,{diff:Y,lockedHint:"Attach a project to review and commit these changes."})},`diff-${he}`)),A.artifacts.results.map((Y,he)=>i.jsx("div",{"data-artifact-card":!0,tabIndex:0,role:"group","aria-label":`Result: ${Y.title}`,className:"chat-artifact-item",children:i.jsx(rbe,{result:Y})},`result-${he}`)),A.artifacts.deploys.map((Y,he)=>i.jsx("div",{"data-artifact-card":!0,tabIndex:0,role:"group","aria-label":`Deployment: ${Y.url}`,className:"chat-artifact-item",children:i.jsx(abe,{deploy:Y})},`deploy-${he}`))]}):null,A.role==="assistant"&&A.draft?i.jsxs("details",{className:"chat-steps",open:!0,children:[i.jsxs("summary",{children:["Skill draft: ",A.draft.name]}),i.jsx(X_,{draft:A.draft,onAccept:Yl,onReject:Xl,onEdit:Ql})]}):null,A.role==="assistant"&&A.plan?i.jsxs("details",{className:"chat-steps",open:!0,children:[i.jsxs("summary",{children:["Plan: ",A.plan.goal]}),i.jsx(Q_,{plan:A.plan})]}):null,A.role==="assistant"&&A.refused?i.jsx("div",{className:"chat-refused-line",children:"⛔ This turn did not run — the isolation it asked for could not be made. Nothing was written, and the reason is above."}):null,A.role==="assistant"&&A.needsProject?i.jsx("div",{className:"chat-refused-line",children:"📁 Nothing was run — attach a project folder above, then send the message again."}):null,A.role==="assistant"&&A.worktree?i.jsx(dbe,{worktree:A.worktree}):null,A.role==="assistant"&&A.resume?i.jsx(fbe,{resume:A.resume}):null,A.role==="assistant"&&A.turnReport?i.jsx(hbe,{report:A.turnReport}):null,A.role==="assistant"&&A.findings&&A.findings.length>0?i.jsx(J_,{findings:A.findings}):null,A.role==="assistant"&&A.tools&&A.tools.length>0?i.jsxs("details",{className:"chat-steps chat-tool-details",children:[i.jsxs("summary",{children:[A.tools.length," tool call",A.tools.length===1?"":"s"]}),i.jsx(Z_,{tools:A.tools})]}):null,A.role==="assistant"&&A.steps&&A.steps.length>0?i.jsxs("details",{className:"chat-steps",children:[i.jsxs("summary",{children:[A.steps.length," step",A.steps.length===1?"":"s"]}),i.jsx("div",{className:"chat-step-line",children:A.steps.map((Y,he)=>i.jsx("div",{children:Y.trim()},he))})]}):null]},H)),d?i.jsxs("div",{className:"chat-bubble chat-assistant",children:[i.jsx("div",{className:"chat-bubble-role",children:"🤖 Agent"}),ie?i.jsx(Q_,{plan:ie}):null,ve?i.jsx(Cc,{diff:ve}):null,y&&d?i.jsx("div",{className:"chat-resume-line",children:"🌿 this turn is running in its own git worktree — the diff arrives with the answer"}):null,j&&d?i.jsx("div",{className:"chat-resume-line",children:"↩️ this turn is replaying the recorded steps of this ask that are unchanged — the count arrives with the answer"}):null,ae.length>0?i.jsx(J_,{findings:ae}):null,ee?i.jsx(X_,{draft:ee,onAccept:Yl,onReject:Xl,onEdit:Ql}):null,G.map(A=>i.jsx(sbe,{request:A,onSave:jd},A.skillName)),we.map((A,H)=>i.jsx(obe,{result:A},`${A.skillName}-${H}`)),i.jsx(Z_,{tools:F,live:!0}),pt?i.jsx("div",{className:"chat-bubble-text chat-streaming",children:i.jsx(q_,{text:pt})}):null,i.jsx("div",{className:"chat-working",children:O.length>0?i.jsx("span",{className:"chat-working-lines",children:O.map((A,H)=>i.jsx("div",{className:"chat-step-line",children:A.trim()},H))}):i.jsxs(i.Fragment,{children:["💭 thinking… ",i.jsx("span",{className:"chat-dots"})]})})]}):null]}),h?i.jsx("div",{className:"admin-row-msg admin-row-msg-err",children:h}):null,se&&It?i.jsxs("div",{className:"admin-row-msg chat-routing-notice",children:["❓ Waiting for ",i.jsx("strong",{children:"your"})," answer — choose one of the options above and the turn continues where it stopped. Nothing is stuck: the server is holding this turn open for you, and the agent has not been told anything yet (its own words: it asked instead of guessing)."]}):se?i.jsxs("div",{className:"admin-row-msg chat-routing-notice",children:["⏳ Still working on the server — ",Gb(zt)," elapsed on this turn, counted from when it started (not from when this page stopped waiting for the reply). This is a long-running turn, not a failure: the answer will appear here by itself when it lands, and you can close this page and come back."]}):null,Mn?i.jsxs("div",{className:"admin-row-msg chat-routing-notice",children:[i.jsxs("span",{children:["ℹ️ ",Mn]})," ",i.jsx("button",{className:"chat-routing-notice-dismiss",type:"button","aria-label":"Dismiss routing notice",onClick:()=>wt(null),children:"✕"})]}):null,Mt?i.jsxs("div",{className:"admin-row-msg chat-routing-notice",children:[i.jsxs("span",{children:["📁 ",Mt]})," ",i.jsx("button",{className:"chat-routing-notice-dismiss",type:"button","aria-label":"Dismiss workspace notice",onClick:()=>an(null),children:"✕"})]}):null,or?i.jsxs("div",{className:"admin-row-msg chat-scratch-notice","data-testid":"chat-scratch-notice",children:[i.jsxs("span",{children:["🗂️ No folder was attached, so this turn used a temporary workspace:"," ",i.jsx("code",{className:"chat-scratch-path",children:or})]})," ",i.jsx("button",{type:"button",className:"admin-mini-btn",title:"Attach this folder to the chat and keep working in it",onClick:()=>{var H;const A=or;In(null),(H=at.current)==null||H.call(at,A)},children:"✓ Use as my project path"})," ",i.jsx("button",{type:"button",className:"admin-mini-btn",title:"Attach a folder of your own — the next turn runs inside it",onClick:()=>{var A;In(null),(A=Gn.current)==null||A.focus()},children:"📁 Attach my own folder"})," ",i.jsx("button",{type:"button",className:"chat-routing-notice-dismiss","aria-label":"Dismiss temporary workspace notice",onClick:()=>In(null),children:"✕"})]}):null,m?i.jsx("div",{className:`admin-row-msg${m.kind==="err"?" admin-row-msg-err":""}`,children:m.text}):null,q&&!d?i.jsxs("div",{className:"chat-retry-row",children:[i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:()=>void ln(q),children:"↻ Retry"}),i.jsx("span",{className:"admin-hint",children:"Re-send the last message — the turn failed."})]}):null,It?i.jsxs("div",{className:"chat-resolve-card chat-question-card",children:[i.jsx("div",{className:"chat-resolve-head",children:i.jsxs("strong",{children:["🤔 ",It.question]})}),i.jsx("div",{className:"chat-resolve-options",children:It.choices.map((A,H)=>i.jsxs("button",{type:"button",className:`chat-chip${Qi.has(H)?" chat-chip-selected":""}`,onClick:()=>Ed(H),children:[A.label,A.description?i.jsxs("span",{className:"admin-hint",children:[" — ",A.description]}):null]},`${A.label}-${H}`))}),i.jsx("input",{className:"chat-question-custom",type:"text",placeholder:"✏️ Or type your own answer…",value:Qr,onChange:A=>gd(A.target.value),onKeyDown:A=>{A.key==="Enter"&&!A.shiftKey&&(A.preventDefault(),Jl())}}),i.jsxs("div",{className:"chat-resolve-foot",children:[i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:Jl,children:Qr.trim()?"Send answer":It.multiSelect?"Submit":"Choose"}),i.jsx("button",{className:"admin-mini-btn",type:"button",onClick:Nd,children:"Skip — best judgment"})]})]}):null,V.length>0&&!d?i.jsxs("div",{className:"chat-followups",children:[i.jsx("span",{className:"admin-hint",children:"Next steps:"}),V.map((A,H)=>i.jsx("button",{className:"chat-chip",type:"button",onClick:()=>void ln(A.prompt),children:A.label||A.prompt},H))]}):null,i.jsxs("form",{className:`chat-composer${Gi?" chat-composer-drag":""}`,onSubmit:A=>{A.preventDefault(),ln(c)},onDragOver:A=>{A.preventDefault(),qi(!0)},onDragLeave:()=>qi(!1),onDrop:A=>{var Y;A.preventDefault(),qi(!1);const H=Array.from(((Y=A.dataTransfer)==null?void 0:Y.files)??[]);for(const he of H.slice(0,10))Gl(he)},children:[wa?i.jsxs("div",{className:"chat-paste-offer",children:[i.jsxs("span",{className:"admin-hint",children:["📄 You pasted ",bt(wa.text.length)," characters. Attach it as a file instead?"]}),i.jsx("button",{type:"button",className:"chat-chip",onClick:vd,children:"Attach as text"}),i.jsx("button",{type:"button",className:"chat-mini-action",onClick:()=>{qn(null),Qa.current=null},children:"Keep inline"})]}):null,_r.length>0?i.jsx("div",{className:"chat-attach-row",children:_r.map((A,H)=>i.jsxs("span",{className:"chat-attach-chip",title:A.encoding==="base64"?`${A.name} (${bt(A.content.length)} base64 chars — read on the server)`:`${A.name} (${bt(A.content.length)} chars)`,children:["📎 ",A.name,i.jsx("span",{className:"admin-hint",children:A.encoding==="base64"?`${Math.round(A.content.length*3/4096)} KB`:`${bt(A.content.length)}c`}),i.jsx("button",{type:"button",className:"chat-mini-action",onClick:()=>$m(H),children:"✕"})]},`${A.name}-${H}`))}):null,i.jsxs("div",{className:"chat-controls",children:[i.jsx("input",{ref:Qs,type:"file",accept:".pdf,.docx,.xlsx,.pptx,.txt,.md,.markdown,.text,.log,.csv,.tsv,.json,.xml,.yaml,.yml,.html,.htm,text/*",style:{display:"none"},onChange:A=>{var Y;const H=(Y=A.target.files)==null?void 0:Y[0];H&&Gl(H),A.target.value=""}}),i.jsx("button",{type:"button",className:"chat-attach-btn",title:"Attach a file (up to 300 KB): PDF, DOCX, XLSX, PPTX or text — documents are read on the server",disabled:d||_r.length>=10,onClick:()=>{var A;return(A=Qs.current)==null?void 0:A.click()},children:"📎 attach"}),i.jsx("button",{type:"button",className:"chat-attach-btn","aria-label":"Download support bundle",title:"Download a support bundle for this chat: the session debug log (which backend served each turn) plus the conversation. Needs NUVIRA_DEBUG_LOG=1 in the dashboard process.",onClick:()=>void Sd(),children:"🐞 debug"}),i.jsxs("button",{type:"button",className:`chat-attach-btn${y?" chat-attach-btn-on":""}`,"aria-label":"Run turns in an isolated git worktree","aria-pressed":y,title:y?"Turns run in their own git worktree and report the diff — click to run in the project tree again":"Run turns in their own git worktree of the attached project, and report the diff against the base commit. Refuses rather than running in your tree when the directory cannot be isolated. Needs an attached project (or the server's own git working directory).",onClick:()=>{v(A=>!A),g(null)},children:["🌿",y?" isolated":" isolate"]}),i.jsxs("button",{type:"button",className:`chat-attach-btn${j?" chat-attach-btn-on":""}`,"aria-label":"Replay this ask's recorded steps instead of paying for them again","aria-pressed":j,title:j?"Recorded steps whose input is unchanged are replayed instead of paid for — click to run fresh again":"Replay the steps of an earlier run of this same ask whose input is unchanged, instead of paying for them again. The record is keyed by the ask and the directory; name a checkpoint id below to resume a specific one. A step whose input CHANGED is paid for again.",onClick:()=>{S(A=>!A),g(null)},children:["↩️",j?" resuming":" resume"]}),j?i.jsx("input",{className:"chat-resume-input",value:x,onChange:A=>N(A.target.value),placeholder:"checkpoint id (blank = this ask's record)",title:"Resume this specific checkpoint record. Blank resumes the record for this ask in this directory.","aria-label":"Checkpoint id to resume",disabled:d}):null,y?i.jsxs("button",{type:"button",className:`chat-attach-btn${k?" chat-attach-btn-on":""}`,"aria-pressed":k,title:k?"The worktree is KEPT after the turn so you can look inside it":"The worktree is measured and removed after each turn",onClick:()=>w(A=>!A),children:["📌",k?" keep":" drop"]}):null,i.jsxs("select",{className:"chat-model-picker","aria-label":"Model: Auto or a specific routable model",title:T?`Pinned to ${T.provider}/${T.model} for this chat. Choose Auto to let the agent route again.`:"Auto (default): the agent picks the best routable model each turn. Choose one to pin it for this chat.",value:T?`${T.provider}|${T.model}`:"",disabled:d,onChange:A=>{const H=A.target.value;if(!H){B(null);return}const Y=H.indexOf("|");B({provider:H.slice(0,Y),model:H.slice(Y+1)})},children:[i.jsx("option",{value:"",children:"🤖 Auto (agent decides)"}),T&&!D.some(A=>A.provider===T.provider&&A.model===T.model)?i.jsxs("option",{value:`${T.provider}|${T.model}`,children:[T.provider,"/",T.model," · pinned"]}):null,D.map(A=>i.jsxs("option",{value:`${A.provider}|${A.model}`,children:[A.provider,"/",A.model," · ",A.band," (",A.capability.toFixed(2),")"]},`${A.provider}|${A.model}`))]}),T?i.jsx("button",{type:"button",className:`chat-attach-btn${$?" chat-attach-btn-on":""}`,"aria-label":"Strict model pin: use this model only","aria-pressed":$,disabled:d,title:$?`This chat runs on ${T.provider}/${T.model} only. If it is unavailable the turn STOPS and says which model did not answer, instead of substituting another one.`:`Fallback allowed: auto routing may substitute another model if ${T.provider}/${T.model} is unavailable. Turn the lock on to work with this model only.`,onClick:()=>I(A=>!A),children:$?"🔒 pinned only":"🔓 fallback allowed"}):null,i.jsx("button",{type:"button",className:`chat-attach-btn${E==="max"?" chat-attach-btn-on":""}`,"aria-label":"Capability mode: balanced or max","aria-pressed":E==="max",disabled:d,title:E==="max"?"Max capability: every turn routes to a strong model (a reasoning floor — not merely “paid”), cost ceilings are lifted, paid models are always allowed, and the loop gets its longest reasoning budget. Click to return to balanced.":"Balanced (default): the best model for complex/critical work and cheaper models for simple work, escalating when a stall is detected. Click for max capability — cost is not a concern.",onClick:()=>void kd(),children:E==="max"?"⚡ max":"⚖️ balanced"}),_?i.jsx("span",{className:"admin-hint",children:_}):null]}),i.jsxs("div",{className:"chat-input-row",children:[i.jsx("textarea",{className:"chat-input-box",value:c,onChange:A=>u(A.target.value),onPaste:Lm,onKeyDown:A=>{A.key==="Enter"&&!A.shiftKey?(A.preventDefault(),ln(c)):A.key==="ArrowUp"&&c===""&&Ft.current&&(A.preventDefault(),u(Ft.current))},placeholder:"Message the agent… (Enter to send · Shift+Enter for a new line · ↑ recalls last · 📎 attach a file or paste a large document)",disabled:d,maxLength:8e3,rows:1,autoFocus:!0}),d?i.jsx("button",{className:"admin-mini-btn chat-cancel-btn",type:"button",onClick:wd,children:"⏹ Cancel"}):null,i.jsx("button",{className:"admin-refresh-btn",type:"submit",disabled:d||!c.trim()&&_r.length===0,children:d?"⏳ Working…":"➤ Send"})]})]}),i.jsxs("p",{className:"admin-hint",children:["Each message runs the full agent loop in the dashboard process (same engine as"," ",i.jsx("code",{children:'nuvira chat "<prompt>"'}),") — the provider API keys must be configured in the dashboard process. Clarifications (",i.jsx("code",{children:"ask_user"}),") appear as a question card here — choose an answer or skip (best judgment)."]})]})]})]}):i.jsx("div",{className:"admin-login-hint",children:i.jsx("p",{children:"Your role can view the dashboard but not chat (requires admin or operator)."})}):i.jsxs("div",{className:"admin-login-hint",children:[i.jsx("p",{children:"Log in (admin or operator) to chat with the agent. Configure the dashboard admin credential first if this is a fresh setup."}),(t==null?void 0:t.configured)===!1?i.jsxs("p",{className:"admin-hint",children:["Run ",i.jsx("code",{children:"nuvira dashboard"})," once, or set ",i.jsx("code",{children:"NUVIRA_DASHBOARD_ADMIN_USER"})," / ",i.jsx("code",{children:"NUVIRA_DASHBOARD_ADMIN_PASSWORD"}),"."]}):null]})]})}const vbe={running:"⏳ running",done:"✅ done",failed:"❌ failed",cancelled:"⏹ cancelled",timeout:"⏰ timed out",error:"💥 error",hung:"🚫 stopped (hung)"},ybe=0;function j$({presets:e,customPlaceholder:t,timeoutMs:n=ybe,hint:r}){const[a,s]=b.useState(null),o=qr(),[l,c]=b.useState(!1),[u,d]=b.useState(""),[f,h]=b.useState(""),[p,m]=b.useState(null),[g,y]=b.useState([]),[v,k]=b.useState(0),w=b.useRef(null),j=b.useRef(null),S=b.useRef(Date.now());b.useEffect(()=>{K.fetchAdminAuthStatus().then(P=>{s(P?{authenticated:P.authenticated,role:P.role??null}:{authenticated:!1,role:null})})},[o]),b.useEffect(()=>{var P,_;try{(_=(P=w.current)==null?void 0:P.scrollIntoView)==null||_.call(P,{block:"end"})}catch{}},[g]),b.useEffect(()=>()=>{var P;(P=j.current)==null||P.call(j)},[]);const x=(a==null?void 0:a.authenticated)===!0&&(a.role==="admin"||a.role==="operator"),N=b.useCallback(async(P,_)=>{var $;if(l)return;c(!0),d(""),y([]),S.current=Date.now(),k(0);const R=await K.startTask(P,_??n);if(!R.ok||!R.task){d(R.error||"Could not start the command."),c(!1);return}const T=R.task;m(T);const B=await K.getTask(T.id);B!=null&&B.task&&y(B.task.logs.map(I=>({stream:I.stream,text:I.text}))),($=j.current)==null||$.call(j),j.current=K.subscribeTask(T.id,{onLog:I=>y(D=>[...D,{stream:I.stream,text:I.text}]),onStatus:I=>{m(D=>D&&{...D,status:I}),I!=="running"&&c(!1)}})},[l,n]),E=b.useCallback(async()=>{p&&await K.cancelTask(p.id)},[p]);return b.useEffect(()=>{if(!l)return;const P=setInterval(()=>k(Date.now()-S.current),1e3);return()=>clearInterval(P)},[l]),i.jsxs("div",{className:"ops-console",children:[a!=null&&a.authenticated?x?i.jsxs(i.Fragment,{children:[i.jsx("div",{className:"ops-presets",children:e.map(P=>i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:()=>void N(P.args,P.timeoutMs),disabled:l,children:P.label},P.label))}),i.jsxs("div",{className:"ops-custom-row",children:[i.jsx("input",{type:"text",value:f,onChange:P=>h(P.target.value),placeholder:t,disabled:l,maxLength:160}),i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:()=>void N(f.trim().split(/\s+/)),disabled:l||!f.trim(),children:"Run"})]}),r?i.jsx("p",{className:"admin-hint",children:r}):null]}):i.jsx("div",{className:"admin-login-hint",children:"Your role can view but not run commands (requires admin or operator)."}):i.jsx("div",{className:"admin-login-hint",children:"Log in (admin or operator) to run commands."}),u?i.jsx("div",{className:"admin-row-msg admin-row-msg-err",children:u}):null,p?i.jsxs("div",{className:"ops-console-box",children:[i.jsxs("div",{className:"ops-console-head",children:[i.jsxs("span",{children:[p.command," · ",i.jsx("span",{className:p.status==="running"?"task-status-running":"",children:vbe[p.status]})," · ",i.jsx("span",{className:"task-elapsed",children:p.status==="running"?Gb(v):Gb(p.durationMs??v)})]}),p.status==="running"?i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:()=>void E(),children:"⏹ Cancel"}):null]}),i.jsxs("pre",{className:"ops-console",role:"log",children:[g.length>0?g.map((P,_)=>i.jsx("div",{children:P.text},_)):i.jsx("div",{className:"admin-hint",children:"Waiting for output…"}),i.jsx("div",{ref:w})]})]}):null]})}const bbe=[{label:"⚡ Quick smoke",args:["eval","run","--tasks","quick","--format","text"]},{label:"⏱ Medium suite",args:["eval","run","--tasks","medium","--format","text"]},{label:"🐢 Slow suite",args:["eval","run","--tasks","slow","--format","text"]},{label:"🏆 M2B parity",args:["eval","run","--suite","m2b","--format","text"]},{label:"📦 Full suite",args:["eval","run","--suite","full","--format","text"]}];function eC(e){return typeof e!="number"?"—":`${Math.round(e*100)}%`}function xbe(e){return new Date(e).toLocaleString()}function wbe({data:e}){var n;const t=((n=e==null?void 0:e.evals)==null?void 0:n.runs)??[];return i.jsxs("div",{className:"panel",children:[i.jsx(Oe,{icon:"🏆",title:"Evals — run nuvira eval from the GUI"}),i.jsx(j$,{presets:bbe,customPlaceholder:"e.g. eval run --tasks my-task --provider groq --model llama",timeoutMs:9e5,hint:i.jsxs(i.Fragment,{children:["Runs the real ",i.jsx("code",{children:"nuvira eval run"})," as an isolated process — same engine, same ledger, same results as the CLI. Long suites can take minutes; you can cancel mid-run."]})}),i.jsx("h2",{className:"section-subtitle",children:"📜 Past runs (auto-refreshes)"}),t.length>0?i.jsx("div",{className:"admin-table-wrapper",children:i.jsxs("table",{className:"admin-table",children:[i.jsx("thead",{children:i.jsxs("tr",{children:[i.jsx("th",{children:"Started"}),i.jsx("th",{children:"Provider"}),i.jsx("th",{children:"Model"}),i.jsx("th",{children:"Tasks"}),i.jsx("th",{children:"Pass"}),i.jsx("th",{children:"Completion"}),i.jsx("th",{children:"Composite"}),i.jsx("th",{children:"Cost"})]})}),i.jsx("tbody",{children:t.map(r=>i.jsxs("tr",{children:[i.jsx("td",{children:xbe(r.startedAt)}),i.jsx("td",{className:"admin-provider-type",children:r.provider}),i.jsx("td",{children:r.model}),i.jsx("td",{children:r.summary.totalTasks}),i.jsxs("td",{children:[r.summary.tasksPassed,"/",r.summary.totalTasks]}),i.jsx("td",{children:eC(r.summary.completionRate)}),i.jsx("td",{children:eC(r.summary.avgCompositeScore)}),i.jsxs("td",{children:["$",(r.summary.totalCostUsd??0).toFixed(4)]})]},r.id))})]})}):i.jsx("div",{className:"empty-state",children:"No eval runs yet — start one above (or `nuvira eval run` from the CLI)."})]})}const kbe=[{label:"🌐 Gateway status",args:["gateway","status"]},{label:"📮 Delivery ledger",args:["gateway","delivery"]},{label:"▶️ Start gateway (foreground)",args:["gateway","start","--no-events"],timeoutMs:0},{label:"⏰ Cron jobs",args:["admin","cron","list"]}];function Sbe(){return i.jsxs("div",{className:"panel",children:[i.jsx(Oe,{icon:"🌐",title:"Gateway ops — run nuvira gateway from the GUI"}),i.jsx(j$,{presets:kbe,customPlaceholder:"e.g. admin cron run nightly or gateway alias add ops email:team@example.com",timeoutMs:0,hint:i.jsxs(i.Fragment,{children:["Each command runs as the real CLI in an isolated process (the P1 task runner) — the same engine as your terminal — and runs ",i.jsx("strong",{children:"until it finishes or you press Cancel"})," (no 5-minute cutoff). The elapsed time is shown beside the status, and work continues after you switch tabs (the process lives on the dashboard server, not the page). The delivery ledger also has its own view in"," ",i.jsx("strong",{children:"Agent Hub → Channels"}),"."]})})]})}const vv={telegram:{icon:"✈️",category:"Chat",steps:["Open Telegram and search for @BotFather","Send /newbot and follow the prompts",'Give your bot a name (e.g. "My Agent Bot")','Give your bot a username ending in "bot"',"BotFather gives you a token — paste it in Step 2","Open your bot in Telegram and send /start"],testTarget:"telegram:"},discord:{icon:"🎮",category:"Chat",steps:["Go to discord.com/developers/applications",'Click "New Application" and give it a name','Go to Bot tab and click "Add Bot"',"Copy the bot token",'Enable "Message Content Intent"',"Invite bot to your server (OAuth2 URL generator)"],testTarget:"discord:"},slack:{icon:"💬",category:"Chat",steps:["Go to api.slack.com/apps","Create New App from scratch","Add Bot Token Scopes: chat:write, im:read, im:write","Install to workspace","Copy the Bot User OAuth Token (xoxb-...)"],testTarget:"slack:"},whatsapp:{icon:"📱",category:"Chat",steps:["Run: nuvira whatsapp pair (or from Gateway tab)","Scan the QR code with WhatsApp","Pairing completes automatically"],testTarget:""},whatsapp_cloud:{icon:"☁️",category:"Chat",steps:["Go to developers.facebook.com","Set up WhatsApp Cloud API","Copy token + Phone ID"],testTarget:"whatsapp_cloud:"},email:{icon:"📧",category:"Chat",steps:["Get SMTP credentials (Gmail, SendGrid, etc.)","For Gmail: use App Password at smtp.gmail.com:587","Paste SMTP host + user below"],testTarget:""},signal:{icon:"🔒",category:"Chat",steps:["Run signal-cli-rest-api Docker container","Register a Signal account","Paste account number below"],testTarget:""},dingtalk:{icon:"🔔",category:"Webhooks",steps:["Open DingTalk and create a group","Add custom robot and copy webhook URL","Paste URL below"],testTarget:""},feishu:{icon:"🐦",category:"Webhooks",steps:["Open Feishu and create a bot","Copy webhook URL and paste below"],testTarget:""},wecom:{icon:"🏢",category:"Webhooks",steps:["Open WeCom and create a group bot","Copy webhook URL and paste below"],testTarget:""},mattermost:{icon:"📋",category:"Webhooks",steps:["Open Mattermost, go to Integrations","Create incoming webhook and copy URL"],testTarget:""},matrix:{icon:"🔗",category:"Chat",steps:["Get your Matrix homeserver URL","Create a bot user and get access token","Paste URL + token below"],testTarget:""},webhook:{icon:"🪝",category:"Webhooks",steps:["Enter your webhook URL","The agent sends outbound webhooks to this URL"],testTarget:""},bluebubbles:{icon:"💙",category:"Chat",steps:["Set up BlueBubbles server","Copy server URL + password"],testTarget:""},ntfy:{icon:"📢",category:"Notifications",steps:["Choose an ntfy topic (or use ntfy.sh)","Paste the topic below"],testTarget:""},teams:{icon:"👥",category:"Webhooks",steps:["Open Microsoft Teams, go to channel","Connectors, Incoming Webhook, create","Copy webhook URL"],testTarget:""},google_chat:{icon:"💬",category:"Webhooks",steps:["Open Google Chat, space settings","Create webhook and copy URL"],testTarget:""},weixin:{icon:"🔴",category:"Chat",steps:["Get Weixin iLink bot token","Paste token below"],testTarget:""},sms:{icon:"📲",category:"Chat",steps:["Get Twilio account SID + auth token","Register a phone number","Paste credentials below"],testTarget:""},irc:{icon:"💻",category:"Chat",steps:["Choose an IRC server (e.g. irc.libera.chat)","Set nickname + channel and paste below"],testTarget:""},simplex:{icon:"📨",category:"Chat",steps:["Run local simplex-chat daemon","Paste WebSocket URL (ws://127.0.0.1:5225)"],testTarget:""},homeassistant:{icon:"🏠",category:"IoT",steps:["Open Home Assistant Profile","Create long-lived access token and paste below"],testTarget:""}};function jbe(){const[e,t]=b.useState(null),[n,r]=b.useState("all"),[a,s]=b.useState(null),[o,l]=b.useState(0),[c,u]=b.useState({}),[d,f]=b.useState(!1),[h,p]=b.useState(null),[m,g]=b.useState({status:"idle"}),[y,v]=b.useState(""),[k,w]=b.useState("Hello from agent-nuvira!"),[j,S]=b.useState(!1),[x,N]=b.useState(null),E=b.useRef(!0),P=b.useCallback(async()=>{const M=await K.getPlatformConfigs();E.current&&t(M)},[]);b.useEffect(()=>(P(),()=>{E.current=!1}),[P]);const _=M=>{s(M),l(0),u(Object.fromEntries(M.envVars.map(O=>[O.varName,O.value]))),p(null),g({status:"idle"});const z=vv[M.platform];v((z==null?void 0:z.testTarget)??""),w("Hello from agent-nuvira!"),N(null)},R=async()=>{if(!a)return;g({status:"checking"});const M=await K.verifyPlatformConfig(a.platform,c);M.ok?(g({status:"ok",info:M.info}),p({kind:"ok",text:"Verified! "+(M.info?"Connected as "+M.info+".":"Token is valid.")})):(g({status:"err",error:M.error}),p({kind:"err",text:M.error||"Verification failed."}))},T=async()=>{if(!a)return;f(!0),p(null);const M=await K.setPlatformConfig(a.platform,c);f(!1),M.ok?(p({kind:"ok",text:"Token saved! Verifying..."}),P(),l(2),R()):p({kind:"err",text:M.error||"Save failed."})},B=async()=>{if(!a||!y)return;S(!0),N(null);const M=await K.sendChannelMessage(y,k);S(!1),M.ok?N({kind:"ok",text:"Message sent via "+M.platform+"! Check your "+a.label+" app."}):N({kind:"err",text:M.error||"Send failed. Make sure the gateway is running (Gateway tab)."})};if(e===null)return i.jsx("div",{className:"empty-state",children:"Loading platforms..."});const $=e.filter(M=>M.configured).length,I=e.filter(M=>n==="configured"?M.configured:n==="unconfigured"?!M.configured:!0),D=a?vv[a.platform]:null;function U(M){return o===M?"wizard-step-dot active":"wizard-step-dot"}return i.jsxs("div",{className:"panel",children:[i.jsx(Oe,{icon:"🌐",title:"Platforms — Messaging Gateway Onboarding"}),i.jsxs("div",{className:"platforms-summary",children:[i.jsxs("div",{className:"platforms-summary-stat",children:[i.jsx("span",{className:"platforms-summary-number",children:$}),i.jsx("span",{className:"platforms-summary-label",children:"configured"})]}),i.jsxs("div",{className:"platforms-summary-stat",children:[i.jsx("span",{className:"platforms-summary-number",children:e.length-$}),i.jsx("span",{className:"platforms-summary-label",children:"available"})]}),i.jsx("div",{className:"platforms-summary-filters",children:["all","configured","unconfigured"].map(M=>i.jsx("button",{type:"button",className:n===M?"platforms-filter-btn active":"platforms-filter-btn",onClick:()=>r(M),children:M==="all"?"All":M==="configured"?"Configured":"Not set up"},M))})]}),i.jsx("div",{className:"platforms-grid",children:I.map(M=>{const z=vv[M.platform];return i.jsxs("div",{className:M.configured?"platform-card configured":"platform-card",children:[i.jsxs("div",{className:"platform-card-head",children:[i.jsx("span",{className:"platform-card-icon",children:(z==null?void 0:z.icon)??"🔌"}),i.jsxs("div",{className:"platform-card-info",children:[i.jsx("span",{className:"platform-card-name",children:M.label}),i.jsx("span",{className:"platform-card-category",children:(z==null?void 0:z.category)??"Platform"})]}),i.jsx("span",{className:M.configured?"status-dot connected":"status-dot reconnecting"})]}),i.jsx("div",{className:"platform-card-vars",children:M.envVars.map(O=>i.jsxs("span",{className:O.set?"platform-var-chip set":"platform-var-chip",children:[O.varName," ",O.set?"done":"--"]},O.varName))}),i.jsxs("div",{className:"platform-card-actions",children:[M.configured?i.jsx("span",{className:"platform-card-badge",children:"Active"}):i.jsx("button",{type:"button",className:"wizard-start-btn",onClick:()=>_(M),children:"Setup"}),M.setupUrl?i.jsx("a",{href:M.setupUrl,target:"_blank",rel:"noopener noreferrer",className:"admin-mini-btn platform-docs-link",children:"Docs"}):null]}),!M.configured&&M.setupHint?i.jsx("div",{className:"platform-card-hint",children:M.setupHint}):null]},M.platform)})}),i.jsxs("div",{className:"platforms-cli-hint",children:[i.jsx("span",{className:"admin-hint",children:"Prefer the terminal? "}),i.jsx("code",{children:"nuvira gateway setup telegram"}),i.jsx("span",{className:"admin-hint",children:" — same wizard from your CLI"})]}),a&&D?i.jsx("div",{className:"wizard-overlay",onClick:()=>s(null),children:i.jsxs("div",{className:"wizard-modal",onClick:M=>M.stopPropagation(),children:[i.jsxs("div",{className:"wizard-header",children:[i.jsx("span",{className:"wizard-icon",children:D.icon}),i.jsxs("span",{className:"wizard-title",children:["Getting Started: ",a.label]}),i.jsxs("div",{className:"wizard-steps-indicator",children:[i.jsx("span",{className:U(0),children:"1"}),i.jsx("span",{className:U(1),children:"2"}),i.jsx("span",{className:U(2),children:"3"})]}),i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>s(null),children:"X"})]}),i.jsxs("div",{className:"wizard-body",children:[o===0&&i.jsxs(i.Fragment,{children:[i.jsxs("p",{className:"wizard-section-title",children:["Step 1: Create your bot on ",a.label]}),i.jsx("ol",{className:"wizard-steps",children:D.steps.map((M,z)=>i.jsx("li",{children:M},z))}),i.jsxs("div",{className:"wizard-nav",children:[i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>l(1),children:"I have my token — Step 2"}),a.setupUrl?i.jsx("a",{href:a.setupUrl,target:"_blank",rel:"noopener noreferrer",className:"admin-mini-btn platform-docs-link",children:"Open docs"}):null]})]}),o===1&&i.jsxs(i.Fragment,{children:[i.jsx("p",{className:"wizard-section-title",children:"Step 2: Paste your token"}),a.envVars.map(M=>i.jsxs("label",{className:"hub-send-target",children:[i.jsx("span",{className:"admin-hint",children:M.prompt}),i.jsx("input",{type:M.secret?"password":"text",value:c[M.varName]??"",onChange:z=>u(O=>({...O,[M.varName]:z.target.value})),placeholder:M.secret?"paste your token here":"value",autoComplete:"off",spellCheck:!1,autoFocus:!0})]},M.varName)),h?i.jsx("div",{className:h.kind==="ok"?"admin-row-msg":"admin-row-msg admin-row-msg-err",children:h.text}):null,i.jsxs("div",{className:"wizard-nav",children:[i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>l(0),children:"Back"}),i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>void T(),disabled:d,children:d?"Saving...":"Save & Verify"})]})]}),o===2&&i.jsxs(i.Fragment,{children:[i.jsx("p",{className:"wizard-section-title",children:"Step 3: Verify and test"}),m.status==="checking"&&i.jsx("div",{className:"wizard-verify-status",children:"Verifying token..."}),m.status==="ok"&&i.jsxs("div",{className:"wizard-verify-status ok",children:["Connected as ",m.info]}),m.status==="err"&&i.jsx("div",{className:"wizard-verify-status err",children:m.error}),m.status==="idle"&&(h==null?void 0:h.kind)==="ok"&&i.jsx("div",{className:"wizard-verify-status ok",children:h.text}),y&&i.jsxs("div",{className:"wizard-test-section",children:[i.jsx("p",{className:"wizard-section-title",children:"Send a test message:"}),i.jsx("div",{className:"wizard-test-row",children:i.jsx("input",{className:"wizard-test-input",value:y,onChange:M=>v(M.target.value),placeholder:"telegram:YOUR_CHAT_ID"})}),i.jsxs("div",{className:"wizard-test-row",children:[i.jsx("input",{className:"wizard-test-input",value:k,onChange:M=>w(M.target.value),placeholder:"Hello from agent-nuvira!"}),i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>void B(),disabled:j||!y,children:j?"Sending...":"Send test"})]}),x?i.jsx("div",{className:x.kind==="ok"?"admin-row-msg":"admin-row-msg admin-row-msg-err",children:x.text}):null]}),i.jsxs("div",{className:"wizard-nav",children:[i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>l(1),children:"Edit token"}),i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>s(null),children:"Done"})]}),!y&&i.jsxs("p",{className:"wizard-hint",children:["Token saved! Start the gateway from the Gateway tab, then send a message from your ",a.label," app."]})]})]})]})}):null]})}const Nbe=[{value:"us-east-1",label:"us-east-1 (N. Virginia) — most models"},{value:"us-west-2",label:"us-west-2 (Oregon) — most models"},{value:"eu-west-1",label:"eu-west-1 (Ireland) — EU coverage"},{value:"ap-southeast-1",label:"ap-southeast-1 (Singapore)"},{value:"ap-northeast-1",label:"ap-northeast-1 (Tokyo)"}],tC=[{name:"Anthropic Claude",models:["claude-haiku-4.5","claude-sonnet-4.6","claude-fable-5","claude-opus-4.6"],checked:!0},{name:"Meta Llama",models:["llama3-1-8b","llama3-1-70b","llama3-3-70b","llama4-scout","llama4-maverick"],checked:!0},{name:"Mistral AI",models:["mistral-large-3","devstral-2","ministral-3"],checked:!1},{name:"DeepSeek",models:["deepseek-v3.2","deepseek-r1"],checked:!1},{name:"Amazon Nova",models:["nova-pro","nova-lite"],checked:!1},{name:"OpenAI on Bedrock",models:["gpt-5.6-terra","gpt-oss-120b"],checked:!1},{name:"Qwen",models:["qwen3-coder-next","qwen3-32b"],checked:!1},{name:"Google Gemma",models:["gemma-3-12b"],checked:!1},{name:"xAI",models:["grok-4.6"],checked:!1}];function Ebe({canWrite:e,sessionExpired:t}){const[n,r]=b.useState(null),[a,s]=b.useState(null),[o,l]=b.useState(!1),[c,u]=b.useState("overview"),d=b.useRef(!0),[f,h]=b.useState("bearer"),[p,m]=b.useState(""),[g,y]=b.useState(""),[v,k]=b.useState(""),[w,j]=b.useState("us-east-1"),[S,x]=b.useState(tC.filter($=>$.checked).map($=>$.name)),[N,E]=b.useState(!1),[P,_]=b.useState(null),R=b.useCallback(async()=>{const $=await K.getBedrockStatus();d.current&&r($)},[]);b.useEffect(()=>(R(),()=>{d.current=!1}),[R]);const T=async()=>{l(!0),s(null);try{const $=await K.probeBedrock((n==null?void 0:n.region)||"us-east-1");if(!d.current)return;$.ok&&$.models&&(s($.models),u("test"))}catch{}finally{d.current&&l(!1)}},B=async()=>{E(!0),_(null);try{const $={BEDROCK_REGION:w};f==="bearer"&&p?$.AWS_BEARER_TOKEN=p:f==="iam"&&(g&&($.AWS_ACCESS_KEY_ID=g),v&&($.AWS_SECRET_ACCESS_KEY=v));const I=await K.setupBedrock($);if(!d.current)return;I.ok?(_({kind:"ok",text:"✅ Configuration saved! Running connectivity test…"}),u("overview"),await R(),setTimeout(()=>void T(),500)):_({kind:"err",text:I.error||"Save failed"})}catch{d.current&&_({kind:"err",text:"Could not reach the dashboard server."})}finally{d.current&&E(!1)}};return n===null?i.jsx("div",{className:"empty-state",children:"Loading Bedrock status…"}):i.jsxs("div",{className:"bedrock-onboarding",children:[i.jsx(Oe,{icon:"🟠",title:"AWS Bedrock"}),i.jsxs("p",{className:"admin-subtitle",children:["Bedrock gives you access to Claude, Llama, Mistral, DeepSeek, and more — all through a single AWS account. Unlike other providers, Bedrock requires a ",i.jsx("strong",{children:"region"}),", ",i.jsx("strong",{children:"AWS credentials"}),", and explicit ",i.jsx("strong",{children:"model access approval"}),"."]}),P?i.jsx("div",{className:`admin-row-msg${P.kind==="ok"?"":" admin-row-msg-err"}`,children:P.text}):null,i.jsxs("div",{className:"bedrock-status-bar",children:[i.jsxs("div",{className:"bedrock-status-item",children:[i.jsx("span",{className:`status-dot ${n.configured?"connected":"reconnecting"}`}),i.jsx("span",{children:n.configured?"Configured":"Not configured"})]}),i.jsxs("div",{className:"bedrock-status-item",children:[i.jsx("span",{className:"bedrock-status-label",children:"Region:"}),i.jsx("code",{children:n.region})]}),i.jsxs("div",{className:"bedrock-status-item",children:[i.jsx("span",{className:"bedrock-status-label",children:"Auth:"}),i.jsx("code",{children:n.authMethod==="bearer"?"API Key":n.authMethod==="iam"?"IAM":"None"})]}),i.jsxs("div",{className:"bedrock-status-actions",children:[e?i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>u(c==="setup"?"overview":"setup"),children:c==="setup"?"✕ Cancel":"⚙ Setup Wizard"}):null,n.configured?i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>void T(),disabled:o,children:o?"⏳ Probing…":"🔍 Test Models"}):null]})]}),c==="setup"&&i.jsxs("div",{className:"bedrock-setup-wizard",children:[i.jsx("h2",{className:"section-subtitle",children:"🚀 Bedrock Setup Wizard"}),i.jsxs("div",{className:"bedrock-wizard-step",children:[i.jsx("h4",{children:"Step 1: Authentication"}),i.jsxs("div",{className:"bedrock-auth-options",children:[i.jsxs("label",{className:`bedrock-auth-option ${f==="bearer"?"selected":""}`,children:[i.jsx("input",{type:"radio",name:"authMethod",checked:f==="bearer",onChange:()=>h("bearer")}),i.jsxs("div",{children:[i.jsx("strong",{children:"Bedrock API Key"}),i.jsx("span",{children:"Simpler — get from Bedrock → Settings → API keys"})]})]}),i.jsxs("label",{className:`bedrock-auth-option ${f==="iam"?"selected":""}`,children:[i.jsx("input",{type:"radio",name:"authMethod",checked:f==="iam",onChange:()=>h("iam")}),i.jsxs("div",{children:[i.jsx("strong",{children:"IAM Credentials"}),i.jsx("span",{children:"Full AWS SDK auth — AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY"})]})]})]}),f==="bearer"?i.jsxs("div",{className:"bedrock-wizard-fields",children:[i.jsxs("div",{className:"bedrock-setup-hint",children:[i.jsx("strong",{children:"How to get a Bedrock API key:"}),i.jsxs("ol",{children:[i.jsxs("li",{children:["Open ",i.jsx("a",{href:"https://console.aws.amazon.com/bedrock/",target:"_blank",rel:"noopener noreferrer",children:"AWS Bedrock Console"})]}),i.jsxs("li",{children:["Go to ",i.jsx("strong",{children:"Settings"})," → ",i.jsx("strong",{children:"API keys"})]}),i.jsx("li",{children:"Create a new key and paste it below"})]})]}),i.jsxs("label",{className:"hub-send-target",children:[i.jsx("span",{className:"admin-hint",children:"Bedrock API Key (Bearer token)"}),i.jsx("input",{type:"password",value:p,onChange:$=>m($.target.value),placeholder:"••••••••••••",autoComplete:"off",spellCheck:!1})]})]}):i.jsxs("div",{className:"bedrock-wizard-fields",children:[i.jsxs("div",{className:"bedrock-setup-hint",children:[i.jsx("strong",{children:"IAM credentials"})," give full AWS SDK access. Create an IAM user with Bedrock permissions."]}),i.jsxs("label",{className:"hub-send-target",children:[i.jsx("span",{className:"admin-hint",children:"AWS_ACCESS_KEY_ID"}),i.jsx("input",{type:"text",value:g,onChange:$=>y($.target.value),placeholder:"AKIA...",autoComplete:"off",spellCheck:!1})]}),i.jsxs("label",{className:"hub-send-target",children:[i.jsx("span",{className:"admin-hint",children:"AWS_SECRET_ACCESS_KEY"}),i.jsx("input",{type:"password",value:v,onChange:$=>k($.target.value),placeholder:"••••••••••••",autoComplete:"off",spellCheck:!1})]})]})]}),i.jsxs("div",{className:"bedrock-wizard-step",children:[i.jsx("h4",{children:"Step 2: AWS Region"}),i.jsxs("p",{className:"admin-hint",children:["Models vary by region. ",i.jsx("strong",{children:"us-east-1"})," and ",i.jsx("strong",{children:"us-west-2"})," have the most models. ⚠️ Do NOT use eu-north-1 unless models are explicitly enabled there."]}),i.jsx("select",{className:"bedrock-region-select",value:w,onChange:$=>j($.target.value),children:Nbe.map($=>i.jsx("option",{value:$.value,children:$.label},$.value))})]}),i.jsxs("div",{className:"bedrock-wizard-step",children:[i.jsx("h4",{children:"Step 3: Model Access"}),i.jsx("p",{className:"admin-hint",children:"Bedrock requires you to request access for each model family."}),i.jsx("div",{className:"bedrock-model-access-hint",children:i.jsx("a",{href:`https://console.aws.amazon.com/bedrock/home?region=${w}#/modelaccess`,target:"_blank",rel:"noopener noreferrer",className:"admin-mini-btn",children:"📖 Open Model Access in AWS Console"})}),i.jsx("div",{className:"bedrock-family-grid",children:tC.map($=>i.jsxs("label",{className:`bedrock-family-card ${S.includes($.name)?"selected":""}`,children:[i.jsx("input",{type:"checkbox",checked:S.includes($.name),onChange:I=>{I.target.checked?x(D=>[...D,$.name]):x(D=>D.filter(U=>U!==$.name))}}),i.jsxs("div",{children:[i.jsx("strong",{children:$.name}),i.jsxs("span",{children:[$.models.length," model(s)"]})]})]},$.name))}),i.jsx("p",{className:"admin-hint",style:{marginTop:8},children:"In the AWS Console, select the families above and submit. Approval is usually instant for Anthropic and Meta models."})]}),i.jsxs("div",{className:"bedrock-wizard-actions",children:[i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>void B(),disabled:N||f==="bearer"&&!p||f==="iam"&&(!g||!v),children:N?"⏳ Saving…":"💾 Save & Test"}),i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>u("overview"),children:"Cancel"})]})]}),c==="test"&&a&&i.jsxs("div",{className:"bedrock-probe-results",children:[i.jsxs("h2",{className:"section-subtitle",children:["🔍 Model Probe Results (",n.region,")"]}),i.jsx("div",{className:"bedrock-probe-grid",children:a.map($=>i.jsxs("div",{className:`bedrock-probe-card bedrock-probe-${$.status}`,children:[i.jsx("span",{className:"bedrock-probe-icon",children:$.status==="accessible"?"✅":$.status==="permission-denied"?"🔒":$.status==="not-found"?"⚫":"❌"}),i.jsx("span",{className:"bedrock-probe-id",children:$.modelId}),i.jsx("span",{className:"bedrock-probe-status",children:$.status==="accessible"?"Ready":$.status==="permission-denied"?`Need access (HTTP ${$.httpStatus})`:$.status==="not-found"?"Not in this region":"Error"})]},$.modelId))}),a.some($=>$.status==="permission-denied")&&i.jsxs("div",{className:"bedrock-probe-action",children:[i.jsxs("p",{children:["Some models exist in ",n.region," but access is not approved."]}),i.jsx("a",{href:`https://console.aws.amazon.com/bedrock/home?region=${n.region}#/modelaccess`,target:"_blank",rel:"noopener noreferrer",className:"admin-mini-btn",children:"🔓 Request Model Access in AWS Console →"})]}),i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>u("overview"),style:{marginTop:12},children:"← Back"})]}),!n.configured&&c==="overview"&&i.jsxs("div",{className:"bedrock-getting-started",children:[i.jsx("h2",{className:"section-subtitle",children:"📋 Getting Started with Bedrock"}),i.jsxs("div",{className:"bedrock-steps",children:[i.jsxs("div",{className:"bedrock-step",children:[i.jsx("span",{className:"bedrock-step-num",children:"1"}),i.jsxs("div",{children:[i.jsx("strong",{children:"Create an AWS account"})," (or use existing)",i.jsxs("span",{children:["New to AWS? Sign up at ",i.jsx("a",{href:"https://aws.amazon.com/",target:"_blank",rel:"noopener noreferrer",children:"aws.amazon.com"})]})]})]}),i.jsxs("div",{className:"bedrock-step",children:[i.jsx("span",{className:"bedrock-step-num",children:"2"}),i.jsxs("div",{children:[i.jsx("strong",{children:"Get Bedrock API key"}),i.jsx("span",{children:"Bedrock → Settings → API keys → Create key"})]})]}),i.jsxs("div",{className:"bedrock-step",children:[i.jsx("span",{className:"bedrock-step-num",children:"3"}),i.jsxs("div",{children:[i.jsx("strong",{children:"Request model access"}),i.jsx("span",{children:"Bedrock → Model access → Select Claude, Llama, etc. → Submit"})]})]}),i.jsxs("div",{className:"bedrock-step",children:[i.jsx("span",{className:"bedrock-step-num",children:"4"}),i.jsxs("div",{children:[i.jsx("strong",{children:"Configure in this wizard"}),i.jsx("span",{children:'Click "Setup Wizard" above to enter your credentials'})]})]})]})]}),n.configured&&c==="overview"&&!a&&i.jsx("div",{className:"bedrock-quick-status",children:i.jsxs("p",{className:"admin-hint",children:["Bedrock is configured. Click ",i.jsx("strong",{children:"🔍 Test Models"})," to verify connectivity and discover which models are accessible in ",n.region,"."]})})]})}const yv=["whatsapp","whatsapp_cloud","telegram","signal","slack","discord","email"];function _be(){const[e,t]=b.useState([]),[n,r]=b.useState(!0),[a,s]=b.useState("all"),[o,l]=b.useState(null),[c,u]=b.useState(""),[d,f]=b.useState(""),[h,p]=b.useState(null),[m,g]=b.useState({}),[y,v]=b.useState({}),[k,w]=b.useState({}),[j,S]=b.useState(null),[x,N]=b.useState(!1),[E,P]=b.useState(!1),[_,R]=b.useState(!1),[T,B]=b.useState(12e4),$=b.useCallback(async()=>{r(!0);const ee=await K.getContacts();ee.ok&&ee.contacts&&t(ee.contacts);const Q=await K.gatewayPolicies();if(Q.ok&&Q.policies){const ae={};for(const ce of yv){const G=Q.policies[ce];G&&(ae[ce]={...G.outboundSenders!==void 0?{outboundSenders:G.outboundSenders}:{},...G.requireApprovedTarget!==void 0?{requireApprovedTarget:G.requireApprovedTarget}:{}})}g(ae),v(ae)}P(Q.askUserWait===!0),R(Q.askUserWait===!0),typeof Q.askUserTimeoutMs=="number"&&B(Q.askUserTimeoutMs),r(!1)},[]);b.useEffect(()=>{$()},[$]);const I=e.filter(ee=>a==="all"||ee.status===a),D=async ee=>{p(null);const Q=await K.approveContact(ee.platform,ee.name);p(Q.ok?{kind:"ok",text:`✅ ${ee.name} approved.`}:{kind:"err",text:Q.error||"Failed."}),$()},U=async ee=>{p(null);const Q=await K.rejectContact(ee.platform,ee.name);p(Q.ok?{kind:"ok",text:`🚫 ${ee.name} rejected.`}:{kind:"err",text:Q.error||"Failed."}),$()},M=async ee=>{p(null);const Q=await K.deleteContact(ee.platform,ee.name);p(Q.ok?{kind:"ok",text:`🗑️ ${ee.name} deleted.`}:{kind:"err",text:Q.error||"Failed."}),$()},z=async()=>{if(!o)return;p(null);const ee=await K.updateContact(o.platform,o.id,{name:c,phone:d});p(ee.ok?{kind:"ok",text:`✅ ${c} updated.`}:{kind:"err",text:ee.error||"Failed."}),l(null),$()},O=ee=>ee==="approved"?i.jsx("span",{className:"contact-status-badge approved",children:"✅ Approved"}):ee==="pending"?i.jsx("span",{className:"contact-status-badge pending",children:"⏳ Pending"}):i.jsx("span",{className:"contact-status-badge rejected",children:"🚫 Rejected"}),J=ee=>({telegram:"✈️",whatsapp:"📱",whatsapp_cloud:"📱",email:"📧",slack:"💬",discord:"🎮"})[ee]||"🔌",F=ee=>ee?new Date(ee).toLocaleString():"—",L=ee=>{const Q=(k[ee]??"").trim();Q&&(g(ae=>{var xe;const ce={...ae[ee]??{}},G=ce.outboundSenders??((xe=y[ee])==null?void 0:xe.outboundSenders)??[];return G.some(we=>we.toLowerCase()===Q.toLowerCase())||(ce.outboundSenders=[...G,Q]),{...ae,[ee]:ce}}),w(ae=>({...ae,[ee]:""})))},ie=(ee,Q)=>{g(ae=>{var xe;const ce={...ae[ee]??{}},G=ce.outboundSenders??((xe=y[ee])==null?void 0:xe.outboundSenders)??[];return ce.outboundSenders=G.filter(we=>we.toLowerCase()!==Q.toLowerCase()),{...ae,[ee]:ce}})},fe=ee=>{g(Q=>{const ae={...Q[ee]??{}};return ae.requireApprovedTarget=ae.requireApprovedTarget!==!0,{...Q,[ee]:ae}})},ve=ee=>{g(Q=>{const ae={...Q[ee]??{}};return delete ae.outboundSenders,{...Q,[ee]:ae}})},Ee=async()=>{N(!0),S(null);const ee={};for(const ce of yv){const G=m[ce]??{},xe=y[ce]??{};(JSON.stringify(G.outboundSenders??null)!==JSON.stringify(xe.outboundSenders??null)||!!G.requireApprovedTarget!=!!xe.requireApprovedTarget)&&(ee[ce]={...G.outboundSenders!==void 0?{outboundSenders:G.outboundSenders}:{outboundSenders:null},requireApprovedTarget:!!G.requireApprovedTarget})}const Q=E!==_;if(Object.keys(ee).length===0&&!Q){N(!1),S({kind:"ok",text:"No changes to save."});return}const ae=await K.saveGatewayPolicies(ee,void 0,void 0,{wait:E,timeoutMs:T});ae.ok?(S({kind:"ok",text:"✅ Send authority saved."}),$()):S({kind:"err",text:ae.error||"Failed to save send authority."}),N(!1)};return i.jsxs("div",{className:"panel contacts-page",children:[i.jsx(Oe,{icon:"📇",title:"Contacts — Outbound Messaging Directory",description:"Manage who the bot can send messages to. Users auto-register on first Telegram message."}),h&&i.jsxs("div",{className:`admin-row-msg ${h.kind==="err"?"admin-row-msg-err":""}`,children:[h.text,i.jsx("button",{className:"admin-mini-btn",onClick:()=>p(null),children:"✕"})]}),i.jsxs("div",{className:"contacts-filters",children:[["all","approved","pending","rejected"].map(ee=>i.jsx("button",{type:"button",className:a===ee?"platforms-filter-btn active":"platforms-filter-btn",onClick:()=>s(ee),children:ee==="all"?`All (${e.length})`:ee==="approved"?`✅ Approved (${e.filter(Q=>Q.status==="approved").length})`:ee==="pending"?`⏳ Pending (${e.filter(Q=>Q.status==="pending").length})`:`🚫 Rejected (${e.filter(Q=>Q.status==="rejected").length})`},ee)),i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>void $(),children:"🔄 Refresh"})]}),n?i.jsx("div",{className:"empty-state",children:"Loading contacts..."}):I.length===0?i.jsxs("div",{className:"empty-state",children:[i.jsxs("p",{children:["No contacts",a!=="all"?` with status "${a}"`:"","."]}),i.jsx("p",{className:"admin-hint",children:'Contacts auto-register when users message the bot on Telegram. They appear here as "Pending" until you approve them.'})]}):i.jsx("div",{className:"contacts-table-wrapper",children:i.jsxs("table",{className:"contacts-table",children:[i.jsx("thead",{children:i.jsxs("tr",{children:[i.jsx("th",{children:"Platform"}),i.jsx("th",{children:"Name"}),i.jsx("th",{children:"ID"}),i.jsx("th",{children:"Phone"}),i.jsx("th",{children:"Status"}),i.jsx("th",{children:"Registered"}),i.jsx("th",{children:"Actions"})]})}),i.jsx("tbody",{children:I.map(ee=>i.jsxs("tr",{className:`contact-row status-${ee.status}`,children:[i.jsxs("td",{children:[J(ee.platform)," ",ee.platform]}),i.jsx("td",{className:"contact-name",children:ee.name}),i.jsx("td",{className:"contact-id",children:i.jsx("code",{children:ee.id})}),i.jsx("td",{className:"contact-phone",children:ee.phone||"—"}),i.jsx("td",{children:O(ee.status)}),i.jsx("td",{className:"contact-date",children:F(ee.registeredAt||ee.addedAt)}),i.jsxs("td",{className:"contact-actions",children:[ee.status!=="approved"&&i.jsx("button",{className:"admin-mini-btn contact-approve-btn",onClick:()=>void D(ee),children:"✅ Approve"}),ee.status!=="rejected"&&i.jsx("button",{className:"admin-mini-btn contact-reject-btn",onClick:()=>void U(ee),children:"🚫 Reject"}),i.jsx("button",{className:"admin-mini-btn",onClick:()=>{l(ee),u(ee.name),f(ee.phone||"")},children:"✏️ Edit"}),i.jsx("button",{className:"admin-mini-btn contact-delete-btn",onClick:()=>void M(ee),children:"🗑️"})]})]},`${ee.platform}:${ee.id}`))})]})}),i.jsxs("div",{className:"panel-header",style:{marginTop:28},children:[i.jsx("h2",{children:"🔐 Send authority — who may message others"}),i.jsxs("p",{className:"admin-hint",children:["Controls who can ask the agent to send a message to ",i.jsx("strong",{children:"someone else"})," through the gateway (e.g. “send this poem to my brother on WhatsApp”). This is separate from a contact’s approval status above, which only gates sending ",i.jsx("em",{children:"to"})," that person. Left empty, a platform ",i.jsx("strong",{children:"inherits"})," its allowed-users list (open). Add ",i.jsx("code",{children:"Allow-All"})," to allow everyone, or list specific senders to restrict it."]})]}),j&&i.jsxs("div",{className:`admin-row-msg ${j.kind==="err"?"admin-row-msg-err":""}`,children:[j.text,i.jsx("button",{className:"admin-mini-btn",onClick:()=>S(null),children:"✕"})]}),i.jsx("div",{className:"hub-permissions",children:yv.map(ee=>{const Q=m[ee]??{},ae=Q.outboundSenders??[],ce=Q.outboundSenders===void 0;return i.jsxs("div",{className:"hub-card",children:[i.jsxs("div",{className:"hub-card-top",children:[i.jsxs("span",{className:"hub-chip",children:[J(ee)," ",ee]}),ce?i.jsx("span",{className:"hub-chip",children:"open"}):i.jsx("span",{className:"hub-chip",children:"restricted"})]}),i.jsx("div",{className:"hub-alias-list",children:ce?i.jsx("span",{className:"admin-hint",children:"Open — anyone who can trigger the agent may send to others."}):ae.length===0?i.jsx("span",{className:"admin-hint",children:"(empty — nobody may send to others)"}):ae.map(G=>i.jsxs("div",{className:"hub-alias-row",children:[i.jsx("span",{className:"hub-chip",children:G}),i.jsx("button",{className:"admin-refresh-btn",disabled:x,onClick:()=>ie(ee,G),children:"✕"})]},`sa-${ee}-${G}`))}),i.jsxs("div",{className:"hub-send-form",children:[i.jsx("input",{type:"text","aria-label":`Allowed sender for ${ee}`,value:k[ee]??"",onChange:G=>w(xe=>({...xe,[ee]:G.target.value})),placeholder:"sender id, or Allow-All",disabled:x}),i.jsx("button",{className:"admin-refresh-btn",disabled:x||!(k[ee]??"").trim(),onClick:()=>L(ee),children:"+ Sender"}),ce?null:i.jsx("button",{className:"admin-refresh-btn",disabled:x,onClick:()=>ve(ee),children:"↺ Reset to open"})]}),i.jsxs("label",{style:{display:"inline-flex",alignItems:"center",gap:6,marginTop:6},children:[i.jsx("input",{type:"checkbox",checked:!!Q.requireApprovedTarget,disabled:x,onChange:()=>fe(ee)}),i.jsx("span",{className:"admin-hint",children:"Require approved recipients"})]})]},`sa-${ee}`)})}),i.jsxs("div",{className:"hub-card",style:{marginTop:16},children:[i.jsxs("div",{className:"hub-card-top",children:[i.jsx("span",{className:"hub-chip",children:"🧠 Clarifying questions"}),E?i.jsx("span",{className:"hub-chip",children:"wait for reply"}):i.jsx("span",{className:"hub-chip",children:"assume option 1"}),E!==_?i.jsx("span",{className:"hub-chip",children:"· unsaved"}):null]}),i.jsxs("label",{style:{display:"inline-flex",alignItems:"center",gap:6,marginTop:6},children:[i.jsx("input",{type:"checkbox",checked:E,disabled:x,onChange:()=>P(ee=>!ee)}),i.jsxs("span",{className:"admin-hint",children:["When the agent asks a question on a channel, ",i.jsx("strong",{children:"wait for the sender's reply"})," before acting. Off (default): the question is sent and the ",i.jsx("em",{children:"first"})," option is assumed immediately — so a reply typed afterwards arrives too late to change anything."]})]}),E?i.jsxs("label",{style:{display:"inline-flex",alignItems:"center",gap:6,marginTop:6},children:[i.jsx("span",{className:"admin-hint",children:"Reply window (seconds)"}),i.jsx("input",{type:"number",min:5,max:600,value:Math.round(T/1e3),disabled:x,onChange:ee=>B(Math.max(5,Math.min(600,Number(ee.target.value)||120))*1e3),style:{width:90}}),i.jsx("span",{className:"admin-hint",children:"then the first option is used, and the timeout is logged."})]}):null]}),i.jsx("div",{style:{marginTop:12},children:i.jsx("button",{className:"admin-refresh-btn",disabled:x,onClick:()=>void Ee(),children:"💾 Save send authority"})}),o&&i.jsx("div",{className:"wizard-overlay",onClick:()=>l(null),children:i.jsxs("div",{className:"wizard-modal",onClick:ee=>ee.stopPropagation(),children:[i.jsxs("div",{className:"wizard-header",children:[i.jsx("span",{className:"wizard-icon",children:"✏️"}),i.jsxs("span",{className:"wizard-title",children:["Edit Contact: ",o.name]}),i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>l(null),children:"✕"})]}),i.jsxs("div",{className:"wizard-body",children:[i.jsxs("label",{className:"hub-send-target",children:[i.jsx("span",{className:"admin-hint",children:"Name"}),i.jsx("input",{type:"text",value:c,onChange:ee=>u(ee.target.value)})]}),i.jsxs("label",{className:"hub-send-target",children:[i.jsx("span",{className:"admin-hint",children:"Phone (optional, for flexible lookup)"}),i.jsx("input",{type:"text",value:d,onChange:ee=>f(ee.target.value),placeholder:"+918800123456"})]}),i.jsxs("p",{className:"admin-hint",children:["Platform: ",i.jsx("strong",{children:o.platform})," | ID: ",i.jsx("code",{children:o.id})]}),i.jsxs("div",{className:"wizard-nav",children:[i.jsx("button",{type:"button",className:"admin-mini-btn",onClick:()=>l(null),children:"Cancel"}),i.jsx("button",{type:"button",className:"admin-refresh-btn",onClick:()=>void z(),children:"Save"})]})]})]})})]})}const nC=["proven-dead","proof-expired","parked","never-verified"];function Wo(e){if(e<=0)return"never";const t=Math.floor(e/1e3),n=Math.floor(t/60),r=Math.floor(n/60),a=Math.floor(r/24);return a>30?`${a}d ago`:a>0?`${a}d ${r%24}h ago`:r>0?`${r}h ${n%60}m ago`:n>0?`${n}m ago`:`${t}s ago`}function Cbe(e){if(e<=0)return"never";const t=(Date.now()-e)/(24*60*60*1e3);return t<1?`${(t*24).toFixed(1)}h`:`${t.toFixed(2)}d`}function Abe({entry:e}){const t=Date.now(),n=t-e.lastProbedAt,r=t-e.lastVerifiedAt,a=t-e.lastUsedAt,s=Math.min(100,n/(30*24*60*60*1e3)*100),o=e.lastVerifiedAt>0?Math.min(100,r/(30*24*60*60*1e3)*100):-1,l=e.lastUsedAt>0?Math.min(100,a/(30*24*60*60*1e3)*100):-1;return i.jsxs("div",{className:"timeline-bar-container",children:[i.jsx("div",{className:"timeline-bar",title:`Last probed: ${Wo(n)}`,children:i.jsx("div",{className:"timeline-bar-fill probe",style:{width:`${s}%`}})}),o>=0&&i.jsx("div",{className:"timeline-bar small",title:`Last verified: ${Wo(r)}`,children:i.jsx("div",{className:"timeline-bar-fill verify",style:{width:`${o}%`}})}),l>=0&&i.jsx("div",{className:"timeline-bar small",title:`Last used: ${Wo(a)}`,children:i.jsx("div",{className:"timeline-bar-fill use",style:{width:`${l}%`}})})]})}function rC(e){return{fontSize:11,padding:"2px 8px",borderRadius:4,background:`${e}20`,color:e,border:`1px solid ${e}40`,whiteSpace:"nowrap"}}function Tbe(){const[e,t]=b.useState(null),[n,r]=b.useState(!0),[a,s]=b.useState(null),[o,l]=b.useState("all"),[c,u]=b.useState("provider"),d=b.useRef(!0),f=h0(),h=b.useCallback(async()=>{try{const z=await fetch("/api/model-timeline");if(!z.ok)throw new Error("Failed to fetch timeline data");const O=await z.json();d.current&&(t(O),s(null))}catch(z){d.current&&s(z instanceof Error?z.message:"Failed to load timeline")}finally{d.current&&r(!1)}},[]),[p,m]=b.useState(null),[g,y]=b.useState(10),[v,k]=b.useState(!1),[w,j]=b.useState(null),S=b.useRef(!1),x=b.useCallback(async()=>{const z=await K.fetchVerifyBacklog();if(!d.current)return;m(z);const O=(z==null?void 0:z.status)==="running";S.current&&!O&&h(),S.current=O},[h]);b.useEffect(()=>{d.current=!0,h(),x();const z=setInterval(()=>void h(),3e4);return()=>{d.current=!1,clearInterval(z)}},[h,x]);const N=(p==null?void 0:p.status)==="running";b.useEffect(()=>{if(!N)return;const z=setInterval(()=>void x(),1e3);return()=>clearInterval(z)},[N,x]);const E=b.useCallback(async()=>{k(!0),j(null);const z=await K.startVerifyBacklog(g);if(d.current){if(z.state&&m(z.state),!z.ok){const O=z.refusal??z.error??"Could not start the run.";j({text:O,kind:z.refusal?"info":"error"})}k(!1)}},[g]);if(n)return i.jsxs("div",{className:"admin-header",children:[i.jsx(Oe,{icon:"📅",title:"Model Discovery Timeline"}),i.jsxs("div",{className:"loading-state",children:[i.jsx("div",{className:"loading-spinner"}),i.jsx("p",{children:"Loading timeline..."})]})]});if(a)return i.jsxs("div",{className:"admin-header",children:[i.jsx(Oe,{icon:"📅",title:"Model Discovery Timeline"}),i.jsx("div",{className:"admin-row-msg admin-row-msg-err",children:a})]});if(e&&!e.counts)return i.jsxs("div",{className:"admin-header",children:[i.jsx(Oe,{icon:"📅",title:"Model Discovery Timeline"}),i.jsxs("div",{className:"admin-row-msg admin-row-msg-err",children:["This dashboard server predates the reachability view. Restart it (",i.jsx("code",{children:"nuvira dashboard stop"}),", then start it again) and reload this page."]})]});const P=(e==null?void 0:e.entries)??[],_=e==null?void 0:e.counts,R=e==null?void 0:e.reachabilityCopy,T=e==null?void 0:e.freshnessCopy,B=_?nC.reduce((z,O)=>z+(_[O]??0),0):0,$=[{key:"tracked-models",icon:"🧠",value:tt((e==null?void 0:e.totalModels)??0),label:"Tracked models (registry)",tone:"accent"},{key:"tracked-providers",icon:"🏢",value:tt((f==null?void 0:f.trackedProviders)??0),label:"Tracked providers (registry)",tone:"accent"}];f&&$.push({key:"listed-models",icon:"📡",value:tt(f.listedModels),label:"Listed models (live probe)",tone:"warn"},{key:"listed-providers",icon:"🛰️",value:tt(f.listedProviders),label:"Listed providers (live probe)",tone:"warn"}),$.push({key:"routable",icon:"✅",value:tt((_==null?void 0:_.routable)??0),label:"Routable now",tone:"ok"},{key:"not-routable",icon:"🚫",value:tt(B),label:"Not routable",tone:"danger"});const I=P.filter(z=>o==="routable"?z.reachability==="routable":o==="not-routable"?z.reachability!=="routable":!0),D=[...I].sort((z,O)=>c==="provider"?z.provider.localeCompare(O.provider)||z.model.localeCompare(O.model):O.lastProbedAt-z.lastProbedAt),U=new Map;for(const z of D){const O=U.get(z.provider);O?O.push(z):U.set(z.provider,[z])}const M=z=>({background:z?"var(--accent-green)":"var(--bg-hover)",border:`1px solid ${z?"var(--accent-green)":"var(--border)"}`,padding:"4px 12px",fontSize:12,cursor:"pointer"});return i.jsxs(i.Fragment,{children:[i.jsx(Oe,{icon:"📅",title:"Model Discovery Timeline"}),i.jsxs("p",{className:"section-description",children:["The registry's age profile: when each tracked model was last probed, last ",i.jsx("em",{children:"verified"}),", and last used — and which ones routing can actually reach. The Models page answers “is it usable right now”; this one answers “what is ageing out”."]}),i.jsx(Wi,{tiles:$}),_?i.jsx("div",{style:{display:"flex",gap:14,flexWrap:"wrap",marginBottom:14,fontSize:11},children:nC.map(z=>{const O=R==null?void 0:R[z];return i.jsxs("span",{title:O==null?void 0:O.blurb,children:[i.jsx("span",{style:{color:(O==null?void 0:O.color)??"var(--text-secondary)"},children:"■"})," ",i.jsxs("span",{style:{color:"var(--text-secondary)"},children:[(O==null?void 0:O.label)??z,": ",i.jsx("strong",{style:{color:"var(--text-primary)"},children:_[z]??0})]})]},z)})}):null,p?i.jsxs("div",{style:{background:"var(--bg-card)",border:"1px solid var(--border)",borderRadius:8,padding:"12px 14px",marginBottom:16},"data-testid":"verify-backlog-panel",children:[i.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[i.jsx("span",{style:{fontWeight:600,color:"var(--text-primary)"},children:"Work the backlog down"}),i.jsxs("span",{style:{fontSize:11,color:"var(--text-secondary)",flex:1,minWidth:260},children:["Each check is a real 1-token generation against one of your provider keys — not a listing lookup. A never-verified model is an ",i.jsx("em",{children:"unknown"}),", not a broken one: a check either proves it routable or marks it proven dead. Runs are bounded and one at a time."]}),i.jsxs("label",{style:{fontSize:11,color:"var(--text-secondary)",display:"flex",alignItems:"center",gap:6},children:["How many",i.jsx("input",{type:"number",min:1,max:p.maxCount??25,value:g,disabled:v||N,"aria-label":"how many models to verify",onChange:z=>y(Number(z.target.value)),style:{width:64,background:"var(--bg-primary)",color:"var(--text-primary)",border:"1px solid var(--border)",borderRadius:4,padding:"3px 6px",fontSize:12}})]}),i.jsx("button",{className:"admin-refresh-btn",type:"button",disabled:v||N||!(g>0),onClick:()=>void E(),style:{background:"var(--accent-green)",border:"1px solid var(--accent-green)",padding:"4px 12px",fontSize:12,cursor:v||N?"default":"pointer"},"data-testid":"verify-backlog-start",children:N?"⏳ Verifying…":v?"Starting…":`▶ Verify next ${g} now`})]}),N?i.jsxs("div",{className:"env-var-notice","data-testid":"verify-backlog-progress",children:["Probing"," ",i.jsx("code",{children:p.current?`${p.current.provider}/${p.current.model}`:"…"})," ","— ",p.processed,"/",p.planned," done · ",p.verified," verified · ",p.unavailable," proven dead"]}):null,!N&&p.status==="done"?i.jsxs("div",{className:"env-var-notice","data-testid":"verify-backlog-summary",children:["✅ ",p.verified," verified · ⛔ ",p.unavailable," proven unavailable · ⚠️ ",p.errored," errored · ⏭"," ",p.skipped," skipped",p.remaining!==null?` — ${p.remaining} still never verified`:""]}):null,(p.results??[]).length>0?i.jsx("div",{style:{display:"flex",gap:10,flexWrap:"wrap",marginTop:8},children:(p.results??[]).map(z=>i.jsxs("span",{style:{fontSize:11,color:"var(--text-secondary)"},title:z.outcome==="verified"?"Proven routable — a 1-token call succeeded":z.outcome==="unavailable"?"Proven dead — the provider refused it (403/404), re-probing will not help":z.outcome==="skipped"?"Skipped — verified recently enough":"Errored — transient, still unknown, will be retried next run",children:[z.outcome==="verified"?"✅":z.outcome==="unavailable"?"⛔":z.outcome==="skipped"?"⏭":"⚠️"," ",i.jsxs("code",{children:[z.provider,"/",z.model]})]},`${z.provider}:${z.model}`))}):null,w?i.jsx("div",{className:`env-var-notice${w.kind==="error"?" env-var-notice-error":""}`,"data-testid":"verify-backlog-message",children:w.text}):p.status==="idle"&&p.refusal?i.jsx("div",{className:"env-var-notice","data-testid":"verify-backlog-message",children:p.refusal}):null]}):null,i.jsxs("div",{style:{display:"flex",gap:8,marginBottom:16,flexWrap:"wrap"},children:[i.jsx("div",{style:{display:"flex",gap:4},children:["all","routable","not-routable"].map(z=>i.jsx("button",{className:`admin-refresh-btn ${o===z?"active":""}`,onClick:()=>l(z),style:M(o===z),children:z==="all"?"All":z==="routable"?"Routable":"Not routable"},z))}),i.jsx("div",{style:{display:"flex",gap:4},children:["provider","lastProbed"].map(z=>i.jsxs("button",{className:`admin-refresh-btn ${c===z?"active":""}`,onClick:()=>u(z),style:M(c===z),children:["Sort: ",z==="lastProbed"?"Last seen":"Provider"]},z))}),i.jsx("button",{className:"admin-refresh-btn",onClick:()=>void h(),style:{background:"var(--bg-hover)",border:"1px solid var(--border)",padding:"4px 12px",fontSize:12,cursor:"pointer"},children:"🔄 Refresh"})]}),i.jsxs("div",{style:{display:"flex",gap:16,marginBottom:4,fontSize:11,color:"var(--text-secondary)",flexWrap:"wrap"},children:[i.jsxs("span",{children:[i.jsx("span",{style:{color:"var(--accent-blue)"},children:"■"})," Probe (last seen in the provider's catalog)"]}),i.jsxs("span",{children:[i.jsx("span",{style:{color:"var(--accent-green)"},children:"■"})," Verified (last success)"]}),i.jsxs("span",{children:[i.jsx("span",{style:{color:"var(--accent-yellow)"},children:"■"})," Used (last invocation)"]})]}),i.jsxs("div",{style:{marginBottom:12,fontSize:11,color:"var(--text-secondary)"},children:[i.jsx("strong",{style:{color:"var(--text-primary)"},children:"Fresh"})," means the provider still lists it."," ",i.jsx("strong",{style:{color:"var(--text-primary)"},children:"Routable"})," means a turn has been proven to work on it within"," ",(e==null?void 0:e.freshDays)??7," days. A fresh model that was never verified is an unknown, not a failure — background spot-checks work through those a few at a time."]}),i.jsx("div",{style:{display:"flex",flexDirection:"column",gap:8},children:Array.from(U.entries()).map(([z,O])=>{const J=O.filter(F=>F.reachability==="routable").length;return i.jsxs("div",{style:{background:"var(--bg-card)",borderRadius:8,border:"1px solid var(--border)",overflow:"hidden"},children:[i.jsxs("div",{style:{padding:"10px 14px",borderBottom:"1px solid var(--border)",display:"flex",alignItems:"center",gap:8},children:[i.jsx("span",{style:{fontSize:16},children:z==="groq"?"⚡":z==="gemini"?"🌀":z==="local"?"💻":"🤖"}),i.jsx("span",{style:{fontWeight:600,color:"var(--text-primary)"},children:z}),i.jsxs("span",{style:{fontSize:12,color:"var(--text-secondary)"},children:["(",O.length," shown · ",J," routable)"]})]}),i.jsx("div",{style:{padding:"8px 14px"},children:O.map(F=>{const L=Date.now(),ie=R==null?void 0:R[F.reachability],fe=T==null?void 0:T[F.freshness],ve=(ie==null?void 0:ie.color)??"var(--text-secondary)";return i.jsxs("div",{"data-testid":`timeline-row-${F.provider}-${F.model}`,style:{display:"flex",alignItems:"center",gap:12,padding:"6px 0",borderBottom:"1px solid var(--border-light)"},children:[i.jsxs("div",{style:{flex:1,minWidth:0},children:[i.jsx("div",{style:{fontSize:13,color:"var(--text-primary)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:F.model}),i.jsxs("div",{style:{fontSize:11,color:"var(--text-secondary)",display:"flex",gap:12,flexWrap:"wrap"},children:[i.jsxs("span",{children:["Probed: ",Wo(L-F.lastProbedAt)]}),i.jsxs("span",{children:["Verified: ",F.lastVerifiedAt>0?Wo(L-F.lastVerifiedAt):"never"]}),F.lastUsedAt>0&&i.jsxs("span",{children:["Used: ",Wo(L-F.lastUsedAt)]}),F.latencyMs!==void 0&&i.jsxs("span",{children:[F.latencyMs,"ms"]}),F.errorRate>0&&i.jsxs("span",{style:{color:F.errorRate>.5?"var(--accent-red)":"var(--accent-yellow)"},children:["err ",(F.errorRate*100).toFixed(0),"%"]}),F.daysSinceVerify!==null&&F.daysSinceVerify>7&&i.jsxs("span",{style:{color:"var(--accent-yellow)"},children:["proof ",Cbe(F.lastVerifiedAt)," old"]})]})]}),i.jsx(Abe,{entry:F}),fe&&i.jsx("span",{style:rC(fe.color),title:fe.blurb,children:fe.label}),i.jsx("span",{style:rC(ve),title:(ie==null?void 0:ie.blurb)??F.reachability,"data-testid":`reachability-${F.provider}-${F.model}`,children:((ie==null?void 0:ie.label)??F.reachability).toUpperCase()})]},F.model)})})]},z)})}),I.length===0&&i.jsx("div",{style:{textAlign:"center",padding:"40px 20px",color:"var(--text-secondary)"},children:o==="routable"&&P.length>0?"No model is routable right now — every tracked model is unverified, parked, expired or dead. The Models page shows what each provider would offer live.":"No models match the current filter"})]})}const aC=7*24*60*60*1e3;function iC(e){const t=Math.max(0,Math.round((Date.now()-e)/6e4));if(t<1)return"just now";if(t<60)return`${t}m ago`;const n=Math.round(t/60);return n<24?`${n}h ago`:`${Math.round(n/24)}d ago`}function sC(e){return(e||"").split(/[\\/]/).filter(Boolean).slice(-2).join("/")||e}function Obe(){const[e,t]=b.useState(null),[n,r]=b.useState(!1),[a,s]=b.useState(!1),[o,l]=b.useState(null),c=b.useCallback(async()=>{const p=await K.fetchContinuity();t(p),r(!0)},[]);b.useEffect(()=>{let p=!0;return K.fetchContinuity().then(m=>{p&&(t(m),r(!0))}),()=>{p=!1}},[]);const u=b.useCallback(async(p,m,g)=>{s(!0),l(null);const y=await K.clearContinuity(p,m,g);y.ok?l(`Removed ${y.removed??0} record(s).`):l(y.error||"Could not clear that."),await c(),s(!1)},[c]);if(!n)return i.jsxs(i.Fragment,{children:[i.jsx("h2",{className:"section-subtitle",children:"🔗 Continuity"}),i.jsx("div",{className:"loading-state",children:i.jsx("p",{children:"Loading continuity data…"})})]});const d=e===null,f=(e==null?void 0:e.sessions)??[],h=(e==null?void 0:e.recall)??[];return i.jsxs(i.Fragment,{children:[i.jsx("h2",{className:"section-subtitle",children:"🔗 Continuity"}),i.jsx("p",{className:"memory-namespace-note",children:"The conversation snapshots that let a crashed or killed turn be resumed, and the index of past asks used for semantic recall. Both are history — they never decide that work is done. Turn the switches on or off on the Process Environment page."}),d?i.jsxs("p",{className:"memory-namespace-note",children:["Continuity data is unavailable — this dashboard server has no ",i.jsx("code",{children:"/api/continuity"})," endpoint."]}):i.jsxs(i.Fragment,{children:[i.jsxs("p",{className:"memory-backend",children:["Session store: ",i.jsx("code",{children:e.toggles.sessionStore?"ON":"OFF"})," · ","Semantic recall: ",i.jsx("code",{children:e.toggles.sessionRecall?"ON":"OFF"})]}),o?i.jsx("div",{className:"env-var-notice",children:o}):null,i.jsxs("h3",{className:"section-subtitle",children:["Stored sessions (",f.length,")"]}),f.length===0?i.jsx("p",{className:"memory-namespace-note",children:"No session snapshots yet."}):i.jsxs(i.Fragment,{children:[i.jsx("div",{className:"memory-list",children:f.map(p=>i.jsxs("div",{className:"memory-item",children:[i.jsxs("span",{className:"memory-project",children:[p.open?"↩️ OPEN":"✓ closed"," · ",p.goal]}),i.jsxs("span",{className:"memory-count",children:[sC(p.cwd)," · ",p.steps," step(s) · ",iC(p.savedAt)]}),i.jsx("button",{className:"admin-mini-btn admin-mini-btn-danger",type:"button",disabled:a,"aria-label":`Forget session ${p.goal}`,onClick:()=>void u("session",p.id),children:"🗑️ Forget"})]},p.id))}),i.jsxs("div",{className:"admin-row-actions",children:[i.jsx("button",{className:"admin-mini-btn admin-mini-btn-danger",type:"button",disabled:a,title:"Delete only session snapshots saved more than 7 days ago",onClick:()=>void u("sessions",void 0,aC),children:"🗑️ Forget older than a week"}),i.jsx("button",{className:"admin-mini-btn admin-mini-btn-danger",type:"button",disabled:a||f.length===0,onClick:()=>void u("sessions"),children:"🗑️ Forget all sessions"})]})]}),i.jsxs("h3",{className:"section-subtitle",children:["Recalled past asks (",h.length,")"]}),h.length===0?i.jsx("p",{className:"memory-namespace-note",children:"Nothing indexed for recall yet."}):i.jsxs(i.Fragment,{children:[i.jsx("div",{className:"memory-list",children:h.map(p=>i.jsxs("div",{className:"memory-item",children:[i.jsxs("span",{className:"memory-project",children:[p.outcome,": ",p.goal]}),i.jsxs("span",{className:"memory-count",children:[sC(p.projectPath)," · ",iC(p.savedAt)]}),i.jsx("button",{className:"admin-mini-btn admin-mini-btn-danger",type:"button",disabled:a,"aria-label":`Forget recall entry ${p.goal}`,onClick:()=>void u("recall-entry",p.id),children:"🗑️ Forget"})]},p.id))}),i.jsxs("div",{className:"admin-row-actions",children:[i.jsx("button",{className:"admin-mini-btn admin-mini-btn-danger",type:"button",disabled:a,title:"Delete only recall entries indexed more than 7 days ago",onClick:()=>void u("recall",void 0,aC),children:"🗑️ Forget older than a week"}),i.jsx("button",{className:"admin-mini-btn admin-mini-btn-danger",type:"button",disabled:a||h.length===0,onClick:()=>void u("recall"),children:"🗑️ Forget all recall entries"})]})]})]})]})}function as(e){return e==null?"0":e>=1e6?(e/1e6).toFixed(1)+"M":e>=1e3?(e/1e3).toFixed(1)+"K":bt(e)}function Pbe(e){return e==null?"0%":(e*100).toFixed(1)+"%"}const oC={"faiss-native":"native FAISS","faiss-ivf":"FAISS-style IVF-flat ANN",json:"exact flat cosine (JSON)"};function Rbe({data:e}){var c,u;if(!e)return i.jsxs(i.Fragment,{children:[i.jsx(Oe,{icon:"💾",title:"Memory Store"}),i.jsx("div",{className:"loading-state",children:i.jsx("p",{children:"Loading memory data..."})})]});const{memory:t,health:n}=e,r=Object.entries(t.byFingerprint||{}).sort(([,d],[,f])=>f-d),a=Object.entries(((c=t.facts)==null?void 0:c.byProject)||{}).sort(([,d],[,f])=>f-d),s=[...t.vectorNamespaces||[]].sort((d,f)=>f.entries-d.entries),o=t.recall||{total:0,today:0,last7d:0},l=[{key:"trajectories",icon:"🧭",value:as(t.total),label:"Trajectories",tone:"accent"},{key:"avg-score",icon:"⭐",value:Pbe(t.avgScore),label:"Avg Score",tone:"ok"},{key:"facts",icon:"📌",value:as((u=t.facts)==null?void 0:u.total),label:"Facts",tone:"warn"},{key:"recall",icon:"🔁",value:as(o.total),label:"Recall Hits",tone:"ok"},{key:"patterns",icon:"🧩",value:as(n==null?void 0:n.patterns),label:"Coding Patterns",tone:"warn"},{key:"feedback",icon:"👍",value:as(n==null?void 0:n.feedback),label:"Feedback Ratings",tone:"ok"}];return i.jsxs(i.Fragment,{children:[i.jsx(Oe,{icon:"💾",title:"Memory Store"}),i.jsx(Wi,{tiles:l}),i.jsxs("p",{className:"memory-backend",children:["Memory tier: ",i.jsx("code",{children:t.backend||"local"})," · ","Vector index: ",i.jsx("code",{children:t.vectorBackend||"unknown"}),t.vectorBackend&&oC[t.vectorBackend]?` (${oC[t.vectorBackend]})`:"",o.last7d>0?` · ${as(o.last7d)} recall(s) this week, ${as(o.today)} today`:" · no recalls yet"]}),i.jsx(Obe,{}),r.length>0&&i.jsxs(i.Fragment,{children:[i.jsx("h2",{className:"section-subtitle",children:"By Project Type"}),i.jsx("div",{className:"memory-list",children:r.map(([d,f])=>i.jsxs("div",{className:"memory-item",children:[i.jsx("span",{className:"memory-project",children:d}),i.jsxs("span",{className:"memory-count",children:[f," trajectory(ies)"]})]},d))})]}),a.length>0&&i.jsxs(i.Fragment,{children:[i.jsx("h2",{className:"section-subtitle",children:"Facts by Project"}),i.jsx("div",{className:"memory-list",children:a.map(([d,f])=>i.jsxs("div",{className:"memory-item",children:[i.jsx("span",{className:"memory-project",children:d}),i.jsxs("span",{className:"memory-count",children:[f," fact(s)"]})]},d))})]}),s.length>0&&i.jsxs(i.Fragment,{children:[i.jsx("h2",{className:"section-subtitle",children:"Vector Index by Namespace"}),i.jsxs("p",{className:"memory-namespace-note",children:["Each namespace is its own index file. ",i.jsx("code",{children:"default"})," holds only successful trajectories and indexed sessions — facts, repo chunks and the model registry have their own namespaces — so a small ",i.jsx("code",{children:"default"})," count is corpus size, not a broken index."]}),i.jsx("div",{className:"memory-list",children:s.map(d=>i.jsxs("div",{className:"memory-item",children:[i.jsx("span",{className:"memory-project",children:d.name}),i.jsxs("span",{className:"memory-count",children:[d.entries," vector(s)"]})]},d.name))})]})]})}function bv(e){const t=e.replace(/[\\/]+$/,""),n=Math.max(t.lastIndexOf("/"),t.lastIndexOf("\\"));return n>=0?t.slice(n+1):t}function Mbe(){const[e,t]=b.useState({configured:!1,authenticated:!1,role:null}),n=qr(),[r,a]=b.useState(null),[s,o]=b.useState(null),[l,c]=b.useState(null),[u,d]=b.useState(""),[f,h]=b.useState(""),[p,m]=b.useState(!1),[g,y]=b.useState(""),[v,k]=b.useState(""),[w,j]=b.useState(null),[S,x]=b.useState(!1),N=e.authenticated&&(e.role==="admin"||e.role==="operator"),E=b.useCallback(async()=>{const T=await K.fetchKnowledge();a(T)},[]);b.useEffect(()=>{K.fetchAdminAuthStatus().then(T=>{t(T?{configured:T.configured,authenticated:T.authenticated,role:T.role??null}:{configured:!1,authenticated:!1,role:null})}),E()},[E,n]);const P=b.useCallback(async()=>{var B;o(null),c(null);const T=f.split(`
206
206
  `).map($=>$.trim()).filter(Boolean);if(!u.trim()||T.length===0){o("A tag and at least one file or folder path are required.");return}m(!0);try{const $=await K.knowledgeIngest(u,T);if(!$.ok)o($.error||"Ingest failed.");else{const I=(B=$.skipped)!=null&&B.length?` Skipped: ${$.skipped.map(D=>`${bv(D.path)} (${D.reason})`).join("; ")}`:"";c(`Ingested ${$.files??0} document(s) / ${$.chunks??0} chunk(s) under '${$.tag}'.${I}`),h(""),await E()}}finally{m(!1)}},[u,f,E]),_=b.useCallback(async()=>{if(o(null),j(null),!g.trim()||!v.trim()){o("A tag and a question are required.");return}x(!0);try{const T=await K.knowledgeQuery(g,v);T.ok?j(T.hits??[]):o(T.error||"Query failed.")}finally{x(!1)}},[g,v]),R=b.useCallback(async T=>{o(null),c(null);const B=await K.knowledgeForget(T);B.ok?c(`Removed knowledge tag '${T}'.`):o(B.error||`Could not remove '${T}'.`),await E()},[E]);return i.jsxs("div",{children:[i.jsx(Oe,{icon:"📚",title:"Knowledge Base",description:"Tag your own documents once; answer questions scoped to a tag. The data part comes from your documents, the general part from the model."}),i.jsxs("div",{className:"env-var-header",children:[i.jsx("span",{className:"env-var-title",children:"Documents and vectors live in ~/.nuvira/memory — never in a repository or package."}),i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:()=>void E(),children:"↻ Refresh"})]}),e.authenticated?null:i.jsx("div",{className:"admin-hint",children:e.configured?"Log in to view or manage knowledge tags.":"Set up an admin account to manage knowledge tags."}),s?i.jsx("div",{className:"admin-error",children:s}):null,l?i.jsx("div",{className:"admin-hint",children:l}):null,i.jsx("h2",{className:"section-title",children:"Tags"}),r&&r.length===0?i.jsx("div",{className:"admin-hint",children:"No knowledge tags yet. Ingest a document below to create one."}):null,r&&r.length>0?i.jsx("div",{className:"admin-table-wrapper",children:i.jsxs("table",{className:"admin-table",children:[i.jsx("thead",{children:i.jsxs("tr",{children:[i.jsx("th",{children:"Tag"}),i.jsx("th",{children:"Chunks"}),i.jsx("th",{children:"Documents"}),N?i.jsx("th",{}):null]})}),i.jsx("tbody",{children:r.map(T=>i.jsxs("tr",{children:[i.jsx("td",{children:T.tag}),i.jsx("td",{children:T.chunkCount}),i.jsx("td",{children:T.documents.map(B=>i.jsxs("div",{title:B.path,children:[bv(B.path)," (",B.chunks," chunk",B.chunks===1?"":"s",")"]},B.path))}),N?i.jsx("td",{children:i.jsx("button",{className:"admin-mini-danger",type:"button",onClick:()=>void R(T.tag),"aria-label":`Remove knowledge tag ${T.tag}`,children:"Forget"})}):null]},T.tag))})]})}):null,N?i.jsxs(i.Fragment,{children:[i.jsx("h2",{className:"section-title",children:"Ingest under a tag"}),i.jsx("div",{className:"admin-hint",children:"One file or folder path per line (PDF, DOCX, XLSX, PPTX, Markdown, CSV, JSON, plain text). Tags are normalized: “Dheeraj Health Report” becomes “dheeraj-health-report”."}),i.jsxs("div",{className:"admin-gate-form",children:[i.jsx("input",{className:"admin-input",type:"text",placeholder:"tag (e.g. dheeraj-health-report)",value:u,onChange:T=>d(T.target.value),"aria-label":"Knowledge tag"}),i.jsx("textarea",{className:"admin-input",rows:3,placeholder:`/path/to/labs.pdf
207
207
  /path/to/notes/`,value:f,onChange:T=>h(T.target.value),"aria-label":"Paths to ingest"}),i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:()=>void P(),disabled:p,children:p?"Ingesting…":"Ingest"})]})]}):null,i.jsx("h2",{className:"section-title",children:"Ask a tagged knowledge base"}),i.jsxs("div",{className:"admin-gate-form",children:[i.jsx("input",{className:"admin-input",type:"text",placeholder:"tag",list:"knowledge-tags",value:g,onChange:T=>y(T.target.value),"aria-label":"Tag to query"}),i.jsx("datalist",{id:"knowledge-tags",children:(r??[]).map(T=>i.jsx("option",{value:T.tag},T.tag))}),i.jsx("input",{className:"admin-input",type:"text",placeholder:"what is my LDL and how do I lower it",value:v,onChange:T=>k(T.target.value),"aria-label":"Question"}),i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:()=>void _(),disabled:S,children:S?"Searching…":"Query"})]}),w&&w.length===0?i.jsx("div",{className:"admin-hint",children:"No passages matched that tag — check the tag name, or ingest documents first."}):null,w&&w.length>0?i.jsx("div",{children:w.map((T,B)=>i.jsxs("div",{className:"admin-summary-card",children:[i.jsxs("div",{className:"admin-summary-label",children:[bv(T.sourcePath)," · chunk ",T.chunkIndex+1," · sim ",T.similarity.toFixed(3)]}),i.jsx("div",{className:"admin-summary-value",style:{whiteSpace:"pre-wrap",fontWeight:400},children:T.text.slice(0,600)})]},`${T.sourcePath}-${T.chunkIndex}-${B}`))}):null]})}const Ibe=7*24*60*60*1e3;function $be(e){return new Date(e).toLocaleDateString("en-US",{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}function Lbe({data:e}){const[t,n]=b.useState(null),[r,a]=b.useState(!1),[s,o]=b.useState(null),l=t??(e==null?void 0:e.history),c=b.useCallback(async(d,f={})=>{a(!0),o(null);const h=await K.clearHistory(d,f);h.ok?o(d==="all"?`Removed ${h.removed??0} conversation(s).`:d==="older"?h.removed?`Removed ${h.removed} conversation(s) older than a week.`:"Nothing older than a week — nothing removed.":`Removed ${h.removed?h.removed:0} conversation(s).`):o(h.error||"Could not delete that.");const p=await K.fetchHistory();p&&n(p),a(!1)},[]);if(!l)return i.jsxs(i.Fragment,{children:[i.jsx(Oe,{icon:"📝",title:"Conversation History"}),i.jsx("div",{className:"loading-state",children:i.jsx("p",{children:"Loading history..."})})]});const u=l.recent||[];return i.jsxs(i.Fragment,{children:[i.jsx(Oe,{icon:"📝",title:"Conversation History"}),i.jsxs("div",{className:"history-stats",children:[i.jsxs("span",{className:"history-count",children:["Total: ",i.jsx("strong",{children:l.total})," sessions"]}),i.jsxs("div",{className:"admin-row-actions",children:[i.jsx("button",{className:"admin-mini-btn admin-mini-btn-danger",type:"button",disabled:r,title:"Delete only conversations started more than 7 days ago",onClick:()=>void c("older",{olderThanMs:Ibe}),children:"🗑️ Forget older than a week"}),i.jsx("button",{className:"admin-mini-btn admin-mini-btn-danger",type:"button",disabled:r||l.total===0,onClick:()=>{window.confirm("Delete ALL stored conversations? This cannot be undone.")&&c("all")},children:"🗑️ Clear all history"})]})]}),s?i.jsx("div",{className:"env-var-notice",children:s}):null,i.jsx("div",{className:"history-list",children:u.length===0?i.jsx("div",{className:"empty-state",children:"No conversations recorded yet."}):u.map(d=>i.jsxs("div",{className:"history-item",children:[i.jsx("div",{className:"history-summary",children:d.summary||"Untitled"}),i.jsxs("div",{className:"history-meta",children:[i.jsxs("span",{children:["📅 ",$be(d.startedAt)]}),i.jsxs("span",{children:["🤖 ",d.provider||"--"]}),i.jsxs("span",{children:["💬 ",d.messageCount||0," msgs"]}),d.tags&&d.tags.length>0&&i.jsxs("span",{children:["🏷️ ",d.tags.map(f=>i.jsx("span",{className:"history-tag",children:f},f))]}),i.jsx("button",{className:"admin-mini-btn admin-mini-btn-danger",type:"button",disabled:r,"aria-label":`Forget conversation ${d.summary||d.id}`,onClick:()=>void c("session",{id:d.id}),children:"🗑️ Forget"})]})]},d.id))})]})}function Dbe(e){const t=Math.max(0,Math.round((Date.now()-e)/6e4));if(t<1)return"just now";if(t<60)return`${t}m ago`;const n=Math.round(t/60);return n<24?`${n}h ago`:`${Math.round(n/24)}d ago`}function Bbe(){const[e,t]=b.useState([]),[n,r]=b.useState(""),[a,s]=b.useState(""),[o,l]=b.useState(null),[c,u]=b.useState(!1),[d,f]=b.useState(!1),[h,p]=b.useState(null),[m,g]=b.useState(null),[y,v]=b.useState(""),[k,w]=b.useState(""),j=b.useCallback(async(E,P)=>{const _=await K.fetchDecisions(E,P);l(_),u(!0)},[]);b.useEffect(()=>{let E=!0;return K.listProjects().then(P=>{var R,T;if(!E)return;t(P);const _=((R=P.find(B=>B.kind==="cwd"))==null?void 0:R.path)??((T=P[0])==null?void 0:T.path)??"";r(_),j(_)}),()=>{E=!1}},[j]);const S=b.useCallback(()=>{n&&j(n,a.trim()||void 0)},[n,a,j]),x=b.useCallback(async E=>{if(!n||!y.trim())return;f(!0),p(null),await K.reviseDecision(n,E,y.trim(),k.trim()||void 0)?(p(`Revised ${E} — the previous answer is kept in its history.`),g(null),v(""),w(""),await j(n,a.trim()||void 0)):p("Could not revise that decision — it may no longer exist."),f(!1)},[n,y,k,a,j]),N=(o==null?void 0:o.decisions)??[];return i.jsxs(i.Fragment,{children:[i.jsx(Oe,{icon:"🧭",title:"Decisions",description:"The choices the agent asked YOU to make (ask_user), kept so you can refer back and revise them. Written to the project's .nuvira/decisions.jsonl — never a substitute for asking."}),c?o===null?i.jsxs("p",{className:"memory-namespace-note",children:["Decision data is unavailable — this dashboard server has no ",i.jsx("code",{children:"/api/decisions"})," endpoint."]}):i.jsxs(i.Fragment,{children:[i.jsx("h2",{className:"section-subtitle",children:"Workspace"}),e.length>1?i.jsxs("label",{className:"memory-backend",children:["Project:"," ",i.jsx("select",{value:n,onChange:E=>{r(E.target.value),j(E.target.value,a.trim()||void 0)},children:e.map(E=>i.jsxs("option",{value:E.path,children:[E.name," (",E.kind,")"]},E.path))})]}):i.jsx("p",{className:"memory-backend",children:i.jsx("code",{children:o.dir})}),i.jsxs("div",{className:"admin-row-actions",children:[i.jsx("input",{type:"search",value:a,placeholder:"Find decisions relevant to an ask…","aria-label":"Search decisions relevant to an ask",onChange:E=>s(E.target.value),onKeyDown:E=>{E.key==="Enter"&&S()}}),i.jsx("button",{className:"admin-mini-btn",type:"button",disabled:!n,onClick:S,children:"🔎 Search"}),o.relevant?i.jsx("button",{className:"admin-mini-btn",type:"button",disabled:!n,onClick:()=>{s(""),j(n)},children:"✕ Clear"}):null]}),h?i.jsx("div",{className:"env-var-notice",children:h}):null,i.jsx("h2",{className:"section-subtitle",children:o.relevant?`Relevant decisions (${N.length})`:`Recorded decisions (${N.length})`}),N.length===0?i.jsx("p",{className:"memory-namespace-note",children:o.relevant?"No recorded decision matches that ask.":"None yet — a decision is recorded when the agent has to ask you one."}):i.jsx("div",{className:"memory-list",children:N.map(E=>{var P;return i.jsxs("div",{className:"memory-item",children:[i.jsxs("div",{children:[i.jsxs("span",{className:"memory-project",children:[E.status==="revised"?"✏️":"✅"," ",E.question]}),i.jsxs("div",{className:"memory-count",children:["→ ",E.answer||"(none)"," · ",Dbe(E.at)," · ",E.source," · ",E.id,E.status==="revised"?` · revised ${((P=E.revisions)==null?void 0:P.length)??0}×`:""]}),E.choices&&E.choices.length>0?i.jsxs("div",{className:"memory-count",children:["offered: ",E.choices.join(" | ")]}):null]}),m===E.id?i.jsxs("div",{children:[i.jsx("input",{type:"text",value:y,placeholder:"New answer","aria-label":`New answer for ${E.question}`,onChange:_=>v(_.target.value)}),i.jsx("input",{type:"text",value:k,placeholder:"Why it changed (optional)","aria-label":`Note for ${E.question}`,onChange:_=>w(_.target.value)}),i.jsx("button",{className:"admin-mini-btn",type:"button",disabled:d||!y.trim(),onClick:()=>void x(E.id),children:"💾 Save"}),i.jsx("button",{className:"admin-mini-btn",type:"button",disabled:d,onClick:()=>{g(null),v(""),w("")},children:"✕ Cancel"})]}):i.jsx("button",{className:"admin-mini-btn",type:"button",onClick:()=>{g(E.id),v(E.answer),w("")},children:"✏️ Revise"})]},E.id)})})]}):i.jsx("div",{className:"loading-state",children:i.jsx("p",{children:"Loading decisions…"})})]})}function zbe({onFetch:e,onClear:t,onExport:n}){const[r,a]=b.useState([]),[s,o]=b.useState(!1),[l,c]=b.useState(""),[u,d]=b.useState(""),[f,h]=b.useState(null),[p,m]=b.useState(null);b.useEffect(()=>{g()},[l,u]);const g=async()=>{o(!0);try{const j=await e({skillName:l||void 0,status:u||void 0,limit:100});a(j);const S=j.length,x=j.filter(P=>P.status==="success").length,N=j.filter(P=>P.status==="failure").length,E=S>0?Math.round(j.reduce((P,_)=>P+_.durationMs,0)/S):0;m({total:S,success:x,failure:N,avgDuration:E})}catch(j){console.error("Failed to fetch execution history:",j)}finally{o(!1)}},y=async j=>{if(n)try{const S=await n(j),x=new Blob([S],{type:j==="json"?"application/json":"text/csv"}),N=URL.createObjectURL(x),E=document.createElement("a");E.href=N,E.download=`execution-history.${j}`,E.click(),URL.revokeObjectURL(N)}catch(S){console.error("Failed to export history:",S)}},v=async()=>{if(t&&confirm("Are you sure you want to clear all execution history?"))try{await t(),a([]),m(null)}catch(j){console.error("Failed to clear history:",j)}},k=j=>{switch(j){case"success":return"✅";case"failure":return"❌";case"timeout":return"⏰";case"rejected":return"🚫";case"error":return"💥";default:return"❓"}},w=j=>{switch(j){case"python":return"🐍";case"node":return"🟢";case"shell":return"🖥️";case"ruby":return"💎";case"go":return"🔵";case"rust":return"🦀";default:return"📜"}};return i.jsxs("div",{className:"execution-history",children:[i.jsx(Oe,{icon:"📜",title:"Execution History",actions:i.jsxs("div",{className:"execution-history-actions",children:[i.jsx("button",{className:"admin-mini-btn",type:"button",onClick:()=>y("json"),children:"📥 Export JSON"}),i.jsx("button",{className:"admin-mini-btn",type:"button",onClick:()=>y("csv"),children:"📥 Export CSV"}),t&&i.jsx("button",{className:"admin-mini-btn admin-mini-btn-danger",type:"button",onClick:v,children:"🗑️ Clear"})]})}),p&&i.jsxs("div",{className:"execution-history-stats",children:[i.jsxs("div",{className:"stat-item",children:[i.jsx("span",{className:"stat-value",children:p.total}),i.jsx("span",{className:"stat-label",children:"Total"})]}),i.jsxs("div",{className:"stat-item stat-success",children:[i.jsx("span",{className:"stat-value",children:p.success}),i.jsx("span",{className:"stat-label",children:"Success"})]}),i.jsxs("div",{className:"stat-item stat-failure",children:[i.jsx("span",{className:"stat-value",children:p.failure}),i.jsx("span",{className:"stat-label",children:"Failed"})]}),i.jsxs("div",{className:"stat-item",children:[i.jsxs("span",{className:"stat-value",children:[p.avgDuration,"ms"]}),i.jsx("span",{className:"stat-label",children:"Avg Duration"})]})]}),i.jsxs("div",{className:"execution-history-filters",children:[i.jsx("input",{className:"env-var-input",type:"text","aria-label":"Filter by skill name",placeholder:"Filter by skill name...",value:l,onChange:j=>c(j.target.value)}),i.jsxs("select",{className:"env-var-input","aria-label":"Filter by status",value:u,onChange:j=>d(j.target.value),children:[i.jsx("option",{value:"",children:"All statuses"}),i.jsx("option",{value:"success",children:"Success"}),i.jsx("option",{value:"failure",children:"Failure"}),i.jsx("option",{value:"timeout",children:"Timeout"}),i.jsx("option",{value:"rejected",children:"Rejected"}),i.jsx("option",{value:"error",children:"Error"})]})]}),i.jsx("div",{className:"execution-history-list",children:s?i.jsx("div",{className:"execution-history-empty",children:"Loading..."}):r.length===0?i.jsx("div",{className:"execution-history-empty",children:"No execution history found. Execute a skill to see results here."}):r.map(j=>i.jsxs("div",{className:`execution-history-entry ${j.status}`,onClick:()=>h((f==null?void 0:f.id)===j.id?null:j),children:[i.jsxs("div",{className:"entry-header",children:[i.jsx("span",{className:"entry-icon",children:k(j.status)}),i.jsx("span",{className:"entry-skill",children:j.skillName}),i.jsxs("span",{className:"entry-runtime",children:[w(j.runtime)," ",j.runtime]}),i.jsxs("span",{className:"entry-duration",children:[j.durationMs,"ms"]}),i.jsx("span",{className:"entry-time",children:new Date(j.timestamp).toLocaleString()}),i.jsx("span",{className:"entry-expand",children:(f==null?void 0:f.id)===j.id?"▼":"▶"})]}),(f==null?void 0:f.id)===j.id&&i.jsxs("div",{className:"entry-details",children:[i.jsxs("div",{className:"entry-detail-row",children:[i.jsx("span",{className:"detail-label",children:"Status:"}),i.jsx("span",{className:"detail-value",children:j.status})]}),i.jsxs("div",{className:"entry-detail-row",children:[i.jsx("span",{className:"detail-label",children:"Runtime:"}),i.jsx("span",{className:"detail-value",children:j.runtime})]}),i.jsxs("div",{className:"entry-detail-row",children:[i.jsx("span",{className:"detail-label",children:"Duration:"}),i.jsxs("span",{className:"detail-value",children:[j.durationMs,"ms"]})]}),j.exitCode!==void 0&&i.jsxs("div",{className:"entry-detail-row",children:[i.jsx("span",{className:"detail-label",children:"Exit Code:"}),i.jsx("span",{className:"detail-value",children:j.exitCode})]}),j.error&&i.jsxs("div",{className:"entry-detail-row",children:[i.jsx("span",{className:"detail-label",children:"Error:"}),i.jsx("span",{className:"detail-value entry-error",children:j.error})]}),j.command&&i.jsxs("div",{className:"entry-detail-row",children:[i.jsx("span",{className:"detail-label",children:"Command:"}),i.jsx("code",{className:"detail-value",children:j.command})]})]})]},j.id))})]})}function Fbe({envVars:e,onSave:t,onDelete:n,onTest:r,readOnly:a=!1}){const[s,o]=b.useState(null),[l,c]=b.useState(""),[u,d]=b.useState(!1),[f,h]=b.useState(""),[p,m]=b.useState(""),[g,y]=b.useState(null),[v,k]=b.useState({}),w=[...e].sort((N,E)=>N.requiredBy&&!E.requiredBy?-1:!N.requiredBy&&E.requiredBy?1:N.name.localeCompare(E.name)),j=N=>{t(N,l),o(null),c("")},S=()=>{f&&p&&(t(f,p),h(""),m(""),d(!1))},x=async N=>{if(r){y(N);try{const E=await r(N);k(P=>({...P,[N]:E}))}catch{k(E=>({...E,[N]:!1}))}finally{y(null)}}};return i.jsxs("div",{className:"env-var-editor",children:[i.jsxs("div",{className:"env-var-header",children:[i.jsx("h2",{className:"env-var-title",children:"🔐 Environment Variables"}),!a&&i.jsx("button",{className:"admin-mini-btn",type:"button",onClick:()=>d(!u),children:u?"✕ Cancel":"+ Add Variable"})]}),u&&!a&&i.jsxs("div",{className:"env-var-add-form",children:[i.jsx("input",{className:"env-var-input",type:"text",placeholder:"Variable name (e.g., MY_API_KEY)",value:f,onChange:N=>h(N.target.value)}),i.jsx("input",{className:"env-var-input",type:"password",placeholder:"Value",value:p,onChange:N=>m(N.target.value)}),i.jsx("button",{className:"admin-refresh-btn",type:"button",disabled:!f||!p,onClick:S,children:"💾 Save"})]}),i.jsx("div",{className:"env-var-list",children:w.length===0?i.jsx("div",{className:"env-var-empty",children:"No environment variables configured. Add one to get started."}):w.map(N=>i.jsxs("div",{className:`env-var-row ${N.isSet?"env-var-set":"env-var-missing"} ${N.isProviderCredential?"env-var-blocked":""}`,children:[i.jsxs("div",{className:"env-var-row-header",children:[i.jsxs("span",{className:"env-var-name",children:[N.name,N.requiredBy&&i.jsxs("span",{className:"env-var-required-badge",children:["required by ",N.requiredBy]}),N.isProviderCredential&&i.jsx("span",{className:"env-var-blocked-badge",children:"🔒 provider credential (blocked)"})]}),i.jsx("span",{className:"env-var-status",children:N.isSet?"✅ Set":"❌ Not set"})]}),N.description&&i.jsx("div",{className:"env-var-description",children:N.description}),s===N.name?i.jsxs("div",{className:"env-var-edit",children:[i.jsx("input",{className:"env-var-input",type:"password",value:l,onChange:E=>c(E.target.value),placeholder:"Enter new value..."}),i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:()=>j(N.name),children:"💾 Save"}),i.jsx("button",{className:"admin-mini-btn",type:"button",onClick:()=>o(null),children:"Cancel"})]}):i.jsxs("div",{className:"env-var-actions",children:[!a&&!N.isProviderCredential&&i.jsx("button",{className:"admin-mini-btn",type:"button",onClick:()=>{o(N.name),c("")},children:"✏️ Edit"}),r&&i.jsx("button",{className:"admin-mini-btn",type:"button",disabled:g===N.name,onClick:()=>x(N.name),children:g===N.name?"⏳ Testing...":"🧪 Test"}),!a&&i.jsx("button",{className:"admin-mini-btn admin-mini-btn-danger",type:"button",onClick:()=>n(N.name),children:"🗑️ Delete"}),v[N.name]!==void 0&&i.jsx("span",{className:`env-var-test-result ${v[N.name]?"env-var-test-pass":"env-var-test-fail"}`,children:v[N.name]?"✅ Valid":"❌ Invalid"})]})]},N.name))}),i.jsx("div",{className:"env-var-help",children:i.jsxs("p",{children:[i.jsx("strong",{children:"Tip:"})," Environment variables are stored in ",i.jsx("code",{children:"~/.nuvira/.env"})," and injected into skill executions. Provider credentials (ANTHROPIC_API_KEY, OPENAI_API_KEY, etc.) are automatically blocked from skill execution for security."]})})]})}function Ube(){const[e,t]=b.useState({configured:!1,authenticated:!1,role:null}),n=qr(),[r,a]=b.useState([]),[s,o]=b.useState(!0),[l,c]=b.useState(null),[u,d]=b.useState(null),f=e.authenticated&&(e.role==="admin"||e.role==="operator"),h=b.useCallback(async()=>{o(!0);const y=await K.fetchSkillEnv();a(y),o(!1)},[]);b.useEffect(()=>{K.fetchAdminAuthStatus().then(y=>{t(y?{configured:y.configured,authenticated:y.authenticated,role:y.role??null}:{configured:!1,authenticated:!1,role:null})}),h()},[h,n]);const p=b.useCallback(async(y,v)=>{var j;c(null),d(null);const k=await K.saveSecrets({[y]:v}),w=(j=k.refused)==null?void 0:j.find(S=>S.name===y);!k.ok||w?c(w?Wbe(y,w.reason):k.error||`Could not save ${y}.`):d(`Saved ${y}.`),await h()},[h]),m=b.useCallback(async y=>{c(null),d(null);const v=await K.deleteSkillEnvVar(y);v.ok?d(v.removed?`Deleted ${y}.`:`${y} was not stored in the env file.`):c(v.error||`Could not delete ${y}.`),await h()},[h]),g=b.useCallback(async y=>{const v=await K.testSkillEnvVar(y);return v.ok?(c(null),d(v.detail||`${y}: ${v.usable?"usable by skills":"not usable by skills"}`),v.usable===!0):(c(v.error||`Could not test ${y}.`),!1)},[]);return i.jsxs("div",{children:[i.jsx(Oe,{icon:"🔐",title:"Skill Environment Variables"}),i.jsxs("div",{className:"env-var-header",children:[i.jsx("span",{className:"env-var-title",children:"Values are masked; only names and set/unset state are shown."}),i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:()=>void h(),children:"↻ Refresh"})]}),i.jsxs("div",{className:"admin-hint",children:["Secrets here are injected into skill executions that declare them (",i.jsx("code",{children:"required_environment_variables"}),"). Provider credentials are listed but locked — they belong to provider setup, and skills never receive them."]}),e.authenticated?null:i.jsx("div",{className:"admin-hint",children:e.configured?"Log in to view or edit skill secrets.":"Set up an admin account to manage skill secrets."}),e.authenticated&&!f?i.jsx("div",{className:"admin-hint",children:"Read-only — admins and operators can change these values."}):null,l?i.jsx("div",{className:"env-var-notice env-var-notice-error",children:l}):null,u?i.jsx("div",{className:"env-var-notice",children:u}):null,s?i.jsx("div",{className:"loading-state",children:"Loading…"}):i.jsx(Fbe,{envVars:r,onSave:(y,v)=>void p(y,v),onDelete:y=>void m(y),onTest:g,readOnly:!f})]})}function Wbe(e,t){switch(t){case"provider-credential":return`${e} is a provider credential — configure it in provider setup instead. Skills never receive it.`;case"invalid-name":return`${e} is not a valid environment variable name.`;case"write-failed":return`${e} could not be written to the env file.`;default:return`${e} was not saved (${t}).`}}const Hbe=[{id:"turn",title:"Turn behaviour",blurb:"How each turn runs. Unset means nobody has asked for anything, which is not the same as asking for no."},{id:"observability",title:"Observability",blurb:"What a run records about itself. Both are off by default and off unless asked for."},{id:"hooks",title:"Tool hooks",blurb:"A command run around every tool call, with the call on stdin as JSON. For a phase, a value here REPLACES the hooks declared in tools.hooks."}];function Gbe(){const[e,t]=b.useState({configured:!1,authenticated:!1,role:null}),n=qr(),[r,a]=b.useState([]),[s,o]=b.useState(!0),[l,c]=b.useState(null),[u,d]=b.useState(null),[f,h]=b.useState({}),[p,m]=b.useState(null),g=e.authenticated&&(e.role==="admin"||e.role==="operator"),y=b.useCallback(async()=>{o(!0),a(await K.fetchProcessEnv()),o(!1)},[]);b.useEffect(()=>{K.fetchAdminAuthStatus().then(w=>{t(w?{configured:w.configured,authenticated:w.authenticated,role:w.role??null}:{configured:!1,authenticated:!1,role:null})}),y()},[y,n]);const v=b.useCallback(async(w,j)=>{m(w),c(null),d(null);const S=await K.saveProcessEnvVar(w,j);if(!S.ok||!S.row)c(S.error||`Could not set ${w}.`);else{const x=S.row;a(N=>N.map(E=>E.name===x.name?x:E)),h(N=>({...N,[w]:""})),d(`${w} = ${x.fileValue}. Takes effect on the next turn; the dashboard picked it up immediately.`)}m(null)},[]),k=b.useCallback(async w=>{m(w),c(null),d(null);const j=await K.deleteProcessEnvVar(w);if(!j.ok||!j.row)c(j.error||`Could not unset ${w}.`);else{const S=j.row;a(x=>x.map(N=>N.name===S.name?S:N)),h(x=>({...x,[w]:""})),d(j.removed?`${w} removed from the env file. ${S.unsetMeans}`:`${w} had no line in the env file. ${S.unsetMeans}`)}m(null)},[]);return i.jsxs("div",{children:[i.jsx(Oe,{icon:"🌱",title:"Process Environment"}),i.jsxs("div",{className:"env-var-header",children:[i.jsx("span",{className:"env-var-title",children:"These are the switches Agent-Nuvira reads for how a run behaves. Values are written to the credential env file and are not masked — do not put a secret in a hook command."}),i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:()=>void y(),children:"↻ Refresh"})]}),i.jsxs("div",{className:"admin-hint",children:["A value exported in your shell ",i.jsx("strong",{children:"wins over this file"}),", for the dashboard and for every CLI run in that shell. A row that says ",i.jsx("em",{children:"shell value wins"})," is reporting exactly that, and writes here will not change it."]}),e.authenticated?null:i.jsx("div",{className:"admin-hint",children:e.configured?"Log in to view or change the process environment.":"Set up an admin account to change the process environment."}),e.authenticated&&!g?i.jsx("div",{className:"admin-hint",children:"Read-only — admins and operators can change these values."}):null,l?i.jsx("div",{className:"env-var-notice env-var-notice-error",children:l}):null,u?i.jsx("div",{className:"env-var-notice",children:u}):null,s?i.jsx("div",{className:"loading-state",children:"Loading…"}):Hbe.map(w=>{const j=r.filter(S=>S.group===w.id);return j.length===0?null:i.jsxs("section",{className:"process-env-group",children:[i.jsx("h3",{className:"process-env-group-title",children:w.title}),i.jsx("p",{className:"process-env-group-blurb",children:w.blurb}),i.jsx("div",{className:"env-var-list",children:j.map(S=>i.jsx(qbe,{row:S,draft:f[S.name]??"",busy:p===S.name,readOnly:!g,onDraft:x=>h(N=>({...N,[S.name]:x})),onSet:x=>void v(S.name,x),onUnset:()=>void k(S.name)},S.name))})]},w.id)})]})}function qbe({row:e,draft:t,busy:n,readOnly:r,onDraft:a,onSet:s,onUnset:o}){const l=e.state==="on",c=e.state!=="unset",u=f=>`admin-mini-btn${f?" process-env-active":""}`,d=e.kind==="flag"&&e.fileValue!==null&&e.fileValue!=="1"&&e.fileValue!=="0"?e.fileValue:null;return i.jsxs("div",{className:`env-var-row ${c?"env-var-set":"env-var-missing"}`,"data-testid":`process-env-row-${e.name}`,children:[i.jsxs("div",{className:"env-var-row-header",children:[i.jsxs("span",{className:"env-var-name",children:[e.name,e.shadowed?i.jsxs("span",{className:"env-var-blocked-badge",children:["⚠️ shell value wins: ",e.processValue]}):null]}),i.jsxs("span",{className:"env-var-status",children:[e.kind==="flag"?l?"✅ On":c?"⭕ Off":"➖ Unset":c?"✅ Set":"➖ Unset",d?` (${d})`:""]})]}),i.jsxs("div",{className:"env-var-description",children:[i.jsx("strong",{children:e.label})," — ",e.description]}),i.jsxs("div",{className:"env-var-description",children:["Unset: ",e.unsetMeans]}),e.cliEquivalent?i.jsxs("div",{className:"env-var-description",children:["Same switch: ",i.jsx("code",{children:e.cliEquivalent})]}):null,e.warning?i.jsxs("div",{className:"env-var-warning",children:["⚠️ ",e.warning]}):null,r?null:i.jsxs("div",{className:"env-var-actions",children:[e.kind==="flag"?i.jsxs(i.Fragment,{children:[i.jsx("button",{className:u(l),type:"button",disabled:n,onClick:()=>s("1"),children:"On"}),i.jsx("button",{className:u(c&&!l),type:"button",disabled:n,onClick:()=>s("0"),children:"Off"}),i.jsx("button",{className:u(!c),type:"button",disabled:n,onClick:o,children:"Unset"})]}):null,e.kind==="text"||e.acceptsValue?i.jsxs(i.Fragment,{children:[i.jsx("input",{className:"env-var-input",type:"text",value:t,placeholder:e.placeholder,disabled:n,onChange:f=>a(f.target.value),"aria-label":`${e.name} value`}),i.jsxs("button",{className:"admin-mini-btn",type:"button",disabled:n||t.trim()==="",onClick:()=>s(t),children:["💾 ",e.valueLabel??"Save"]})]}):null,e.kind==="text"?i.jsx("button",{className:"admin-mini-btn admin-mini-btn-danger",type:"button",disabled:n,onClick:o,children:"🗑️ Unset"}):null]})]})}const lC={before_tool_call:"🛑",after_tool_call:"✅",failed_tool_call:"❌",on_session_end:"🏁"};function cC(e){const t={};for(const n of e.split(`
208
208
  `)){const r=n.trim();if(!r)continue;const a=r.indexOf("=");if(a<=0)continue;const s=r.slice(0,a).trim(),o=r.slice(a+1).trim();s&&o&&(t[s]=o)}return Object.keys(t).length>0?t:void 0}function Kbe(e){const t=e.when??{},n=[];if(t.tool&&n.push(`tool ${t.tool}`),t.surface&&n.push(`surface ${t.surface}`),t.cwdPrefix&&n.push(`cwd ${t.cwdPrefix}*`),t.argsMatch)for(const[a,s]of Object.entries(t.argsMatch))n.push(`${a}=${s}`);const r=n.length>0?n.join(" · "):"every call";switch(e.action.kind){case"deny":return`${r} → deny${e.action.reason?`: ${e.action.reason}`:""}`;case"notify":return`${r} → notify: ${e.action.message}`;case"scan-args":return`${r} → scan args for secrets${e.action.denyOnHit?" (deny on hit)":""}`}}function Vbe(){const e=qr(),[t,n]=b.useState({configured:!1,authenticated:!1,role:null}),[r,a]=b.useState(null),[s,o]=b.useState(!0),[l,c]=b.useState(null),[u,d]=b.useState(null),[f,h]=b.useState(!1),[p,m]=b.useState([]),[g,y]=b.useState(""),[v,k]=b.useState(""),[w,j]=b.useState("before_tool_call"),[S,x]=b.useState("deny"),[N,E]=b.useState(""),[P,_]=b.useState(""),[R,T]=b.useState(""),[B,$]=b.useState(""),[I,D]=b.useState(""),[U,M]=b.useState("hook fired: {tool}"),[z,O]=b.useState(!1),J=t.authenticated&&(t.role==="admin"||t.role==="operator"),F=b.useCallback(async()=>{o(!0);const G=await K.fetchHooks();G?(a(G),m(G.hooks)):c("Could not load hooks — the dashboard server may be older than this bundle."),o(!1)},[]);b.useEffect(()=>{K.fetchAdminAuthStatus().then(G=>{n(G?{configured:G.configured,authenticated:G.authenticated,role:G.role??null}:{configured:!1,authenticated:!1,role:null})}),F()},[F,e]);const L=(r==null?void 0:r.events)??["before_tool_call","after_tool_call","failed_tool_call","on_session_end"],ie=(r==null?void 0:r.eventDescriptions)??{},fe=(r==null?void 0:r.actionKinds)??["deny","notify","scan-args"],ve=(r==null?void 0:r.actionDescriptions)??{},Ee=b.useMemo(()=>p.some(G=>G.id===g.trim()),[p,g]),ee=/^[a-z0-9][a-z0-9-]{0,63}$/.test(g.trim()),Q=ee&&!Ee&&v.trim().length>0,ae=b.useCallback(()=>{c(null),d(null);const G={...N.trim()?{tool:N.trim()}:{},...P.trim()?{surface:P.trim()}:{},...R.trim()?{cwdPrefix:R.trim()}:{},...cC(B)?{argsMatch:cC(B)}:{}},xe=S==="deny"?{kind:"deny",...I.trim()?{reason:I.trim()}:{}}:S==="notify"?{kind:"notify",message:U.trim()||"hook fired: {tool}"}:{kind:"scan-args",denyOnHit:z,...I.trim()?{reason:I.trim()}:{}},we={id:g.trim(),label:v.trim(),event:w,enabled:!0,...Object.keys(G).length>0?{when:G}:{},action:xe,source:"user",updatedAt:Date.now()};m(Pe=>[...Pe,we]),y(""),k(""),E(""),_(""),T(""),$(""),D(""),O(!1)},[g,v,w,S,N,P,R,B,I,U,z]),ce=b.useCallback(async()=>{h(!0),c(null),d(null);const G=await K.saveHooks(p);G.ok?(m(G.hooks??p),d(`Saved ${(G.hooks??p).length} hook(s). They are in force on the next tool call.`)):c(G.error||"Could not save hooks."),h(!1)},[p]);return i.jsxs("div",{children:[i.jsx(Oe,{icon:"🪝",title:"Hooks",description:"Declarative lifecycle rules bound to nuvira's own seams. A hook is DATA, not code: its only possible actions are deny, notify and secret-scan. There is no run-command action and no third-party script — nothing here executes."}),i.jsxs("div",{className:"env-var-header",children:[i.jsxs("span",{className:"env-var-title",children:[p.length," declared · ",p.filter(G=>G.enabled).length," enabled",r!=null&&r.file?i.jsxs(i.Fragment,{children:[" · stored at ",i.jsx("code",{children:r.file})]}):null]}),i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:()=>void F(),children:"↻ Refresh"}),J?i.jsxs("button",{className:"admin-refresh-btn",type:"button",disabled:f,onClick:()=>void ce(),children:["💾 ",f?"Saving…":"Save hooks"]}):null]}),t.authenticated?null:i.jsx("div",{className:"admin-hint",children:t.configured?"Log in to view or change hooks.":"Set up an admin account to change hooks."}),t.authenticated&&!J?i.jsx("div",{className:"admin-hint",children:"Read-only — admins and operators can change hooks."}):null,l?i.jsx("div",{className:"env-var-notice env-var-notice-error",children:l}):null,u?i.jsx("div",{className:"env-var-notice",children:u}):null,i.jsxs("section",{className:"panel",children:[i.jsx("h2",{className:"section-title",children:"How it works"}),i.jsxs("p",{className:"admin-hint",children:["When a seam fires, nuvira tests each enabled hook whose event matches, in order, and the FIRST ",i.jsx("code",{children:"deny"})," ","wins. Every action is implemented natively, so a bad hook can at worst block a call or print a line — it can never run code, reach the network, or read a credential."]}),i.jsxs("table",{className:"chat-plan-table",children:[i.jsx("thead",{children:i.jsxs("tr",{children:[i.jsx("th",{children:"Seam"}),i.jsx("th",{children:"When it fires"})]})}),i.jsx("tbody",{children:L.map(G=>i.jsxs("tr",{children:[i.jsxs("td",{children:[lC[G]," ",i.jsx("code",{children:G})]}),i.jsx("td",{children:ie[G]??""})]},G))})]}),i.jsxs("table",{className:"chat-plan-table",children:[i.jsx("thead",{children:i.jsxs("tr",{children:[i.jsx("th",{children:"Action"}),i.jsx("th",{children:"What it can do"})]})}),i.jsx("tbody",{children:fe.map(G=>i.jsxs("tr",{children:[i.jsx("td",{children:i.jsx("code",{children:G})}),i.jsx("td",{children:ve[G]??""})]},G))})]})]}),i.jsxs("section",{className:"panel",children:[i.jsx("h2",{className:"section-title",children:"Declared hooks"}),s?i.jsx("div",{className:"loading-state",children:"Loading…"}):p.length===0?i.jsx("div",{className:"admin-hint",children:"No hooks declared. Add one below — it stays a draft until you Save."}):i.jsx("div",{className:"env-var-list",children:p.map(G=>i.jsxs("div",{className:`env-var-row ${G.enabled?"env-var-set":"env-var-missing"}`,"data-testid":`hook-row-${G.id}`,children:[i.jsxs("div",{className:"env-var-row-header",children:[i.jsxs("span",{className:"env-var-name",children:[lC[G.event]," ",i.jsx("code",{children:G.id})," — ",G.label,G.source==="builtin"?i.jsx("span",{className:"hub-chip",children:"builtin"}):null]}),i.jsx("span",{className:"env-var-status",children:G.event})]}),i.jsx("div",{className:"env-var-description",children:Kbe(G)}),J?i.jsxs("div",{className:"env-var-actions",children:[i.jsx("button",{className:`admin-mini-btn${G.enabled?" process-env-active":""}`,type:"button",onClick:()=>m(xe=>xe.map(we=>we.id===G.id?{...we,enabled:!we.enabled}:we)),children:G.enabled?"✅ Enabled":"⭕ Disabled"}),G.source==="builtin"?i.jsx("span",{className:"admin-hint",children:"Built-in default — disable it to switch it off; it cannot be deleted."}):i.jsx("button",{className:"admin-mini-btn admin-mini-btn-danger",type:"button",onClick:()=>m(xe=>xe.filter(we=>we.id!==G.id)),children:"🗑️ Remove"})]}):null]},G.id))})]}),J?i.jsxs("section",{className:"panel",children:[i.jsx("h2",{className:"section-title",children:"Add a hook"}),i.jsxs("div",{className:"env-var-row",children:[i.jsx("div",{className:"env-var-row-header",children:i.jsxs("span",{className:"env-var-name",children:[i.jsx("input",{className:"env-var-input",type:"text",value:g,placeholder:"id (e.g. block-rm-rf)","aria-label":"Hook id",onChange:G=>y(G.target.value)}),i.jsx("input",{className:"env-var-input",type:"text",value:v,placeholder:"label","aria-label":"Hook label",onChange:G=>k(G.target.value)})]})}),g.trim()&&!ee?i.jsx("div",{className:"env-var-warning",children:"⚠️ id must be lowercase letters, digits and hyphens."}):null,Ee?i.jsx("div",{className:"env-var-warning",children:"⚠️ that id is already declared."}):null,i.jsxs("div",{className:"env-var-description",children:[i.jsxs("label",{children:["Seam:"," ",i.jsx("select",{value:w,"aria-label":"Hook event",onChange:G=>j(G.target.value),children:L.map(G=>i.jsx("option",{value:G,children:G},G))})]})," ",i.jsxs("label",{children:["Action:"," ",i.jsx("select",{value:S,"aria-label":"Hook action",onChange:G=>x(G.target.value),children:fe.map(G=>i.jsx("option",{value:G,disabled:G==="deny"&&w!=="before_tool_call",children:G},G))})]})]}),i.jsxs("div",{className:"env-var-description",children:["Match (blank = every call):"," ",i.jsx("input",{className:"env-var-input",type:"text",value:N,placeholder:"tool glob (run_*)","aria-label":"Tool glob",onChange:G=>E(G.target.value)})," ",i.jsx("input",{className:"env-var-input",type:"text",value:P,placeholder:"surface glob","aria-label":"Surface glob",onChange:G=>_(G.target.value)})," ",i.jsx("input",{className:"env-var-input",type:"text",value:R,placeholder:"cwd prefix","aria-label":"Cwd prefix",onChange:G=>T(G.target.value)})]}),i.jsxs("div",{className:"env-var-description",children:["Arg match (one ",i.jsx("code",{children:"key=glob"})," per line, optional):"," ",i.jsx("textarea",{className:"env-var-input",value:B,placeholder:"command=rm -rf*","aria-label":"Arg match",onChange:G=>$(G.target.value)})]}),S==="notify"?i.jsxs("div",{className:"env-var-description",children:["Message:"," ",i.jsx("input",{className:"env-var-input",type:"text",value:U,"aria-label":"Notify message",onChange:G=>M(G.target.value)})," ",i.jsxs("span",{className:"admin-hint",children:["{tool} {surface} {event}"," are interpolated."]})]}):i.jsxs("div",{className:"env-var-description",children:[S==="deny"?"Reason":"Reason (when denied)",":"," ",i.jsx("input",{className:"env-var-input",type:"text",value:I,"aria-label":"Reason",onChange:G=>D(G.target.value)})]}),S==="scan-args"&&w==="before_tool_call"?i.jsxs("label",{className:"env-var-description",children:[i.jsx("input",{type:"checkbox",checked:z,onChange:G=>O(G.target.checked)})," Block the call when a secret shape is found"]}):null,i.jsxs("div",{className:"env-var-actions",children:[i.jsx("button",{className:"admin-refresh-btn",type:"button",disabled:!Q,onClick:ae,children:"➕ Add to draft"}),i.jsx("span",{className:"admin-hint",children:"Nothing is in force until you press Save hooks."})]})]})]}):null]})}const Ybe={read:{label:"read",className:"cap-effect-read"},"local-write":{label:"local write",className:"cap-effect-local"},"local-state":{label:"machine state",className:"cap-effect-local"},external:{label:"off-machine",className:"cap-effect-external"},destructive:{label:"destructive",className:"cap-effect-destructive"}};function Xbe(e){return Ybe[e]??{label:e,className:"cap-effect-local"}}function Qbe(){const[e,t]=b.useState(null),[n,r]=b.useState([]),[a,s]=b.useState({authenticated:!1,role:null}),o=qr(),[l,c]=b.useState(!0),[u,d]=b.useState(null),[f,h]=b.useState(null),[p,m]=b.useState(null),[g,y]=b.useState(""),[v,k]=b.useState(""),[w,j]=b.useState(""),S=a.authenticated&&(a.role==="admin"||a.role==="operator"),x=b.useCallback(async()=>{c(!0);const[I,D]=await Promise.all([K.fetchCapabilities(),K.fetchSessionGrants()]);d(I?null:"Could not read capabilities from the server."),t(I),r(D??[]),c(!1)},[]);b.useEffect(()=>{K.fetchAdminAuthStatus().then(I=>{s(I?{authenticated:I.authenticated,role:I.role??null}:{authenticated:!1,role:null})}),x()},[x,o]);const N=b.useCallback(async I=>{m(I),d(null),await K.revokeSessionGrant(I)?r(U=>U.filter(M=>M.sessionId!==I)):d(`Could not end the grant for ${I}.`),m(null)},[]),E=b.useCallback(I=>{I&&t(D=>D&&{...D,learnedCommands:I})},[]),P=b.useCallback(async()=>{const I=g.trim(),D=v.trim();if(!I||!D)return;m("__save__"),d(null),h(null);const U=await K.saveLearnedCommand(I,D,w.trim()||void 0);U.ok?(E(U.commands),y(""),k(""),j(""),h(`Learned "${I}" for this machine.`)):d(U.error||"Could not save the command."),m(null)},[g,v,w,E]),_=b.useCallback(async I=>{m(I),d(null),h(null);const D=await K.forgetLearnedCommand(I);D.ok?(E(D.commands),h(`Forgot "${I}" on this machine.`)):d(D.error||`Could not forget "${I}".`),m(null)},[E]),R=(e==null?void 0:e.readyCount)??0,T=(e==null?void 0:e.blockedCount)??0,B=(e==null?void 0:e.missingExecutables)??[],$=(e==null?void 0:e.learnedCommands)??[];return i.jsxs("div",{children:[i.jsx(Oe,{icon:"🧰",title:"Capabilities"}),i.jsxs("div",{className:"env-var-header",children:[i.jsx("span",{className:"env-var-title",children:"What the agent can do on this machine, read from the same declarations the model discovers. A missing executable blocks a verb; a credential that is not an environment variable does not — it may live in the vault."}),i.jsx("button",{className:"admin-refresh-btn",type:"button",onClick:()=>void x(),children:"↻ Refresh"})]}),u?i.jsx("div",{className:"env-var-notice env-var-notice-error",children:u}):null,f?i.jsx("div",{className:"env-var-notice",children:f}):null,l?i.jsx("div",{className:"loading-state",children:"Loading…"}):e?i.jsxs(i.Fragment,{children:[i.jsxs("div",{className:"cap-summary","data-testid":"cap-summary",children:[i.jsxs("span",{className:"cap-tile cap-tile-ok","data-testid":"cap-tile-ready",children:[i.jsx("strong",{children:R})," ready"]}),i.jsxs("span",{className:`cap-tile${T>0?" cap-tile-blocked":""}`,"data-testid":"cap-tile-blocked",children:[i.jsx("strong",{children:T})," blocked"]}),i.jsxs("span",{className:`cap-tile${B.length>0?" cap-tile-blocked":""}`,"data-testid":"cap-tile-missing",children:[i.jsx("strong",{children:B.length})," missing executable",B.length===1?"":"s"]}),i.jsxs("span",{className:"cap-tile","data-testid":"cap-tile-grants",children:[i.jsx("strong",{children:n.length})," live session grant",n.length===1?"":"s"]})]}),i.jsxs("section",{className:"cap-section","data-testid":"cap-missing",children:[i.jsx("h3",{className:"cap-section-title",children:"Missing executables"}),B.length===0?i.jsx("p",{className:"cap-empty",children:"Every executable the curated verbs need is on PATH."}):i.jsx("ul",{className:"cap-missing-list",children:B.map(I=>i.jsxs("li",{className:"cap-missing-row",children:[i.jsx("code",{className:"cap-missing-bins",children:I.anyOf.join(" or ")}),i.jsxs("span",{className:"cap-missing-for",children:["needed by ",I.forRefs.join(", ")]}),i.jsx("span",{className:"cap-missing-remedy",children:I.remedy})]},I.anyOf.join("|")))})]}),i.jsxs("section",{className:"cap-section","data-testid":"cap-verbs",children:[i.jsx("h3",{className:"cap-section-title",children:"Curated verbs"}),i.jsx("div",{className:"cap-verb-list",children:e.verbs.map(I=>i.jsx(Zbe,{verb:I},I.id))})]}),i.jsxs("section",{className:"cap-section","data-testid":"cap-learned",children:[i.jsxs("h3",{className:"cap-section-title",children:["Learned commands (",$.length,")"]}),i.jsx("p",{className:"cap-section-blurb",children:"Commands derived for this machine, keyed by what they do — recorded by the model or observed from a labelled run. They are HINTS: the agent still checks presence before running one. Add or replace one with the same verb below."}),$.length===0?i.jsx("p",{className:"cap-empty",children:"Nothing learned yet — the agent records a command when it derives one, or when a labelled run succeeds."}):i.jsx("ul",{className:"cap-learned-list",children:$.map(I=>i.jsxs("li",{className:"cap-learned-row","data-testid":`cap-learned-${I.verb}`,children:[i.jsx("span",{className:"cap-learned-verb",children:I.verb}),i.jsx("span",{className:"cap-badge cap-effect-local",children:I.os}),i.jsx("span",{className:"cap-badge cap-effect-read",children:I.source}),i.jsx("code",{className:"cap-learned-cmd",children:I.command}),I.note?i.jsx("span",{className:"cap-learned-note",children:I.note}):null,S?i.jsx("button",{className:"admin-mini-btn admin-mini-btn-danger",type:"button",disabled:p===I.verb,onClick:()=>void _(I.verb),children:"Forget"}):null]},`${I.verb}|${I.os}`))}),S?i.jsxs("div",{className:"cap-learned-form",children:[i.jsx("input",{className:"env-var-input",type:"text","aria-label":"learned verb",placeholder:"verb (e.g. install java)",value:g,disabled:p==="__save__",onChange:I=>y(I.target.value)}),i.jsx("input",{className:"env-var-input",type:"text","aria-label":"learned command",placeholder:"command (e.g. brew install openjdk)",value:v,disabled:p==="__save__",onChange:I=>k(I.target.value)}),i.jsx("input",{className:"env-var-input",type:"text","aria-label":"learned note",placeholder:"note (optional)",value:w,disabled:p==="__save__",onChange:I=>j(I.target.value)}),i.jsx("button",{className:"admin-mini-btn",type:"button",disabled:!g.trim()||!v.trim()||p==="__save__",onClick:()=>void P(),children:"💾 Learn"})]}):i.jsx("div",{className:"admin-hint",children:"Read-only — admins and operators can add or remove learned commands."})]}),i.jsxs("section",{className:"cap-section","data-testid":"cap-grants",children:[i.jsx("h3",{className:"cap-section-title",children:"Live session grants"}),n.length===0?i.jsx("p",{className:"cap-empty",children:"No live session grants — off-machine actions will ask."}):i.jsx("ul",{className:"cap-grant-list",children:n.map(I=>i.jsxs("li",{className:"cap-grant-row","data-testid":`cap-grant-${I.sessionId}`,children:[i.jsx("code",{className:"cap-grant-id",children:I.sessionId}),i.jsx("span",{className:"cap-grant-cats",children:I.categories.join(", ")||"(no categories)"}),i.jsx("button",{className:"admin-mini-btn admin-mini-btn-danger",type:"button",disabled:p===I.sessionId,onClick:()=>void N(I.sessionId),children:"End"})]},I.sessionId))})]})]}):i.jsx("div",{className:"admin-hint",children:"Capabilities are unavailable right now."})]})}function Zbe({verb:e}){const t=Xbe(e.effect);return i.jsxs("div",{className:`cap-verb${e.ready?" cap-verb-ready":" cap-verb-blocked"}`,"data-testid":`cap-verb-${e.ref}`,children:[i.jsxs("div",{className:"cap-verb-header",children:[i.jsx("span",{className:"cap-verb-name",children:e.name}),i.jsx("span",{className:`cap-badge ${t.className}`,children:t.label}),i.jsx("span",{className:`cap-badge ${e.ready?"cap-effect-read":"cap-effect-destructive"}`,children:e.ready?"✅ ready":"⛔ blocked"}),e.grantable?i.jsxs("span",{className:"cap-badge cap-effect-local",children:["grantable: ",e.grantable]}):null]}),i.jsx("div",{className:"cap-verb-does",children:e.does}),e.gaps.length>0?i.jsx("ul",{className:"cap-verb-gaps",children:e.gaps.map(n=>i.jsx("li",{children:n},n))}):null,e.ask.length>0?i.jsxs("div",{className:"cap-verb-ask",children:["Will ask for: ",e.ask.join(", ")]}):null,e.onThisMachine?i.jsxs("div",{className:"cap-verb-cmd",children:["On this machine: ",i.jsx("code",{children:e.onThisMachine.command}),e.onThisMachine.note?i.jsxs("span",{className:"cap-verb-note",children:[" — ",e.onThisMachine.note]}):null]}):null,e.undo?i.jsxs("div",{className:"cap-verb-undo",children:["Undo: ",e.undo]}):null]})}function Jbe(e){const t={};for(const n of e.split(`
@@ -233,4 +233,4 @@ ${R.warnings.join(`
233
233
  `)}`:"")),l(null),v(xv),await k((e==null?void 0:e.deep)===!0)},x=async _=>{s(_);const R=await yB(_);if(s(null),!R.ok){l(R.reason??"Could not remove that server.");return}u(`Removed ${_}`),await k((e==null?void 0:e.deep)===!0)},N=(e==null?void 0:e.canWrite)??!1,E=(e==null?void 0:e.servers)??[];return i.jsxs("div",{className:"page",children:[i.jsx(Oe,{icon:"🔌",title:"MCP",description:"External MCP servers — configured once here and used by the agent on every surface. These controls write the same mcp.* config the CLI does."}),i.jsxs("div",{className:"mcp-card",children:[i.jsxs("div",{className:"mcp-muted",children:["Config file: ",i.jsx("code",{children:(e==null?void 0:e.configDir)??"…"})," — these controls write the same"," ",i.jsx("code",{children:"mcp.*"})," keys as ",i.jsx("code",{children:"nuvira config set mcp.*"}),", so the terminal and this page can never disagree."]}),i.jsxs("div",{style:{marginTop:10},children:[i.jsx("button",{className:"mcp-btn secondary",onClick:()=>void k(!0),disabled:n,children:"Check dependencies"}),i.jsx("span",{className:"mcp-muted",style:{marginLeft:8},children:e!=null&&e.deep?"service checks ran (e.g. docker daemon)":"service checks skipped on page load — press to probe them"})]})]}),o&&i.jsx("div",{className:"mcp-card mcp-problem",style:{whiteSpace:"pre-wrap"},children:o}),c&&i.jsx("div",{className:"mcp-card mcp-muted",children:c}),n&&i.jsx("div",{className:"mcp-card mcp-muted",children:"Loading MCP configuration…"}),e&&i.jsxs(i.Fragment,{children:[i.jsxs("div",{className:"mcp-card",children:[i.jsx("h3",{children:"Settings"}),i.jsx("div",{className:"mcp-muted",children:"Applies to every MCP server on every surface."}),i.jsx(ho,{label:"Enabled",hint:"Master switch — false makes MCP inert everywhere (true/false)",value:String(e.settings.enabled),disabled:!N,onSave:_=>w("mcp.enabled",_)}),i.jsx(ho,{label:"Auto-connect",hint:"Connect configured servers at the start of a turn (bounded, never fatal)",value:String(e.settings.autoConnect),disabled:!N,onSave:_=>w("mcp.autoConnect",_)}),i.jsx(ho,{label:"Connect timeout (ms)",hint:"Wall-clock budget for the connect step; exceeding it proceeds without MCP",value:String(e.settings.connectTimeoutMs),disabled:!N,onSave:_=>w("mcp.connectTimeoutMs",_)}),i.jsx(ho,{label:"Tools per server",hint:"Per-server eager-schema cap — stored and reported; enforcement is not wired yet (nothing is truncated today)",value:String(e.settings.maxToolsPerServer),disabled:!N,onSave:_=>w("mcp.maxToolsPerServer",_)}),i.jsx(ho,{label:"Tools in total",hint:"Cross-server ceiling — stored and reported; enforcement is not wired yet (nothing is truncated today)",value:String(e.settings.maxToolsTotal),disabled:!N,onSave:_=>w("mcp.maxToolsTotal",_)}),i.jsx(ho,{label:"Subagents inherit",hint:"conservative = only when the parent had MCP AND the child's allowance covers it; full = pass the parent's whole MCP set down (reach, never approval)",value:e.settings.subagentInheritance,disabled:!N,onSave:_=>w("mcp.subagent.inherit",_)}),((P=e.settings.warnings)==null?void 0:P.length)>0&&i.jsx("div",{className:"mcp-error",children:e.settings.warnings.join(`
234
234
  `)})]}),i.jsxs("div",{className:"mcp-card",children:[i.jsxs("h3",{children:["Configured servers (",E.length,")"]}),E.length===0&&i.jsx("div",{className:"mcp-muted",children:"None yet. Add one by hand below (any server), install one from the catalog, or drop a JSON file into the config directory."}),E.map(_=>{const R=e.settings.servers[_.name]??{};return i.jsxs("div",{className:"mcp-variant",children:[i.jsxs("div",{children:[i.jsx("strong",{children:_.name}),i.jsx("span",{className:"mcp-badge",children:_.transport}),_.variant&&i.jsxs("span",{className:"mcp-badge",children:["variant ",_.variant]}),i.jsx("span",{className:`mcp-badge ${_.enabled?"ok":"bad"}`,children:_.enabled?"enabled":"disabled"}),_.connected&&i.jsx("span",{className:"mcp-badge ok",children:"connected"})]}),i.jsxs("div",{className:"mcp-muted",children:[_.command?`${_.command} ${_.args.join(" ")}`:_.url,_.runtime?` (runtime: ${[_.runtime.command,..._.runtime.args??[]].join(" ")})`:"",_.envKeys.length>0?` · credentials: ${_.envKeys.join(", ")}`:"",_.headerKeys.length>0?` · headers: ${_.headerKeys.join(", ")}`:""]}),i.jsxs("div",{style:{marginTop:6,display:"flex",gap:8,flexWrap:"wrap"},children:[i.jsx("button",{className:"mcp-btn secondary",disabled:!N,onClick:()=>v(nxe(_)),children:"Edit"}),i.jsx("button",{className:"mcp-btn secondary",disabled:!N||a===_.name,onClick:()=>void w(`mcp.servers.${_.name}.enabled`,_.enabled?"false":"true"),children:_.enabled?"Disable":"Enable"}),i.jsx("input",{className:"mcp-input",style:{minWidth:260},placeholder:"runtime override, e.g. /opt/node20/bin/node /usr/local/bin/npx",defaultValue:R.runtime?[R.runtime.command,...R.runtime.args??[]].join(" "):"",disabled:!N,onKeyDown:T=>{T.key==="Enter"&&w(`mcp.servers.${_.name}.runtime.command`,T.target.value)}}),i.jsx("button",{className:"mcp-btn secondary",disabled:!N,onClick:()=>void w(`mcp.servers.${_.name}.runtime.command`,""),children:"Clear runtime"}),i.jsx("button",{className:"mcp-btn secondary",disabled:!N||a===_.name,onClick:()=>void x(_.name),children:"Uninstall"})]})]},_.name)})]}),i.jsxs("div",{className:"mcp-card",children:[i.jsx("h3",{children:"Add a server"}),i.jsxs("div",{className:"mcp-muted",children:["Any MCP server — a local command or a remote endpoint — not only the ones in the catalog below. This writes ",i.jsxs("code",{children:[e.configDir,"/<name>.json"]}),", the same file"," ",i.jsx("code",{children:"nuvira mcp add"})," writes, so the agent uses it on the next turn: no code, no release. Use ",i.jsx("strong",{children:"Edit"})," on a configured server to change it."]}),i.jsxs("div",{style:{display:"grid",gridTemplateColumns:"180px 1fr",gap:10,alignItems:"center",marginTop:10},children:[i.jsx("label",{className:"mcp-setting-label",children:"Name"}),i.jsx("input",{className:"mcp-input",placeholder:"my-server",value:y.name,disabled:!N||a==="__custom__",onChange:_=>v({...y,name:_.target.value})}),i.jsx("label",{className:"mcp-setting-label",children:"Transport"}),i.jsxs("div",{children:[i.jsxs("label",{className:"mcp-muted",style:{marginRight:12},children:[i.jsx("input",{type:"radio",name:"custom-transport",checked:y.transport==="stdio",disabled:!N,onChange:()=>v({...y,transport:"stdio"})})," ","stdio (a local process)"]}),i.jsxs("label",{className:"mcp-muted",children:[i.jsx("input",{type:"radio",name:"custom-transport",checked:y.transport==="sse",disabled:!N,onChange:()=>v({...y,transport:"sse"})})," ","remote (Streamable HTTP)"]})]}),y.transport==="stdio"?i.jsxs(i.Fragment,{children:[i.jsx("label",{className:"mcp-setting-label",children:"Command"}),i.jsx("input",{className:"mcp-input",placeholder:"npx",value:y.command,disabled:!N||a==="__custom__",onChange:_=>v({...y,command:_.target.value})}),i.jsx("label",{className:"mcp-setting-label",children:"Arguments"}),i.jsx("input",{className:"mcp-input",placeholder:"-y, @modelcontextprotocol/server-filesystem, /path/to/dir",value:y.args,disabled:!N||a==="__custom__",onChange:_=>v({...y,args:_.target.value})}),i.jsx("label",{className:"mcp-setting-label",children:"Environment"}),i.jsx("textarea",{className:"mcp-input",rows:3,placeholder:`TOKEN=…
235
235
  ANOTHER=…`,value:y.env,disabled:!N||a==="__custom__",onChange:_=>v({...y,env:_.target.value})})]}):i.jsxs(i.Fragment,{children:[i.jsx("label",{className:"mcp-setting-label",children:"URL"}),i.jsx("input",{className:"mcp-input",placeholder:"https://example.com/mcp",value:y.url,disabled:!N||a==="__custom__",onChange:_=>v({...y,url:_.target.value})}),i.jsx("label",{className:"mcp-setting-label",children:"Headers"}),i.jsx("textarea",{className:"mcp-input",rows:3,placeholder:"Authorization: Bearer …",value:y.headers,disabled:!N||a==="__custom__",onChange:_=>v({...y,headers:_.target.value})})]})]}),i.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center",marginTop:10,flexWrap:"wrap"},children:[i.jsxs("label",{className:"mcp-muted",children:[i.jsx("input",{type:"checkbox",checked:y.overwrite,disabled:!N||a==="__custom__",onChange:_=>v({...y,overwrite:_.target.checked})})," ","Replace the existing config for this name"]}),i.jsx("button",{className:"mcp-btn",disabled:!N||a==="__custom__",onClick:()=>void S(),children:a==="__custom__"?"Saving…":y.overwrite?"Save server":"Add server"}),i.jsx("button",{className:"mcp-btn secondary",disabled:a==="__custom__",onClick:()=>v(xv),children:"Clear"})]}),i.jsx("div",{className:"mcp-muted",style:{marginTop:8},children:"Credentials typed here go into the config file (mode 0600) and are never sent back to this page — editing an existing server keeps the secrets it already has unless you type a new value over them."})]}),i.jsxs("div",{className:"mcp-card",children:[i.jsxs("h3",{children:["Catalog (",e.catalog.length," capabilities)"]}),i.jsx("div",{className:"mcp-muted",children:"Each capability lists every way it can run on THIS machine, what that way needs, and what you get. A dependency that is missing (install it) is different from a service that is down (start it)."}),e.catalog.map(_=>i.jsxs("div",{className:"mcp-variant",children:[i.jsxs("div",{children:[i.jsx("strong",{children:_.name}),_.installed&&i.jsx("span",{className:"mcp-badge ok",children:"installed"}),i.jsxs("span",{className:"mcp-muted",children:[" — ",_.description]})]}),i.jsx("ul",{className:"mcp-offers",children:_.offers.map(R=>i.jsx("li",{children:R},R))}),_.supersedes&&i.jsxs("div",{className:"mcp-muted",children:["supersedes: ",_.supersedes]}),_.variants.map(R=>i.jsxs("div",{className:"mcp-muted",style:{marginLeft:12},children:[i.jsxs("label",{children:[i.jsx("input",{type:"radio",name:`variant-${_.name}`,checked:(h[_.name]??"")===R.id,disabled:R.optIn===!1&&h[_.name]!==R.id?!1:!N,onChange:()=>p(T=>({...T,[_.name]:R.id}))})," ",i.jsx("strong",{children:R.id})," — ",R.label," ",i.jsx("span",{className:`mcp-badge ${R.status.ok?"ok":"bad"}`,children:R.status.ok?"runnable":"cannot run yet"}),R.optIn&&i.jsx("span",{className:"mcp-badge",children:"opt-in"}),i.jsx("span",{className:"mcp-badge",children:R.trust})]}),i.jsx("div",{children:R.command?`${R.command} ${R.args.join(" ")}`:R.url}),R.status.problems.map(T=>i.jsxs("div",{className:"mcp-problem",children:["⚠ ",T]},T)),R.status.unverified.map(T=>i.jsxs("div",{children:["note: ",T]},T)),R.note&&i.jsxs("div",{children:["caveat: ",R.note]})]},R.id)),i.jsxs("div",{style:{marginTop:6,display:"flex",gap:8,flexWrap:"wrap"},children:[(_.variants.find(T=>T.id===h[_.name])??_.variants.find(T=>!T.optIn)??_.variants[0]).requires.filter(T=>T.kind==="env").map(T=>i.jsx("input",{className:"mcp-input",style:{minWidth:280},type:"password",placeholder:`${T.name} (${T.hint})`,disabled:!N,value:d[`${_.name}:${T.name}`]??"",onChange:B=>f($=>({...$,[`${_.name}:${T.name}`]:B.target.value}))},T.name)),i.jsx("input",{className:"mcp-input",placeholder:"runtime override (optional)",disabled:!N,value:m[_.name]??"",onChange:R=>g(T=>({...T,[_.name]:R.target.value}))}),i.jsx("button",{className:"mcp-btn",disabled:!N||a===_.name||_.installed,onClick:()=>void j(_),children:a===_.name?"Installing…":_.installed?"Installed":"Install"})]})]},_.name))]})]})]})}function axe(){const[e,t]=b.useState(null),[n,r]=b.useState(!1),[a,s]=b.useState("--"),[o,l]=b.useState(!1),u=Li().pathname==="/chat",[d,f]=b.useState(u);b.useEffect(()=>{u&&f(!0)},[u]);const h=b.useCallback(g=>{t(g),s(new Date().toLocaleTimeString())},[]),p=b.useCallback(g=>{r(g)},[]),m=b.useCallback(async()=>{l(!0);try{const g=await K.fetchAll();g&&h(g)}finally{l(!1)}},[h]);return b.useEffect(()=>{K.fetchAll().then(v=>{v&&h(v)});const g=K.subscribe(h),y=K.onConnectionChange(p);return K.connect(),()=>{g(),y(),K.disconnect()}},[h,p]),i.jsxs(TB,{connected:n,lastUpdated:a,onRefresh:m,refreshing:o,children:[d&&i.jsx("div",{style:{display:u?void 0:"none"},children:i.jsx(gbe,{})}),i.jsx("div",{style:{display:u?"none":void 0},children:i.jsxs(G2,{children:[i.jsx(Ge,{path:"/",element:i.jsx(iS,{to:"/overview",replace:!0})}),i.jsx(Ge,{path:"/overview",element:i.jsx(use,{data:e,onRefresh:m,refreshing:o})}),i.jsx(Ge,{path:"/chat",element:null}),i.jsx(Ge,{path:"/dag",element:i.jsx(wse,{data:e})}),i.jsx(Ge,{path:"/costs",element:i.jsx(kse,{data:e})}),i.jsx(Ge,{path:"/benchmarks",element:i.jsx(jse,{data:e})}),i.jsx(Ge,{path:"/models",element:i.jsx(moe,{})}),i.jsx(Ge,{path:"/models/timeline",element:i.jsx(Tbe,{})}),i.jsx(Ge,{path:"/routing",element:i.jsx(Xoe,{data:e})}),i.jsx(Ge,{path:"/requests",element:i.jsx(nle,{data:e})}),i.jsx(Ge,{path:"/traces",element:i.jsx(ple,{})}),i.jsx(Ge,{path:"/hub",element:i.jsx(Rle,{})}),i.jsx(Ge,{path:"/capabilities",element:i.jsx(Qbe,{})}),i.jsx(Ge,{path:"/tasks",element:i.jsx(Fle,{})}),i.jsx(Ge,{path:"/evals",element:i.jsx(wbe,{data:e})}),i.jsx(Ge,{path:"/platforms",element:i.jsx(jbe,{})}),i.jsx(Ge,{path:"/mcp",element:i.jsx(rxe,{})}),i.jsx(Ge,{path:"/bedrock",element:i.jsx(Ebe,{canWrite:!0,sessionExpired:g=>console.error(g)})}),i.jsx(Ge,{path:"/contacts",element:i.jsx(_be,{})}),i.jsx(Ge,{path:"/gateway",element:i.jsx(Sbe,{})}),i.jsx(Ge,{path:"/env",element:i.jsx(Ube,{})}),i.jsx(Ge,{path:"/process-env",element:i.jsx(Gbe,{})}),i.jsx(Ge,{path:"/hooks",element:i.jsx(Vbe,{})}),i.jsx(Ge,{path:"/memory",element:i.jsx(Rbe,{data:e})}),i.jsx(Ge,{path:"/knowledge",element:i.jsx(Mbe,{})}),i.jsx(Ge,{path:"/history",element:i.jsx(Lbe,{data:e})}),i.jsx(Ge,{path:"/decisions",element:i.jsx(Bbe,{})}),i.jsx(Ge,{path:"/executions",element:i.jsx(zbe,{onFetch:g=>K.fetchExecutionAudit(g)})}),i.jsx(Ge,{path:"/system",element:i.jsx(Ose,{data:e,connected:n,lastUpdated:a})}),i.jsx(Ge,{path:"/admin",element:i.jsx(xle,{})}),i.jsx(Ge,{path:"/help",element:i.jsx(dse,{})}),i.jsx(Ge,{path:"*",element:i.jsx(iS,{to:"/overview",replace:!0})})]})})]})}iw(LT());kT(document.getElementById("root")).render(i.jsx(b.StrictMode,{children:i.jsx(J2,{children:i.jsx(axe,{})})}));
236
- //# sourceMappingURL=index-V0rIqVbg.js.map
236
+ //# sourceMappingURL=index-CGYIlLpO.js.map