@polderlabs/bizar 5.4.0 → 5.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bizar-dash/dist/assets/{EnvVarsSection-DqvB8ZcJ.js → EnvVarsSection-L413CQEI.js} +3 -3
- package/bizar-dash/dist/assets/{EnvVarsSection-DqvB8ZcJ.js.map → EnvVarsSection-L413CQEI.js.map} +1 -1
- package/bizar-dash/dist/assets/{MobileChat-DRXP2ERQ.js → MobileChat-0kGQb1S6.js} +1 -1
- package/bizar-dash/dist/assets/{MobileChat-DRXP2ERQ.js.map → MobileChat-0kGQb1S6.js.map} +1 -1
- package/bizar-dash/dist/assets/MobileSettings-Cq1oFIdO.js +1 -0
- package/bizar-dash/dist/assets/{MobileSettings-CVW9VhEo.js.map → MobileSettings-Cq1oFIdO.js.map} +1 -1
- package/bizar-dash/dist/assets/{Toast-CcZVVN4i.js → Toast-C6f1zFJ2.js} +1 -1
- package/bizar-dash/dist/assets/{Toast-CcZVVN4i.js.map → Toast-C6f1zFJ2.js.map} +1 -1
- package/bizar-dash/dist/assets/{icons-OMEGx5KA.js → icons-BsWXWkEF.js} +121 -126
- package/bizar-dash/dist/assets/icons-BsWXWkEF.js.map +1 -0
- package/bizar-dash/dist/assets/main-BklYy02e.css +1 -0
- package/bizar-dash/dist/assets/main-CBTgYSeG.js +18 -0
- package/bizar-dash/dist/assets/main-CBTgYSeG.js.map +1 -0
- package/bizar-dash/dist/assets/mobile-CsaN4CxH.js +1 -0
- package/bizar-dash/dist/assets/{mobile-XN2P7YfM.js.map → mobile-CsaN4CxH.js.map} +1 -1
- package/bizar-dash/dist/assets/{mobile-layout-D6V-7WnA.css → mobile-layout-CJnZNLy3.css} +1 -1
- package/bizar-dash/dist/assets/mobile-layout-iFBdjEE4.js +2 -0
- package/bizar-dash/dist/assets/mobile-layout-iFBdjEE4.js.map +1 -0
- package/bizar-dash/dist/assets/{useSlashCommands-iyoW95UB.js → useSlashCommands-DGJcC9iQ.js} +2 -2
- package/bizar-dash/dist/assets/{useSlashCommands-iyoW95UB.js.map → useSlashCommands-DGJcC9iQ.js.map} +1 -1
- package/bizar-dash/dist/index.html +8 -8
- package/bizar-dash/dist/mobile.html +4 -4
- package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/bizar-dash/src/server/backup-store.mjs +6 -1
- package/bizar-dash/src/server/bg-spawner.mjs +574 -0
- package/bizar-dash/src/server/memory-lightrag.mjs +242 -0
- package/bizar-dash/src/server/memory-store.mjs +43 -3
- package/bizar-dash/src/server/routes/background.mjs +143 -0
- package/bizar-dash/src/server/routes/lightrag.mjs +10 -0
- package/bizar-dash/src/server/routes/memory.mjs +8 -0
- package/bizar-dash/src/server/server.mjs +22 -0
- package/bizar-dash/src/web/App.tsx +3 -0
- package/bizar-dash/src/web/MobileApp.tsx +1 -10
- package/bizar-dash/src/web/components/InstallConfirmDialog.tsx +1 -1
- package/bizar-dash/src/web/components/SettingsNav.tsx +1 -10
- package/bizar-dash/src/web/lib/types.ts +39 -1
- package/bizar-dash/src/web/styles/main.css +43 -0
- package/bizar-dash/src/web/styles/mobile-layout.css +7 -5
- package/bizar-dash/src/web/styles/settings.css +46 -0
- package/bizar-dash/src/web/views/BackgroundAgents.tsx +399 -30
- package/bizar-dash/src/web/views/Settings.tsx +12 -12
- package/bizar-dash/src/web/views/SpawnAgentModal.tsx +221 -0
- package/bizar-dash/tests/BackgroundAgents.test.tsx +160 -0
- package/bizar-dash/tests/background-pause-resume.test.mjs +46 -0
- package/bizar-dash/tests/background-spawn-from-ui.test.mjs +36 -0
- package/bizar-dash/tests/background-steer.test.mjs +42 -0
- package/bizar-dash/tests/lightrag-startup-hook.test.mjs +206 -0
- package/bizar-dash/tests/memory-auto-reindex.test.mjs +196 -0
- package/bizar-dash/tests/memory-cli.test.mjs +1 -1
- package/bizar-dash/tests/memory-default-vault.test.mjs +90 -3
- package/bizar-dash/tests/memory-lightrag-extended.test.mjs +131 -0
- package/bizar-dash/tests/mobile-layout.test.tsx +36 -0
- package/bizar-dash/tests/settings-layout.test.tsx +3 -3
- package/bizar-dash/tests/settings-nav.test.tsx +7 -5
- package/cli/bin.mjs +16 -0
- package/cli/commands/deploy/docker.mjs +2 -1
- package/cli/commands/lightrag.mjs +171 -0
- package/cli/commands/service.mjs +7 -0
- package/cli/commands/util.mjs +8 -1
- package/cli/init.mjs +1 -1
- package/cli/post-install-smoke.mjs +230 -0
- package/cli/provision.mjs +177 -0
- package/cli/provision.test.mjs +180 -0
- package/cli/service-controller.mjs +378 -28
- package/cli/service-controller.test.mjs +100 -0
- package/cli/service-env.mjs +139 -0
- package/cli/service.mjs +23 -0
- package/config/agents/_shared/AGENT_BASELINE.md +6 -6
- package/install.sh +87 -6
- package/package.json +1 -1
- package/plugins/bizar/index.ts +147 -0
- package/plugins/bizar/src/background-state.ts +84 -5
- package/plugins/bizar/src/background.ts +388 -10
- package/plugins/bizar/src/hooks/memory-inject.ts +247 -0
- package/plugins/bizar/src/hooks/memory-write-on-end.ts +188 -0
- package/plugins/bizar/src/opencode-runner.ts +87 -1
- package/plugins/bizar/src/tools/bg-pause.ts +77 -0
- package/plugins/bizar/src/tools/bg-report-progress.ts +101 -0
- package/plugins/bizar/src/tools/bg-resume.ts +72 -0
- package/plugins/bizar/src/tools/bg-send-message.ts +105 -0
- package/plugins/bizar/src/tools/bg-spawn.ts +13 -6
- package/plugins/bizar/src/tools/bg-status.ts +10 -0
- package/plugins/bizar/src/tools/memory-list.ts +135 -0
- package/plugins/bizar/src/tools/memory-read.ts +142 -0
- package/plugins/bizar/src/tools/memory-search.ts +228 -0
- package/plugins/bizar/src/tools/memory-write.ts +183 -0
- package/plugins/bizar/tests/memory-write-on-end.test.ts +92 -0
- package/plugins/bizar/tests/tools/bg-pause.test.ts +64 -0
- package/plugins/bizar/tests/tools/bg-report-progress.test.ts +82 -0
- package/plugins/bizar/tests/tools/bg-resume.test.ts +43 -0
- package/plugins/bizar/tests/tools/bg-send-message.test.ts +46 -0
- package/bizar-dash/dist/assets/MobileSettings-CVW9VhEo.js +0 -1
- package/bizar-dash/dist/assets/icons-OMEGx5KA.js.map +0 -1
- package/bizar-dash/dist/assets/main-CMAGZouj.js +0 -16
- package/bizar-dash/dist/assets/main-CMAGZouj.js.map +0 -1
- package/bizar-dash/dist/assets/main-O2tZVdHm.css +0 -1
- package/bizar-dash/dist/assets/mobile-XN2P7YfM.js +0 -1
- package/bizar-dash/dist/assets/mobile-layout-DqTxvXZp.js +0 -2
- package/bizar-dash/dist/assets/mobile-layout-DqTxvXZp.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as c,j as e,R as ye}from"./react-vendor-Dn4wqh4Z.js";import{u as Y}from"./Toast-
|
|
2
|
-
`)})]}),n.status==="error"&&n.error&&e.jsxs("div",{className:"updates-pkg-error",children:[e.jsx(ie,{size:12})," ",n.error]})]},r.id)})}),e.jsxs("div",{className:"updates-actions",children:[e.jsxs(b,{onClick:d,disabled:x,children:[s.checking?e.jsx("span",{className:"btn-spinner"}):e.jsx(O,{size:14}),"Check for updates"]}),e.jsxs(b,{variant:"primary",onClick:i,disabled:!s.hasUpdates||s.updating,children:[s.updating?e.jsx("span",{className:"btn-spinner"}):e.jsx(G,{size:14}),s.updating?"Updating…":s.hasUpdates?"Update now":"Up to date"]}),s.requiresRestart&&e.jsxs(b,{variant:"danger",onClick:m,children:[e.jsx(O,{size:14})," Restart Dashboard"]})]}),s.error&&e.jsxs("div",{className:"updates-error",children:[e.jsx(ie,{size:14}),e.jsx("span",{children:s.error})]})]})}function _e(a,s,{delay:l=800,onSaved:d,onError:i}={}){const[m,x]=c.useState(a),[r,n]=c.useState("idle"),u=c.useRef(null),g=c.useRef(null),j=c.useRef(a),y=c.useRef(!1),C=c.useCallback(async p=>{n("saving");try{await s(p),j.current=p,g.current=null,n("saved"),d==null||d(),setTimeout(()=>n("idle"),2e3)}catch(v){n("error"),i==null||i(v)}},[s,d,i]),L=c.useCallback(p=>{x(p),g.current=p,y.current=!0,u.current&&clearTimeout(u.current),u.current=setTimeout(()=>{u.current=null,y.current=!1;const v=g.current;g.current=null,v!==null&&C(v)},l)},[l,C]),S=c.useCallback(()=>{u.current&&(clearTimeout(u.current),u.current=null,y.current=!1)},[]),h=c.useCallback(async()=>{if(u.current){clearTimeout(u.current),u.current=null,y.current=!1;const p=g.current;g.current=null,p!==null&&await C(p)}},[C]);return c.useEffect(()=>()=>{if(u.current){clearTimeout(u.current),u.current=null;const p=g.current;g.current=null,p!==null&&(n("saving"),s(p).then(()=>{j.current=p,n("saved"),d==null||d()}).catch(v=>{n("error"),i==null||i(v)}).finally(()=>{setTimeout(()=>n("idle"),2e3)}))}},[s,d,i]),{value:m,setValue:L,status:r,save:C,flush:h,clearDebounce:S,hasPendingDebounceRef:y,pendingValueRef:g}}function de({initialValue:a,saveFn:s,delay:l=800,render:d,className:i}){const{value:m,setValue:x,status:r,save:n,clearDebounce:u,hasPendingDebounceRef:g,pendingValueRef:j}=_e(a,s,{delay:l}),y=ye.useCallback(()=>{g.current&&(u(),j.current!==null&&n(j.current))},[u,g,n,j]);return e.jsxs("div",{className:`autosave-field ${i||""} ${r}`,children:[d({value:m,onChange:x,onBlur:y}),e.jsxs("span",{className:"autosave-status",role:"status","aria-live":"polite",children:[r==="saving"&&e.jsx(we,{className:"spinning",size:12}),r==="saved"&&e.jsx(Ne,{size:12}),r==="error"&&e.jsx(pe,{size:12})]})]})}const He=[{id:"topnav",label:"Top nav"},{id:"sidebar",label:"Sidebar"},{id:"both",label:"Both"}];function Je({settings:a,patchUi:s,patchTop:l,autoSave:d}){return e.jsxs(e.Fragment,{children:[e.jsxs(E,{id:"settings-layout","data-section":"layout",children:[e.jsxs($,{children:[e.jsx(Se,{size:14})," UI layout"]}),e.jsx(B,{children:"Choose how the dashboard's navigation is presented."}),e.jsx("div",{className:"layout-row","data-setting-id":"ui.layout",children:He.map(i=>e.jsx("button",{type:"button",className:P("layout-card",a.ui.layout===i.id&&"layout-card-active"),onClick:()=>s({layout:i.id}),children:e.jsx("span",{className:"layout-card-label",children:i.label})},i.id))}),e.jsxs("label",{className:"checkbox-row","data-setting-id":"ui.showHeader",children:[e.jsx("input",{type:"checkbox",checked:a.ui.showHeader,onChange:i=>s({showHeader:i.target.checked})}),e.jsx("span",{children:"Show header"})]}),e.jsxs("label",{className:"checkbox-row","data-setting-id":"ui.showStatusBar",children:[e.jsx("input",{type:"checkbox",checked:a.ui.showStatusBar,onChange:i=>s({showStatusBar:i.target.checked})}),e.jsx("span",{children:"Show status bar"})]}),e.jsxs("div",{className:"field","data-setting-id":"ui.defaultTab",children:[e.jsx("label",{className:"field-label",children:"Default tab"}),e.jsxs("select",{className:"select",value:a.ui.defaultTab,onChange:i=>s({defaultTab:i.target.value}),children:[e.jsx("option",{value:"overview",children:"Overview"}),e.jsx("option",{value:"chat",children:"Chat"}),e.jsx("option",{value:"agents",children:"Agents"}),e.jsx("option",{value:"artifacts",children:"Plans"}),e.jsx("option",{value:"projects",children:"Projects"}),e.jsx("option",{value:"tasks",children:"Tasks"}),e.jsx("option",{value:"config",children:"Config"}),e.jsx("option",{value:"settings",children:"Settings"}),e.jsx("option",{value:"mods",children:"Mods"}),e.jsx("option",{value:"schedules",children:"Schedules"})]})]})]}),e.jsxs(E,{id:"settings-general","data-section":"general",children:[e.jsx($,{children:"General"}),e.jsx(B,{children:"Default agent + model override."}),e.jsxs("div",{className:"field","data-setting-id":"defaultAgent",children:[e.jsx("label",{className:"field-label",htmlFor:"set-default-agent",children:"Default agent"}),e.jsx(de,{initialValue:a.defaultAgent||"",saveFn:async i=>{l("defaultAgent",i),d==null||d("defaultAgent",i)},render:({value:i,onChange:m,onBlur:x})=>e.jsx("input",{id:"set-default-agent",className:"input",type:"text",placeholder:"e.g. odin",value:i,onChange:r=>m(r.target.value),onBlur:x})})]}),e.jsxs("div",{className:"field","data-setting-id":"defaultModel",children:[e.jsx("label",{className:"field-label",htmlFor:"set-default-model",children:"Model override"}),e.jsx(de,{initialValue:a.defaultModel||"",saveFn:async i=>{l("defaultModel",i),d==null||d("defaultModel",i)},render:({value:i,onChange:m,onBlur:x})=>e.jsx("input",{id:"set-default-model",className:"input",type:"text",placeholder:"(leave empty for provider default)",value:i,onChange:r=>m(r.target.value),onBlur:x})})]})]})]})}function es({initialStatus:a}){var p;const[s,l]=c.useState(a??null),[d,i]=c.useState(""),[m,x]=c.useState(!1),[r,n]=c.useState(null);c.useEffect(()=>{s===null&&k.get("/tailscale/status").then(v=>l(v)).catch(()=>l(null))},[]);const u=async()=>{try{const v=await k.get("/tailscale/status");l(v)}catch{n("Failed to load Tailscale status")}},g=async()=>{if(d.trim()){x(!0),n(null);try{await k.post("/tailscale/setup",{authKey:d.trim()}),await u(),i("")}catch(v){n(v.message||"Authentication failed")}finally{x(!1)}}},j=async()=>{var v,w,z;if(s){x(!0),n(null);try{await k.post("/tailscale/setup",{port:((v=s.settings)==null?void 0:v.port)||4321,https:((w=s.settings)==null?void 0:w.https)!==!1,hostname:((z=s.settings)==null?void 0:z.hostname)||""}),await u()}catch(T){n(T.message||"Setup failed")}finally{x(!1)}}},y=async()=>{x(!0),n(null);try{await k.post("/tailscale/unserve"),await u()}catch(v){n(v.message||"Remove failed")}finally{x(!1)}},C=(s==null?void 0:s.installed)??!1,L=(s==null?void 0:s.authenticated)??!1,S=((p=s==null?void 0:s.settings)==null?void 0:p.enabled)??!1,h=S?`https://${(s==null?void 0:s.hostname)||"bizar-dash"}`:null;return C?e.jsxs(E,{id:"settings-tailscale-auth","data-section":"tailscale",children:[e.jsxs($,{children:[e.jsx(ce,{size:14})," Tailscale Integration"]}),e.jsx(B,{children:"Expose the dashboard over your Tailscale network using an auth key."}),r&&e.jsx("p",{style:{color:"var(--color-error, #f85149)",fontSize:"0.85rem"},children:r}),L?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"status-row",style:{display:"flex",alignItems:"center",gap:"0.5rem",marginBottom:"0.75rem"},children:[e.jsx(V,{size:16,style:{color:"var(--color-success, #3fb950)"}}),e.jsxs("span",{children:["Authenticated as ",e.jsx("strong",{children:(s==null?void 0:s.hostname)||"unknown"})]})]}),S&&h?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"status-row",style:{display:"flex",alignItems:"center",gap:"0.5rem",marginBottom:"0.75rem"},children:[e.jsx(Ce,{size:16}),e.jsx("a",{href:h,target:"_blank",rel:"noreferrer",children:h})]}),e.jsx(b,{variant:"secondary",size:"sm",onClick:y,disabled:m,children:"Remove serve"})]}):e.jsx(b,{variant:"primary",size:"sm",onClick:j,disabled:m,children:"Set up Tailscale serve"})]}):e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"muted",style:{marginBottom:"0.75rem"},children:"Not authenticated with Tailscale."}),e.jsxs("div",{style:{display:"flex",gap:"0.5rem",flexWrap:"wrap"},children:[e.jsx("input",{type:"text",className:"input",placeholder:"tskey-...",value:d,onChange:v=>i(v.target.value),style:{flex:1,minWidth:"200px"},disabled:m}),e.jsx(b,{variant:"primary",size:"sm",onClick:g,disabled:m||!d.trim(),children:"Authenticate"})]})]})]}):e.jsxs(E,{id:"settings-tailscale-auth","data-section":"tailscale",children:[e.jsxs($,{children:[e.jsx(ce,{size:14})," Tailscale Integration"]}),e.jsx(B,{children:"Tailscale is not installed on this machine."}),e.jsxs("p",{className:"muted",children:["Install from"," ",e.jsx("a",{href:"https://tailscale.com/download",target:"_blank",rel:"noreferrer",children:"tailscale.com/download"})]})]})}function ss({settings:a,patchTop:s}){var l,d,i;return e.jsxs(E,{id:"settings-system-llm","data-section":"system-llm",children:[e.jsxs($,{children:[e.jsx(ze,{size:14})," System LLM API"]}),e.jsx(B,{children:"Configures the LLM used for automatic title generation, prompt enhancement, summarization, and other system-level calls."}),e.jsxs("label",{className:"checkbox-row","data-setting-id":"systemLlm.enabled",children:[e.jsx("input",{type:"checkbox",checked:!!((l=a.systemLlm)!=null&&l.enabled),onChange:m=>{const x=a.systemLlm||{enabled:!0,provider:"opencode",model:"opencode/deepseek-v4-flash-free"};s("systemLlm",{...x,enabled:m.target.checked})}}),e.jsx("span",{children:"Enable system LLM calls"})]}),e.jsxs("div",{className:"field","data-setting-id":"systemLlm.provider",style:{marginTop:"var(--space-3)"},children:[e.jsx("label",{className:"field-label",htmlFor:"set-system-llm-provider",children:"Provider"}),e.jsxs("select",{id:"set-system-llm-provider",className:"select",value:((d=a.systemLlm)==null?void 0:d.provider)||"opencode",onChange:m=>{const x=a.systemLlm||{enabled:!0,provider:"opencode",model:"opencode/deepseek-v4-flash-free"};s("systemLlm",{...x,provider:m.target.value})},children:[e.jsx("option",{value:"opencode",children:"Opencode"}),e.jsx("option",{value:"openrouter",children:"OpenRouter"}),e.jsx("option",{value:"minimax",children:"MiniMax"})]})]}),e.jsxs("div",{className:"field","data-setting-id":"systemLlm.model",children:[e.jsx("label",{className:"field-label",htmlFor:"set-system-llm-model",children:"Model"}),e.jsx("input",{id:"set-system-llm-model",className:"input mono",type:"text",placeholder:"opencode/deepseek-v4-flash-free",value:((i=a.systemLlm)==null?void 0:i.model)||"opencode/deepseek-v4-flash-free",onChange:m=>{const x=a.systemLlm||{enabled:!0,provider:"opencode",model:"opencode/deepseek-v4-flash-free"};s("systemLlm",{...x,model:m.target.value})}}),e.jsxs("p",{className:"field-help",children:["The API key is read from ",e.jsx("code",{children:"auth.json"})," for the selected provider. Leave the default model for best results."]})]}),e.jsxs("div",{style:{marginTop:"var(--space-4)"},children:[e.jsx("h4",{style:{margin:"0 0 var(--space-2)"},children:"Features using this API"}),e.jsxs("ul",{className:"settings-feature-list",style:{margin:0,paddingLeft:"var(--space-4)",lineHeight:1.8},children:[e.jsx("li",{children:"Auto-title generation for new chat sessions"}),e.jsx("li",{children:"Auto-title generation for new tasks"}),e.jsx("li",{children:'"Enhance prompt" button in the task input'}),e.jsx("li",{children:'"Enhance prompt" button in the chat composer'}),e.jsx("li",{className:"muted",style:{fontSize:12},children:"Future: summarization, name generation, and more"})]})]})]})}const Ve=[{value:"anthropic",label:"Anthropic"},{value:"anyllm",label:"AnyLLM"},{value:"litellm-anthropic",label:"LiteLLM (Anthropic)"},{value:"litellm-openai",label:"LiteLLM (OpenAI)"}];function Oe({settings:a,onPatch:s}){const l=Y(),[d,i]=c.useState(null),[m,x]=c.useState(null),[r,n]=c.useState(!1),[u,g]=c.useState(!1),[j,y]=c.useState(!1),[C,L]=c.useState(!1),[S,h]=c.useState(!1),[p,v]=c.useState(!1),w=c.useCallback(async()=>{n(!0);try{const[o,U]=await Promise.all([k.get("/headroom/status"),k.get("/headroom/stats?hours=24").catch(()=>({error:"no stats"}))]);i(o),U.error||x(U)}catch(o){l.error(`Failed to load Headroom status: ${o.message}`)}finally{n(!1)}},[l]);c.useEffect(()=>{w()},[w]);const z=async()=>{g(!0);try{const o=await k.post("/headroom/install",{force:!0});o.installed?(l.success(`Headroom installed via ${o.method}.`),await w()):l.error('Headroom install failed. Try: pip install "headroom-ai[all]"')}catch(o){l.error(`Install failed: ${o.message}`)}finally{g(!1)}},T=async()=>{y(!0);try{(await k.post("/headroom/wrap",{port:a.port})).ok?(l.success("opencode wrapped with Headroom."),await w()):l.error("Wrap failed.")}catch(o){l.error(`Wrap failed: ${o.message}`)}finally{y(!1)}},_=async()=>{L(!0);try{(await k.post("/headroom/unwrap")).ok?(l.success("opencode unwrapped from Headroom."),await w()):l.error("Unwrap failed.")}catch(o){l.error(`Unwrap failed: ${o.message}`)}finally{L(!1)}},W=async()=>{h(!0);try{(await k.post("/headroom/proxy/start",{port:a.port,host:a.host})).ok?(l.success(`Headroom proxy started on ${a.host}:${a.port}.`),await w()):l.error("Proxy start failed.")}catch(o){l.error(`Proxy start failed: ${o.message}`)}finally{h(!1)}},K=async()=>{v(!0);try{(await k.post("/headroom/proxy/stop")).ok?(l.success("Headroom proxy stopped."),await w()):l.error("Proxy stop failed.")}catch(o){l.error(`Proxy stop failed: ${o.message}`)}finally{v(!1)}},Z=async()=>{try{const{spawn:o}=await ke(async()=>{const{spawn:U}=await import("./__vite-browser-external-BIHI7g3E.js");return{spawn:U}},[]);o("headroom",["dashboard"],{detached:!0,stdio:"ignore"})}catch{l.error("Could not open Headroom dashboard. Run `headroom dashboard` manually.")}},{installed:R,version:q,proxyRunning:M,proxyPort:X,wrapped:A}=d||{},H=(m==null?void 0:m.compressionRatio)??0,D=(m==null?void 0:m.tokensSaved)??0;return e.jsx("div",{id:"settings-headroom","data-section":"headroom",children:e.jsxs(E,{children:[e.jsxs($,{children:[e.jsx(me,{size:14,style:{color:M?"var(--success)":"var(--text-dim)"}}),"Headroom",R&&q&&e.jsxs("span",{style:{fontSize:11,color:"var(--text-dim)",marginLeft:6},children:["v",q," ",M?"✓":"✗"]}),!R&&e.jsx("span",{style:{fontSize:11,color:"var(--error)",marginLeft:6},children:"not installed"})]}),e.jsx(B,{children:"Context compression for token efficiency. Compresses tool outputs, logs, and conversation history by 60–95% before they reach the model."}),e.jsxs("div",{style:{display:"flex",gap:16,flexWrap:"wrap",marginTop:12,marginBottom:12},children:[e.jsxs("div",{className:"headroom-status-item",children:[R?e.jsx(V,{size:12,style:{color:"var(--success)"}}):e.jsx(se,{size:12,style:{color:"var(--error)"}}),e.jsx("span",{children:R?"Installed":"Not installed"})]}),e.jsxs("div",{className:"headroom-status-item",children:[M?e.jsx(V,{size:12,style:{color:"var(--success)"}}):e.jsx(se,{size:12,style:{color:"var(--text-dim)"}}),e.jsxs("span",{children:["Proxy ",M?`${X} ✓`:"stopped"]})]}),e.jsxs("div",{className:"headroom-status-item",children:[A?e.jsx(V,{size:12,style:{color:"var(--success)"}}):e.jsx(se,{size:12,style:{color:"var(--text-dim)"}}),e.jsxs("span",{children:["opencode ",A?"wrapped":"not wrapped"]})]})]}),(D>0||H>0)&&e.jsxs("div",{style:{display:"flex",gap:24,marginBottom:12},children:[e.jsxs("div",{children:[e.jsx("div",{style:{fontSize:20,fontWeight:700,color:"var(--success)"},children:H>0?`${Math.round(H*100)}%`:"—"}),e.jsx("div",{className:"muted",style:{fontSize:11},children:"Compression ratio"})]}),e.jsxs("div",{children:[e.jsx("div",{style:{fontSize:20,fontWeight:700,color:"var(--accent)"},children:D>0?D.toLocaleString():"—"}),e.jsx("div",{className:"muted",style:{fontSize:11},children:"Tokens saved (24h)"})]})]}),e.jsxs("div",{style:{display:"flex",gap:8,flexWrap:"wrap",marginBottom:8},children:[R?e.jsxs(e.Fragment,{children:[e.jsxs(b,{variant:"secondary",size:"sm",onClick:T,disabled:j||A,title:A?"opencode is already wrapped":"Wrap opencode to route through Headroom proxy",children:[j?e.jsx("span",{className:"btn-spinner"}):e.jsx(Ae,{size:13}),j?"Wrapping…":A?"Wrapped ✓":"Wrap opencode"]}),A&&e.jsxs(b,{variant:"ghost",size:"sm",onClick:_,disabled:C,children:[C?e.jsx("span",{className:"btn-spinner"}):e.jsx(O,{size:13}),C?"Unwrapping…":"Unwrap"]})]}):e.jsxs(b,{variant:"primary",size:"sm",onClick:z,disabled:u,children:[u?e.jsx("span",{className:"btn-spinner"}):e.jsx(G,{size:13}),u?"Installing…":"Install Headroom"]}),R&&e.jsxs(e.Fragment,{children:[M?e.jsxs(b,{variant:"secondary",size:"sm",onClick:K,disabled:p,children:[p?e.jsx("span",{className:"btn-spinner"}):e.jsx(Re,{size:13}),p?"Stopping…":"Stop proxy"]}):e.jsxs(b,{variant:"secondary",size:"sm",onClick:W,disabled:S,children:[S?e.jsx("span",{className:"btn-spinner"}):e.jsx(Le,{size:13}),S?"Starting…":"Start proxy"]}),e.jsxs(b,{variant:"ghost",size:"sm",onClick:Z,children:[e.jsx(Ie,{size:13}),"Dashboard"]})]}),e.jsx(b,{variant:"ghost",size:"sm",onClick:w,disabled:r,children:e.jsx(O,{size:13,className:r?"spin":""})})]}),e.jsxs("div",{style:{marginTop:16},children:[e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.enabled,onChange:o=>s({enabled:o.target.checked})}),e.jsx("span",{children:"Enable Headroom"})]}),e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.autoInstall,onChange:o=>s({autoInstall:o.target.checked})}),e.jsx("span",{children:"Auto-install if missing on dashboard startup"})]}),e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.autoStart,onChange:o=>s({autoStart:o.target.checked})}),e.jsx("span",{children:"Auto-start proxy on dashboard startup"})]}),e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.autoWrap,onChange:o=>s({autoWrap:o.target.checked})}),e.jsx("span",{children:"Auto-wrap opencode on dashboard startup"})]}),e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.routeAllProviders,onChange:o=>s({routeAllProviders:o.target.checked})}),e.jsx("span",{children:"Route all providers through Headroom proxy"})]}),e.jsxs("div",{className:"task-form-row",style:{marginTop:12},children:[e.jsxs("div",{className:"task-form-field",children:[e.jsx("label",{className:"field-label",children:"Proxy port"}),e.jsx("input",{type:"number",className:"input",value:a.port,min:1,max:65535,onChange:o=>s({port:Math.max(1,Math.min(65535,parseInt(o.target.value,10)||8787))})})]}),e.jsxs("div",{className:"task-form-field",children:[e.jsx("label",{className:"field-label",children:"Proxy host"}),e.jsx("input",{type:"text",className:"input",value:a.host,onChange:o=>s({host:o.target.value})})]})]}),e.jsxs("div",{className:"task-form-row",children:[e.jsxs("div",{className:"task-form-field",children:[e.jsx("label",{className:"field-label",children:"Backend"}),e.jsx("select",{className:"select",value:a.backend,onChange:o=>s({backend:o.target.value}),children:Ve.map(o=>e.jsx("option",{value:o.value,children:o.label},o.value))})]}),e.jsxs("div",{className:"task-form-field",children:[e.jsx("label",{className:"field-label",children:"Monthly budget (USD)"}),e.jsx("input",{type:"number",className:"input",value:a.budget,min:0,step:1,onChange:o=>s({budget:Math.max(0,parseFloat(o.target.value)||0)})}),e.jsx("span",{className:"field-help",children:"0 = unlimited"})]})]}),e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.outputShaper,onChange:o=>s({outputShaper:o.target.checked})}),e.jsx("span",{children:"Enable output shaper"})]}),e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.telemetry,onChange:o=>s({telemetry:o.target.checked})}),e.jsx("span",{children:"Enable telemetry"})]})]})]})})}const ue={enabled:!0,autoInstall:!0,port:8787,host:"127.0.0.1",outputShaper:!1,telemetry:!1,budget:0,backend:"anthropic",autoStart:!0,autoWrap:!0,routeAllProviders:!0};function as({settings:a,setSettings:s,setDirty:l}){return e.jsx(Oe,{settings:a.headroom||ue,onPatch:d=>{s(i=>({...i,headroom:{...i.headroom||ue,...d}})),l(!0)}})}function Fe(){const a=Y(),[s,l]=c.useState([]),[d,i]=c.useState(new Set),[m,x]=c.useState(!0),[r,n]=c.useState(""),[u,g]=c.useState(!0),j=c.useCallback(async()=>{x(!0);try{const[h,p]=await Promise.all([k.get("/activity"),k.get("/activity/hidden")]);l(Array.isArray(h.items)?h.items:[]),i(new Set(p.hidden||[]))}catch(h){a.error(`Load failed: ${h.message}`)}finally{x(!1)}},[a]);c.useEffect(()=>{j()},[j]);const y=(h,p)=>{const v=`${h.kind||""}|${h.ts||""}|${h.slug||""}|${p}`;let w=0;for(let z=0;z<v.length;z++)w=(w<<5)-w+v.charCodeAt(z)|0;return Math.abs(w).toString(16).padStart(8,"0").slice(0,16)},C=async()=>{try{await k.del("/activity/hide"),i(new Set),a.success("All hidden activity restored.")}catch(h){a.error(`Restore failed: ${h.message}`)}},L=async h=>{try{await k.del(`/activity/hide/${encodeURIComponent(h)}`);const p=new Set(d);p.delete(h),i(p)}catch(p){a.error(`Restore failed: ${p.message}`)}},S=s.filter((h,p)=>{const v=y(h,p);if(!u&&d.has(v))return!1;if(!r)return!0;const w=r.toLowerCase();return[h.kind,h.slug,h.message].some(z=>typeof z=="string"&&z.toLowerCase().includes(w))});return e.jsxs(E,{id:"settings-activity-log","data-section":"activity-log",children:[e.jsxs($,{children:[e.jsx(me,{size:14})," Activity log",e.jsxs("span",{className:"muted",style:{fontWeight:400,marginLeft:8,fontSize:12},children:[s.length," total · ",d.size," hidden"]}),e.jsx(b,{variant:"ghost",size:"sm",style:{marginLeft:"auto"},onClick:j,title:"Reload",children:e.jsx(O,{size:12})})]}),e.jsxs(B,{children:["Full history from ",e.jsx("code",{children:"~/.bizar/activity.log"}),". Hiding an item in the Overview only hides it there — the entry stays here."]}),e.jsxs("div",{className:"activity-log-toolbar",children:[e.jsxs("div",{className:"activity-log-search",children:[e.jsx(te,{size:12}),e.jsx("input",{type:"text",className:"input",placeholder:"Filter by kind, slug, or message…",value:r,onChange:h=>n(h.target.value)})]}),e.jsxs("label",{className:"activity-log-toggle",children:[e.jsx("input",{type:"checkbox",checked:u,onChange:h=>g(h.target.checked)}),"Show hidden"]}),e.jsxs(b,{variant:"ghost",size:"sm",disabled:d.size===0,onClick:C,title:"Restore all hidden items to the Overview",children:[e.jsx(ne,{size:12})," Restore all"]})]}),m?e.jsx("div",{className:"muted",style:{padding:"12px 0",fontSize:12},children:"Loading…"}):S.length===0?e.jsx("div",{className:"muted",style:{padding:"12px 0",fontSize:12},children:s.length===0?"No activity yet.":"No items match the current filter."}):e.jsxs("div",{className:"activity-log-table-wrap",children:[e.jsxs("table",{className:"activity-log-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Kind"}),e.jsx("th",{children:"Detail"}),e.jsx("th",{children:"Time"}),e.jsx("th",{})]})}),e.jsx("tbody",{children:S.slice(0,200).map((h,p)=>{const v=y(h,p),w=d.has(v);return e.jsxs("tr",{className:P(w&&"activity-log-row-hidden"),children:[e.jsx("td",{className:"activity-log-kind",children:h.kind||"activity"}),e.jsx("td",{className:"activity-log-detail",children:h.message||h.slug||"—"}),e.jsx("td",{className:"activity-log-time mono",children:h.ts?new Date(h.ts).toLocaleString():"—"}),e.jsx("td",{children:w?e.jsx(b,{variant:"ghost",size:"sm",onClick:()=>L(v),title:"Restore to Overview",children:e.jsx(ne,{size:12})}):e.jsx("span",{className:"activity-log-state-tag",children:"shown"})})]},`${h.ts}-${p}`)})})]}),S.length>200&&e.jsxs("div",{className:"muted",style:{fontSize:11,padding:"8px 0"},children:["Showing first 200 of ",S.length,"."]})]})]})}function We({about:a}){return e.jsxs(E,{id:"settings-about","data-section":"about",children:[e.jsxs($,{children:[e.jsx(Ee,{size:14})," About"]}),e.jsx(B,{children:"Build metadata."}),e.jsxs("dl",{className:"about-table",children:[e.jsx("dt",{children:"Version"}),e.jsx("dd",{className:"mono",children:(a==null?void 0:a.version)||"—"}),e.jsx("dt",{children:"Homepage"}),e.jsx("dd",{children:e.jsx("a",{href:(a==null?void 0:a.homepage)||"https://github.com/DrB0rk/BizarHarness",target:"_blank",rel:"noopener noreferrer",children:(a==null?void 0:a.homepage)||"https://github.com/DrB0rk/BizarHarness"})}),e.jsx("dt",{children:"License"}),e.jsx("dd",{children:(a==null?void 0:a.license)||"MIT"})]})]})}function ts({about:a}){return e.jsxs(e.Fragment,{children:[e.jsx(Fe,{}),e.jsx(We,{about:a})]})}function Ke({onError:a}){const s=Y(),[l,d]=c.useState([]),[i,m]=c.useState(!1),[x,r]=c.useState(!1),[n,u]=c.useState(new Set),[g,j]=c.useState(null),[y,C]=c.useState(""),[L,S]=c.useState(!1),[h,p]=c.useState(""),[v,w]=c.useState(""),[z,T]=c.useState(!1),[_,W]=c.useState(""),[K,Z]=c.useState(!1),[R,q]=c.useState(""),[M,X]=c.useState(new Set),A=c.useCallback(async()=>{m(!0);try{const t=await k.get("/env-vars");d(t)}catch(t){s.error(`Load failed: ${t.message}`),a==null||a(t.message)}finally{m(!1)}},[s,a]);c.useEffect(()=>{A()},[A]);const H=t=>{u(N=>{const f=new Set(N);return f.has(t)?f.delete(t):f.add(t),f})},D=async()=>{const t=h.trim().toUpperCase(),N=v.trim();if(!t||!/^BIZAR_[A-Z0-9_]+$/.test(t)){s.warning("Name must match BIZAR_<NAME> (e.g. BIZAR_MINIMAX_KEY)");return}if(!N){s.warning("Value is required.");return}if(l.some(f=>f.name===t)){s.warning(`${t} already exists.`);return}r(!0);try{await k.post("/env-vars",{name:t,value:N}),s.success(`${t} created.`),S(!1),p(""),w(""),await A()}catch(f){s.error(`Create failed: ${f.message}`)}finally{r(!1)}},o=t=>{j(t.name),C(t.value===t.value.replace(/\*/g,"")?t.value:""),u(N=>{const f=new Set(N);return f.add(t.name),f})},U=async t=>{if(!y.trim()){s.warning("Value cannot be empty.");return}r(!0);try{await k.put(`/env-vars/${encodeURIComponent(t)}`,{value:y.trim()}),s.success(`${t} updated.`),j(null),await A()}catch(N){s.error(`Update failed: ${N.message}`)}finally{r(!1)}},re=async t=>{if(confirm(`Delete ${t}? This cannot be undone.`))try{await k.del(`/env-vars/${encodeURIComponent(t)}`),s.success(`${t} deleted.`),await A()}catch(N){s.error(`Delete failed: ${N.message}`)}},ge=async()=>{if(!_.trim()){s.warning("Nothing to import.");return}Z(!0);try{const t=await k.post("/env-vars/bulk-import",{envContent:_});s.success(`Imported ${t.imported}, skipped ${t.skipped}.`),t.errors.length>0&&s.warning(`${t.errors.length} lines had errors: ${t.errors.slice(0,3).join("; ")}${t.errors.length>3?"…":""}`),W(""),T(!1),await A()}catch(t){s.error(`Bulk import failed: ${t.message}`)}finally{Z(!1)}},je=async()=>{try{const t=await k.get("/env-vars/export"),N=new Blob([t],{type:"text/plain"}),f=URL.createObjectURL(N),I=document.createElement("a");I.href=f,I.download=".env",I.click(),URL.revokeObjectURL(f),s.success("Exported .env file.")}catch(t){s.error(`Export failed: ${t.message}`)}},F=c.useMemo(()=>{if(!R.trim())return l;const t=R.toLowerCase();return l.filter(N=>N.name.toLowerCase().includes(t))},[l,R]),Q=c.useMemo(()=>{const t={};for(const N of F){const f=N.name.split("_")[0]+"_";(t[f]??(t[f]=[])).push(N)}return t},[F]),ve=t=>{X(N=>{const f=new Set(N);return f.has(t)?f.delete(t):f.add(t),f})},le=c.useMemo(()=>{const t=["BIZAR_","PROVIDER_","MODEL_","API_"];return Object.keys(Q).sort((f,I)=>{const J=t.indexOf(f),ee=t.indexOf(I);return J===-1&&ee===-1?f.localeCompare(I):J===-1?1:ee===-1?-1:J-ee})},[Q]);if(i)return e.jsx("div",{className:"muted",style:{padding:"16px 0",fontSize:13},children:"Loading env vars…"});const fe=le.length>1;return e.jsxs("div",{className:"env-var-manager",children:[e.jsxs("div",{className:"env-var-toolbar",children:[e.jsxs(b,{variant:"primary",size:"sm",onClick:()=>S(!0),children:[e.jsx($e,{size:12})," New variable"]}),e.jsxs(b,{variant:"secondary",size:"sm",onClick:()=>T(t=>!t),className:z?"active":"",children:[e.jsx(Be,{size:12})," Bulk import"]}),e.jsxs(b,{variant:"ghost",size:"sm",onClick:je,title:"Export as .env",children:[e.jsx(G,{size:12})," Export"]}),e.jsxs("div",{className:"env-var-search-wrap",children:[e.jsx(te,{size:12,className:"env-var-search-icon"}),e.jsx("input",{className:"env-var-search input",placeholder:"Filter…",value:R,onChange:t=>q(t.target.value)})]}),e.jsx(b,{variant:"ghost",size:"sm",onClick:A,title:"Reload",children:e.jsx(O,{size:12})})]}),z&&e.jsxs("div",{className:"env-var-bulk-panel",children:[e.jsxs("div",{className:"env-var-bulk-header",children:[e.jsxs("span",{children:["Paste ",e.jsx("code",{children:"KEY=value"})," lines (one per line):"]}),e.jsx(b,{variant:"ghost",size:"sm",onClick:()=>T(!1),children:e.jsx(oe,{size:12})})]}),e.jsx("textarea",{className:"input mono env-var-bulk-textarea",placeholder:`BIZAR_API_KEY=your-key-here
|
|
1
|
+
import{r as c,j as e,R as ye}from"./react-vendor-Dn4wqh4Z.js";import{u as Y}from"./Toast-C6f1zFJ2.js";import{c as $,W as be,a as k,_ as ke}from"./mobile-layout-iFBdjEE4.js";import{a4 as G,bd as V,C as pe,z as ie,R as O,be as we,y as Ne,bf as Se,ay as ce,bg as Ce,i as ze,g as me,ad as se,Z as Ae,b0 as Re,a9 as Le,E as Ie,r as te,Q as ne,I as Ee,t as Pe,aX as Te,X as oe,aA as xe,e as $e,d as Be,U as Me,a3 as De,W as Ue}from"./icons-BsWXWkEF.js";const b=c.forwardRef(function({variant:s="secondary",size:l="md",iconOnly:d=!1,loading:i=!1,disabled:m,className:x,children:r,...n},u){return e.jsxs("button",{ref:u,type:n.type??"button",disabled:m||i,className:$("btn",`btn-${s}`,`btn-size-${l}`,d&&"btn-icon",i&&"btn-loading",x),...n,children:[i?e.jsx("span",{className:"btn-spinner","aria-hidden":!0}):null,r]})});function E({variant:a="elevated",interactive:s=!1,className:l,children:d,...i}){return e.jsx("div",{className:$("card",`card-${a}`,s&&"card-interactive",l),...i,children:d})}function P({children:a,className:s}){return e.jsx("h3",{className:$("card-title",s),children:a})}function T({children:a,className:s}){return e.jsx("div",{className:$("card-meta",s),children:a})}const ae=[{id:"bizar",name:"Bizar CLI"},{id:"bizar-dash",name:"Dashboard"},{id:"bizar-plugin",name:"Opencode Plugin"}];function Qe(){const a=Y(),[s,l]=c.useState({current:{},latest:null,checking:!1,updating:!1,hasUpdates:!1,requiresRestart:!1,perPackage:{}});c.useEffect(()=>{const r=new be;return r.on(n=>{(n.type==="update:progress"||n.type==="update:log"||n.type==="update:complete")&&l(u=>{if(n.type==="update:complete")return{...u,updating:!1,requiresRestart:!!n.requiresRestart};if(n.type==="update:log"){const j=n,y=u.perPackage[j.pkg]||{logs:[]};return{...u,perPackage:{...u.perPackage,[j.pkg]:{...y,logs:[...(y.logs||[]).slice(-50),j.line]}}}}const g=n;return{...u,perPackage:{...u.perPackage,[g.pkg]:{...u.perPackage[g.pkg],status:g.status,error:g.error,newVersion:g.newVersion}}}})}),()=>r.close()},[]),c.useEffect(()=>{k.get("/updates/status").then(r=>l(n=>({...n,current:r.current}))).catch(r=>l(n=>({...n,error:r.message})))},[]);const d=async()=>{l(r=>({...r,checking:!0,error:void 0}));try{const r=await k.get("/updates/check");l(n=>({...n,checking:!1,current:r.current,latest:r.latest,hasUpdates:r.hasUpdates}))}catch(r){l(n=>({...n,checking:!1,error:r.message}))}},i=async()=>{if(confirm("Update Bizar packages? The dashboard will restart automatically.")){l(r=>({...r,updating:!0,requiresRestart:!1,perPackage:{},error:void 0}));try{await k.post("/updates/apply",{packages:["bizar","bizar-dash","bizar-plugin"]})}catch(r){l(n=>({...n,updating:!1,error:r.message}))}}},m=async()=>{if(confirm("Restart the dashboard? You will be disconnected briefly."))try{await k.post("/restart"),a.info("Restarting…",3e3),setTimeout(()=>window.location.reload(),3e3)}catch{a.error("Restart failed")}},x=s.checking||s.updating;return e.jsxs(E,{id:"settings-updates","data-section":"updates",children:[e.jsxs(P,{children:[e.jsx(G,{size:14})," Updates"]}),e.jsx(T,{children:"Check installed Bizar packages and apply dashboard updates."}),e.jsxs("div",{className:"updates-current",children:[e.jsx("h4",{children:"Installed versions"}),e.jsx("ul",{children:ae.map(r=>e.jsxs("li",{children:[e.jsx("span",{children:r.name}),e.jsx("code",{className:"mono",children:s.current[r.id]||"—"})]},r.id))})]}),s.latest&&e.jsxs("div",{className:"updates-latest",children:[e.jsx("h4",{children:"Latest available"}),e.jsx("ul",{children:ae.map(r=>{var j;const n=s.current[r.id],u=(j=s.latest)==null?void 0:j[r.id],g=n&&u&&n!==u;return e.jsxs("li",{className:g?"updates-outdated":"updates-current-version",children:[e.jsx("span",{children:r.name}),e.jsxs("code",{className:"mono",children:[u||"—",g&&e.jsx("span",{className:"updates-badge",children:"update available"})]})]},r.id)})})]}),s.updating&&e.jsx("div",{className:"updates-progress-rows",children:ae.map(r=>{const n=s.perPackage[r.id]||{status:"idle",logs:[]};return e.jsxs("div",{className:"updates-pkg-row",children:[e.jsxs("div",{className:"updates-pkg-row-header",children:[e.jsx("span",{className:"updates-pkg-name",children:r.name}),e.jsxs("div",{className:"updates-pkg-status",children:[n.status==="starting"&&e.jsx("span",{className:"btn-spinner"}),n.status==="installing"&&e.jsx("span",{className:"btn-spinner"}),n.status==="done"&&e.jsx(V,{size:14,className:"icon-success"}),n.status==="error"&&e.jsx(pe,{size:14,className:"icon-error"}),e.jsx("span",{children:n.status}),n.newVersion&&e.jsxs("code",{className:"mono",style:{fontSize:11},children:["→ ",n.newVersion]})]})]}),n.logs.length>0&&e.jsxs("details",{className:"updates-pkg-logs",children:[e.jsxs("summary",{children:["npm output (",n.logs.length," lines)"]}),e.jsx("pre",{children:n.logs.join(`
|
|
2
|
+
`)})]}),n.status==="error"&&n.error&&e.jsxs("div",{className:"updates-pkg-error",children:[e.jsx(ie,{size:12})," ",n.error]})]},r.id)})}),e.jsxs("div",{className:"updates-actions",children:[e.jsxs(b,{onClick:d,disabled:x,children:[s.checking?e.jsx("span",{className:"btn-spinner"}):e.jsx(O,{size:14}),"Check for updates"]}),e.jsxs(b,{variant:"primary",onClick:i,disabled:!s.hasUpdates||s.updating,children:[s.updating?e.jsx("span",{className:"btn-spinner"}):e.jsx(G,{size:14}),s.updating?"Updating…":s.hasUpdates?"Update now":"Up to date"]}),s.requiresRestart&&e.jsxs(b,{variant:"danger",onClick:m,children:[e.jsx(O,{size:14})," Restart Dashboard"]})]}),s.error&&e.jsxs("div",{className:"updates-error",children:[e.jsx(ie,{size:14}),e.jsx("span",{children:s.error})]})]})}function _e(a,s,{delay:l=800,onSaved:d,onError:i}={}){const[m,x]=c.useState(a),[r,n]=c.useState("idle"),u=c.useRef(null),g=c.useRef(null),j=c.useRef(a),y=c.useRef(!1),C=c.useCallback(async p=>{n("saving");try{await s(p),j.current=p,g.current=null,n("saved"),d==null||d(),setTimeout(()=>n("idle"),2e3)}catch(v){n("error"),i==null||i(v)}},[s,d,i]),L=c.useCallback(p=>{x(p),g.current=p,y.current=!0,u.current&&clearTimeout(u.current),u.current=setTimeout(()=>{u.current=null,y.current=!1;const v=g.current;g.current=null,v!==null&&C(v)},l)},[l,C]),S=c.useCallback(()=>{u.current&&(clearTimeout(u.current),u.current=null,y.current=!1)},[]),h=c.useCallback(async()=>{if(u.current){clearTimeout(u.current),u.current=null,y.current=!1;const p=g.current;g.current=null,p!==null&&await C(p)}},[C]);return c.useEffect(()=>()=>{if(u.current){clearTimeout(u.current),u.current=null;const p=g.current;g.current=null,p!==null&&(n("saving"),s(p).then(()=>{j.current=p,n("saved"),d==null||d()}).catch(v=>{n("error"),i==null||i(v)}).finally(()=>{setTimeout(()=>n("idle"),2e3)}))}},[s,d,i]),{value:m,setValue:L,status:r,save:C,flush:h,clearDebounce:S,hasPendingDebounceRef:y,pendingValueRef:g}}function de({initialValue:a,saveFn:s,delay:l=800,render:d,className:i}){const{value:m,setValue:x,status:r,save:n,clearDebounce:u,hasPendingDebounceRef:g,pendingValueRef:j}=_e(a,s,{delay:l}),y=ye.useCallback(()=>{g.current&&(u(),j.current!==null&&n(j.current))},[u,g,n,j]);return e.jsxs("div",{className:`autosave-field ${i||""} ${r}`,children:[d({value:m,onChange:x,onBlur:y}),e.jsxs("span",{className:"autosave-status",role:"status","aria-live":"polite",children:[r==="saving"&&e.jsx(we,{className:"spinning",size:12}),r==="saved"&&e.jsx(Ne,{size:12}),r==="error"&&e.jsx(pe,{size:12})]})]})}const He=[{id:"topnav",label:"Top nav"},{id:"sidebar",label:"Sidebar"},{id:"both",label:"Both"}];function Je({settings:a,patchUi:s,patchTop:l,autoSave:d}){return e.jsxs(e.Fragment,{children:[e.jsxs(E,{id:"settings-layout","data-section":"layout",children:[e.jsxs(P,{children:[e.jsx(Se,{size:14})," UI layout"]}),e.jsx(T,{children:"Choose how the dashboard's navigation is presented."}),e.jsx("div",{className:"layout-row","data-setting-id":"ui.layout",children:He.map(i=>e.jsx("button",{type:"button",className:$("layout-card",a.ui.layout===i.id&&"layout-card-active"),onClick:()=>s({layout:i.id}),children:e.jsx("span",{className:"layout-card-label",children:i.label})},i.id))}),e.jsxs("label",{className:"checkbox-row","data-setting-id":"ui.showHeader",children:[e.jsx("input",{type:"checkbox",checked:a.ui.showHeader,onChange:i=>s({showHeader:i.target.checked})}),e.jsx("span",{children:"Show header"})]}),e.jsxs("label",{className:"checkbox-row","data-setting-id":"ui.showStatusBar",children:[e.jsx("input",{type:"checkbox",checked:a.ui.showStatusBar,onChange:i=>s({showStatusBar:i.target.checked})}),e.jsx("span",{children:"Show status bar"})]}),e.jsxs("div",{className:"field","data-setting-id":"ui.defaultTab",children:[e.jsx("label",{className:"field-label",children:"Default tab"}),e.jsxs("select",{className:"select",value:a.ui.defaultTab,onChange:i=>s({defaultTab:i.target.value}),children:[e.jsx("option",{value:"overview",children:"Overview"}),e.jsx("option",{value:"chat",children:"Chat"}),e.jsx("option",{value:"agents",children:"Agents"}),e.jsx("option",{value:"artifacts",children:"Plans"}),e.jsx("option",{value:"projects",children:"Projects"}),e.jsx("option",{value:"tasks",children:"Tasks"}),e.jsx("option",{value:"config",children:"Config"}),e.jsx("option",{value:"settings",children:"Settings"}),e.jsx("option",{value:"mods",children:"Mods"}),e.jsx("option",{value:"schedules",children:"Schedules"})]})]})]}),e.jsxs(E,{id:"settings-general","data-section":"general",children:[e.jsx(P,{children:"General"}),e.jsx(T,{children:"Default agent + model override."}),e.jsxs("div",{className:"field","data-setting-id":"defaultAgent",children:[e.jsx("label",{className:"field-label",htmlFor:"set-default-agent",children:"Default agent"}),e.jsx(de,{initialValue:a.defaultAgent||"",saveFn:async i=>{l("defaultAgent",i),d==null||d("defaultAgent",i)},render:({value:i,onChange:m,onBlur:x})=>e.jsx("input",{id:"set-default-agent",className:"input",type:"text",placeholder:"e.g. odin",value:i,onChange:r=>m(r.target.value),onBlur:x})})]}),e.jsxs("div",{className:"field","data-setting-id":"defaultModel",children:[e.jsx("label",{className:"field-label",htmlFor:"set-default-model",children:"Model override"}),e.jsx(de,{initialValue:a.defaultModel||"",saveFn:async i=>{l("defaultModel",i),d==null||d("defaultModel",i)},render:({value:i,onChange:m,onBlur:x})=>e.jsx("input",{id:"set-default-model",className:"input",type:"text",placeholder:"(leave empty for provider default)",value:i,onChange:r=>m(r.target.value),onBlur:x})})]})]})]})}function es({initialStatus:a}){var p;const[s,l]=c.useState(a??null),[d,i]=c.useState(""),[m,x]=c.useState(!1),[r,n]=c.useState(null);c.useEffect(()=>{s===null&&k.get("/tailscale/status").then(v=>l(v)).catch(()=>l(null))},[]);const u=async()=>{try{const v=await k.get("/tailscale/status");l(v)}catch{n("Failed to load Tailscale status")}},g=async()=>{if(d.trim()){x(!0),n(null);try{await k.post("/tailscale/setup",{authKey:d.trim()}),await u(),i("")}catch(v){n(v.message||"Authentication failed")}finally{x(!1)}}},j=async()=>{var v,w,z;if(s){x(!0),n(null);try{await k.post("/tailscale/setup",{port:((v=s.settings)==null?void 0:v.port)||4321,https:((w=s.settings)==null?void 0:w.https)!==!1,hostname:((z=s.settings)==null?void 0:z.hostname)||""}),await u()}catch(B){n(B.message||"Setup failed")}finally{x(!1)}}},y=async()=>{x(!0),n(null);try{await k.post("/tailscale/unserve"),await u()}catch(v){n(v.message||"Remove failed")}finally{x(!1)}},C=(s==null?void 0:s.installed)??!1,L=(s==null?void 0:s.authenticated)??!1,S=((p=s==null?void 0:s.settings)==null?void 0:p.enabled)??!1,h=S?`https://${(s==null?void 0:s.hostname)||"bizar-dash"}`:null;return C?e.jsxs(E,{id:"settings-tailscale-auth","data-section":"tailscale",children:[e.jsxs(P,{children:[e.jsx(ce,{size:14})," Tailscale Integration"]}),e.jsx(T,{children:"Expose the dashboard over your Tailscale network using an auth key."}),r&&e.jsx("p",{style:{color:"var(--color-error, #f85149)",fontSize:"0.85rem"},children:r}),L?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"status-row",style:{display:"flex",alignItems:"center",gap:"0.5rem",marginBottom:"0.75rem"},children:[e.jsx(V,{size:16,style:{color:"var(--color-success, #3fb950)"}}),e.jsxs("span",{children:["Authenticated as ",e.jsx("strong",{children:(s==null?void 0:s.hostname)||"unknown"})]})]}),S&&h?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"status-row",style:{display:"flex",alignItems:"center",gap:"0.5rem",marginBottom:"0.75rem"},children:[e.jsx(Ce,{size:16}),e.jsx("a",{href:h,target:"_blank",rel:"noreferrer",children:h})]}),e.jsx(b,{variant:"secondary",size:"sm",onClick:y,disabled:m,children:"Remove serve"})]}):e.jsx(b,{variant:"primary",size:"sm",onClick:j,disabled:m,children:"Set up Tailscale serve"})]}):e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"muted",style:{marginBottom:"0.75rem"},children:"Not authenticated with Tailscale."}),e.jsxs("div",{style:{display:"flex",gap:"0.5rem",flexWrap:"wrap"},children:[e.jsx("input",{type:"text",className:"input",placeholder:"tskey-...",value:d,onChange:v=>i(v.target.value),style:{flex:1,minWidth:"200px"},disabled:m}),e.jsx(b,{variant:"primary",size:"sm",onClick:g,disabled:m||!d.trim(),children:"Authenticate"})]})]})]}):e.jsxs(E,{id:"settings-tailscale-auth","data-section":"tailscale",children:[e.jsxs(P,{children:[e.jsx(ce,{size:14})," Tailscale Integration"]}),e.jsx(T,{children:"Tailscale is not installed on this machine."}),e.jsxs("p",{className:"muted",children:["Install from"," ",e.jsx("a",{href:"https://tailscale.com/download",target:"_blank",rel:"noreferrer",children:"tailscale.com/download"})]})]})}function ss({settings:a,patchTop:s}){var l,d,i;return e.jsxs(E,{id:"settings-system-llm","data-section":"system-llm",children:[e.jsxs(P,{children:[e.jsx(ze,{size:14})," System LLM API"]}),e.jsx(T,{children:"Configures the LLM used for automatic title generation, prompt enhancement, summarization, and other system-level calls."}),e.jsxs("label",{className:"checkbox-row","data-setting-id":"systemLlm.enabled",children:[e.jsx("input",{type:"checkbox",checked:!!((l=a.systemLlm)!=null&&l.enabled),onChange:m=>{const x=a.systemLlm||{enabled:!0,provider:"opencode",model:"opencode/deepseek-v4-flash-free"};s("systemLlm",{...x,enabled:m.target.checked})}}),e.jsx("span",{children:"Enable system LLM calls"})]}),e.jsxs("div",{className:"field","data-setting-id":"systemLlm.provider",style:{marginTop:"var(--space-3)"},children:[e.jsx("label",{className:"field-label",htmlFor:"set-system-llm-provider",children:"Provider"}),e.jsxs("select",{id:"set-system-llm-provider",className:"select",value:((d=a.systemLlm)==null?void 0:d.provider)||"opencode",onChange:m=>{const x=a.systemLlm||{enabled:!0,provider:"opencode",model:"opencode/deepseek-v4-flash-free"};s("systemLlm",{...x,provider:m.target.value})},children:[e.jsx("option",{value:"opencode",children:"Opencode"}),e.jsx("option",{value:"openrouter",children:"OpenRouter"}),e.jsx("option",{value:"minimax",children:"MiniMax"})]})]}),e.jsxs("div",{className:"field","data-setting-id":"systemLlm.model",children:[e.jsx("label",{className:"field-label",htmlFor:"set-system-llm-model",children:"Model"}),e.jsx("input",{id:"set-system-llm-model",className:"input mono",type:"text",placeholder:"opencode/deepseek-v4-flash-free",value:((i=a.systemLlm)==null?void 0:i.model)||"opencode/deepseek-v4-flash-free",onChange:m=>{const x=a.systemLlm||{enabled:!0,provider:"opencode",model:"opencode/deepseek-v4-flash-free"};s("systemLlm",{...x,model:m.target.value})}}),e.jsxs("p",{className:"field-help",children:["The API key is read from ",e.jsx("code",{children:"auth.json"})," for the selected provider. Leave the default model for best results."]})]}),e.jsxs("div",{style:{marginTop:"var(--space-4)"},children:[e.jsx("h4",{style:{margin:"0 0 var(--space-2)"},children:"Features using this API"}),e.jsxs("ul",{className:"settings-feature-list",style:{margin:0,paddingLeft:"var(--space-4)",lineHeight:1.8},children:[e.jsx("li",{children:"Auto-title generation for new chat sessions"}),e.jsx("li",{children:"Auto-title generation for new tasks"}),e.jsx("li",{children:'"Enhance prompt" button in the task input'}),e.jsx("li",{children:'"Enhance prompt" button in the chat composer'}),e.jsx("li",{className:"muted",style:{fontSize:12},children:"Future: summarization, name generation, and more"})]})]})]})}const Ve=[{value:"anthropic",label:"Anthropic"},{value:"anyllm",label:"AnyLLM"},{value:"litellm-anthropic",label:"LiteLLM (Anthropic)"},{value:"litellm-openai",label:"LiteLLM (OpenAI)"}];function Oe({settings:a,onPatch:s}){const l=Y(),[d,i]=c.useState(null),[m,x]=c.useState(null),[r,n]=c.useState(!1),[u,g]=c.useState(!1),[j,y]=c.useState(!1),[C,L]=c.useState(!1),[S,h]=c.useState(!1),[p,v]=c.useState(!1),w=c.useCallback(async()=>{n(!0);try{const[o,U]=await Promise.all([k.get("/headroom/status"),k.get("/headroom/stats?hours=24").catch(()=>({error:"no stats"}))]);i(o),U.error||x(U)}catch(o){l.error(`Failed to load Headroom status: ${o.message}`)}finally{n(!1)}},[l]);c.useEffect(()=>{w()},[w]);const z=async()=>{g(!0);try{const o=await k.post("/headroom/install",{force:!0});o.installed?(l.success(`Headroom installed via ${o.method}.`),await w()):l.error('Headroom install failed. Try: pip install "headroom-ai[all]"')}catch(o){l.error(`Install failed: ${o.message}`)}finally{g(!1)}},B=async()=>{y(!0);try{(await k.post("/headroom/wrap",{port:a.port})).ok?(l.success("opencode wrapped with Headroom."),await w()):l.error("Wrap failed.")}catch(o){l.error(`Wrap failed: ${o.message}`)}finally{y(!1)}},_=async()=>{L(!0);try{(await k.post("/headroom/unwrap")).ok?(l.success("opencode unwrapped from Headroom."),await w()):l.error("Unwrap failed.")}catch(o){l.error(`Unwrap failed: ${o.message}`)}finally{L(!1)}},W=async()=>{h(!0);try{(await k.post("/headroom/proxy/start",{port:a.port,host:a.host})).ok?(l.success(`Headroom proxy started on ${a.host}:${a.port}.`),await w()):l.error("Proxy start failed.")}catch(o){l.error(`Proxy start failed: ${o.message}`)}finally{h(!1)}},K=async()=>{v(!0);try{(await k.post("/headroom/proxy/stop")).ok?(l.success("Headroom proxy stopped."),await w()):l.error("Proxy stop failed.")}catch(o){l.error(`Proxy stop failed: ${o.message}`)}finally{v(!1)}},Z=async()=>{try{const{spawn:o}=await ke(async()=>{const{spawn:U}=await import("./__vite-browser-external-BIHI7g3E.js");return{spawn:U}},[]);o("headroom",["dashboard"],{detached:!0,stdio:"ignore"})}catch{l.error("Could not open Headroom dashboard. Run `headroom dashboard` manually.")}},{installed:R,version:q,proxyRunning:M,proxyPort:X,wrapped:A}=d||{},H=(m==null?void 0:m.compressionRatio)??0,D=(m==null?void 0:m.tokensSaved)??0;return e.jsx("div",{id:"settings-headroom","data-section":"headroom",children:e.jsxs(E,{children:[e.jsxs(P,{children:[e.jsx(me,{size:14,style:{color:M?"var(--success)":"var(--text-dim)"}}),"Headroom",R&&q&&e.jsxs("span",{style:{fontSize:11,color:"var(--text-dim)",marginLeft:6},children:["v",q," ",M?"✓":"✗"]}),!R&&e.jsx("span",{style:{fontSize:11,color:"var(--error)",marginLeft:6},children:"not installed"})]}),e.jsx(T,{children:"Context compression for token efficiency. Compresses tool outputs, logs, and conversation history by 60–95% before they reach the model."}),e.jsxs("div",{style:{display:"flex",gap:16,flexWrap:"wrap",marginTop:12,marginBottom:12},children:[e.jsxs("div",{className:"headroom-status-item",children:[R?e.jsx(V,{size:12,style:{color:"var(--success)"}}):e.jsx(se,{size:12,style:{color:"var(--error)"}}),e.jsx("span",{children:R?"Installed":"Not installed"})]}),e.jsxs("div",{className:"headroom-status-item",children:[M?e.jsx(V,{size:12,style:{color:"var(--success)"}}):e.jsx(se,{size:12,style:{color:"var(--text-dim)"}}),e.jsxs("span",{children:["Proxy ",M?`${X} ✓`:"stopped"]})]}),e.jsxs("div",{className:"headroom-status-item",children:[A?e.jsx(V,{size:12,style:{color:"var(--success)"}}):e.jsx(se,{size:12,style:{color:"var(--text-dim)"}}),e.jsxs("span",{children:["opencode ",A?"wrapped":"not wrapped"]})]})]}),(D>0||H>0)&&e.jsxs("div",{style:{display:"flex",gap:24,marginBottom:12},children:[e.jsxs("div",{children:[e.jsx("div",{style:{fontSize:20,fontWeight:700,color:"var(--success)"},children:H>0?`${Math.round(H*100)}%`:"—"}),e.jsx("div",{className:"muted",style:{fontSize:11},children:"Compression ratio"})]}),e.jsxs("div",{children:[e.jsx("div",{style:{fontSize:20,fontWeight:700,color:"var(--accent)"},children:D>0?D.toLocaleString():"—"}),e.jsx("div",{className:"muted",style:{fontSize:11},children:"Tokens saved (24h)"})]})]}),e.jsxs("div",{style:{display:"flex",gap:8,flexWrap:"wrap",marginBottom:8},children:[R?e.jsxs(e.Fragment,{children:[e.jsxs(b,{variant:"secondary",size:"sm",onClick:B,disabled:j||A,title:A?"opencode is already wrapped":"Wrap opencode to route through Headroom proxy",children:[j?e.jsx("span",{className:"btn-spinner"}):e.jsx(Ae,{size:13}),j?"Wrapping…":A?"Wrapped ✓":"Wrap opencode"]}),A&&e.jsxs(b,{variant:"ghost",size:"sm",onClick:_,disabled:C,children:[C?e.jsx("span",{className:"btn-spinner"}):e.jsx(O,{size:13}),C?"Unwrapping…":"Unwrap"]})]}):e.jsxs(b,{variant:"primary",size:"sm",onClick:z,disabled:u,children:[u?e.jsx("span",{className:"btn-spinner"}):e.jsx(G,{size:13}),u?"Installing…":"Install Headroom"]}),R&&e.jsxs(e.Fragment,{children:[M?e.jsxs(b,{variant:"secondary",size:"sm",onClick:K,disabled:p,children:[p?e.jsx("span",{className:"btn-spinner"}):e.jsx(Re,{size:13}),p?"Stopping…":"Stop proxy"]}):e.jsxs(b,{variant:"secondary",size:"sm",onClick:W,disabled:S,children:[S?e.jsx("span",{className:"btn-spinner"}):e.jsx(Le,{size:13}),S?"Starting…":"Start proxy"]}),e.jsxs(b,{variant:"ghost",size:"sm",onClick:Z,children:[e.jsx(Ie,{size:13}),"Dashboard"]})]}),e.jsx(b,{variant:"ghost",size:"sm",onClick:w,disabled:r,children:e.jsx(O,{size:13,className:r?"spin":""})})]}),e.jsxs("div",{style:{marginTop:16},children:[e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.enabled,onChange:o=>s({enabled:o.target.checked})}),e.jsx("span",{children:"Enable Headroom"})]}),e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.autoInstall,onChange:o=>s({autoInstall:o.target.checked})}),e.jsx("span",{children:"Auto-install if missing on dashboard startup"})]}),e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.autoStart,onChange:o=>s({autoStart:o.target.checked})}),e.jsx("span",{children:"Auto-start proxy on dashboard startup"})]}),e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.autoWrap,onChange:o=>s({autoWrap:o.target.checked})}),e.jsx("span",{children:"Auto-wrap opencode on dashboard startup"})]}),e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.routeAllProviders,onChange:o=>s({routeAllProviders:o.target.checked})}),e.jsx("span",{children:"Route all providers through Headroom proxy"})]}),e.jsxs("div",{className:"task-form-row",style:{marginTop:12},children:[e.jsxs("div",{className:"task-form-field",children:[e.jsx("label",{className:"field-label",children:"Proxy port"}),e.jsx("input",{type:"number",className:"input",value:a.port,min:1,max:65535,onChange:o=>s({port:Math.max(1,Math.min(65535,parseInt(o.target.value,10)||8787))})})]}),e.jsxs("div",{className:"task-form-field",children:[e.jsx("label",{className:"field-label",children:"Proxy host"}),e.jsx("input",{type:"text",className:"input",value:a.host,onChange:o=>s({host:o.target.value})})]})]}),e.jsxs("div",{className:"task-form-row",children:[e.jsxs("div",{className:"task-form-field",children:[e.jsx("label",{className:"field-label",children:"Backend"}),e.jsx("select",{className:"select",value:a.backend,onChange:o=>s({backend:o.target.value}),children:Ve.map(o=>e.jsx("option",{value:o.value,children:o.label},o.value))})]}),e.jsxs("div",{className:"task-form-field",children:[e.jsx("label",{className:"field-label",children:"Monthly budget (USD)"}),e.jsx("input",{type:"number",className:"input",value:a.budget,min:0,step:1,onChange:o=>s({budget:Math.max(0,parseFloat(o.target.value)||0)})}),e.jsx("span",{className:"field-help",children:"0 = unlimited"})]})]}),e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.outputShaper,onChange:o=>s({outputShaper:o.target.checked})}),e.jsx("span",{children:"Enable output shaper"})]}),e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.telemetry,onChange:o=>s({telemetry:o.target.checked})}),e.jsx("span",{children:"Enable telemetry"})]})]})]})})}const ue={enabled:!0,autoInstall:!0,port:8787,host:"127.0.0.1",outputShaper:!1,telemetry:!1,budget:0,backend:"anthropic",autoStart:!0,autoWrap:!0,routeAllProviders:!0};function as({settings:a,setSettings:s,setDirty:l}){return e.jsx(Oe,{settings:a.headroom||ue,onPatch:d=>{s(i=>({...i,headroom:{...i.headroom||ue,...d}})),l(!0)}})}function Fe(){const a=Y(),[s,l]=c.useState([]),[d,i]=c.useState(new Set),[m,x]=c.useState(!0),[r,n]=c.useState(""),[u,g]=c.useState(!0),j=c.useCallback(async()=>{x(!0);try{const[h,p]=await Promise.all([k.get("/activity"),k.get("/activity/hidden")]);l(Array.isArray(h.items)?h.items:[]),i(new Set(p.hidden||[]))}catch(h){a.error(`Load failed: ${h.message}`)}finally{x(!1)}},[a]);c.useEffect(()=>{j()},[j]);const y=(h,p)=>{const v=`${h.kind||""}|${h.ts||""}|${h.slug||""}|${p}`;let w=0;for(let z=0;z<v.length;z++)w=(w<<5)-w+v.charCodeAt(z)|0;return Math.abs(w).toString(16).padStart(8,"0").slice(0,16)},C=async()=>{try{await k.del("/activity/hide"),i(new Set),a.success("All hidden activity restored.")}catch(h){a.error(`Restore failed: ${h.message}`)}},L=async h=>{try{await k.del(`/activity/hide/${encodeURIComponent(h)}`);const p=new Set(d);p.delete(h),i(p)}catch(p){a.error(`Restore failed: ${p.message}`)}},S=s.filter((h,p)=>{const v=y(h,p);if(!u&&d.has(v))return!1;if(!r)return!0;const w=r.toLowerCase();return[h.kind,h.slug,h.message].some(z=>typeof z=="string"&&z.toLowerCase().includes(w))});return e.jsxs(E,{id:"settings-activity-log","data-section":"activity-log",children:[e.jsxs(P,{children:[e.jsx(me,{size:14})," Activity log",e.jsxs("span",{className:"muted",style:{fontWeight:400,marginLeft:8,fontSize:12},children:[s.length," total · ",d.size," hidden"]}),e.jsx(b,{variant:"ghost",size:"sm",style:{marginLeft:"auto"},onClick:j,title:"Reload",children:e.jsx(O,{size:12})})]}),e.jsxs(T,{children:["Full history from ",e.jsx("code",{children:"~/.bizar/activity.log"}),". Hiding an item in the Overview only hides it there — the entry stays here."]}),e.jsxs("div",{className:"activity-log-toolbar",children:[e.jsxs("div",{className:"activity-log-search",children:[e.jsx(te,{size:12}),e.jsx("input",{type:"text",className:"input",placeholder:"Filter by kind, slug, or message…",value:r,onChange:h=>n(h.target.value)})]}),e.jsxs("label",{className:"activity-log-toggle",children:[e.jsx("input",{type:"checkbox",checked:u,onChange:h=>g(h.target.checked)}),"Show hidden"]}),e.jsxs(b,{variant:"ghost",size:"sm",disabled:d.size===0,onClick:C,title:"Restore all hidden items to the Overview",children:[e.jsx(ne,{size:12})," Restore all"]})]}),m?e.jsx("div",{className:"muted",style:{padding:"12px 0",fontSize:12},children:"Loading…"}):S.length===0?e.jsx("div",{className:"muted",style:{padding:"12px 0",fontSize:12},children:s.length===0?"No activity yet.":"No items match the current filter."}):e.jsxs("div",{className:"activity-log-table-wrap",children:[e.jsxs("table",{className:"activity-log-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Kind"}),e.jsx("th",{children:"Detail"}),e.jsx("th",{children:"Time"}),e.jsx("th",{})]})}),e.jsx("tbody",{children:S.slice(0,200).map((h,p)=>{const v=y(h,p),w=d.has(v);return e.jsxs("tr",{className:$(w&&"activity-log-row-hidden"),children:[e.jsx("td",{className:"activity-log-kind",children:h.kind||"activity"}),e.jsx("td",{className:"activity-log-detail",children:h.message||h.slug||"—"}),e.jsx("td",{className:"activity-log-time mono",children:h.ts?new Date(h.ts).toLocaleString():"—"}),e.jsx("td",{children:w?e.jsx(b,{variant:"ghost",size:"sm",onClick:()=>L(v),title:"Restore to Overview",children:e.jsx(ne,{size:12})}):e.jsx("span",{className:"activity-log-state-tag",children:"shown"})})]},`${h.ts}-${p}`)})})]}),S.length>200&&e.jsxs("div",{className:"muted",style:{fontSize:11,padding:"8px 0"},children:["Showing first 200 of ",S.length,"."]})]})]})}function We({about:a}){return e.jsxs(E,{id:"settings-about","data-section":"about",children:[e.jsxs(P,{children:[e.jsx(Ee,{size:14})," About"]}),e.jsx(T,{children:"Build metadata."}),e.jsxs("dl",{className:"about-table",children:[e.jsx("dt",{children:"Version"}),e.jsx("dd",{className:"mono",children:(a==null?void 0:a.version)||"—"}),e.jsx("dt",{children:"Homepage"}),e.jsx("dd",{children:e.jsx("a",{href:(a==null?void 0:a.homepage)||"https://github.com/DrB0rk/BizarHarness",target:"_blank",rel:"noopener noreferrer",children:(a==null?void 0:a.homepage)||"https://github.com/DrB0rk/BizarHarness"})}),e.jsx("dt",{children:"License"}),e.jsx("dd",{children:(a==null?void 0:a.license)||"MIT"})]})]})}function ts({about:a}){return e.jsxs(e.Fragment,{children:[e.jsx(Fe,{}),e.jsx(We,{about:a})]})}function Ke({onError:a}){const s=Y(),[l,d]=c.useState([]),[i,m]=c.useState(!1),[x,r]=c.useState(!1),[n,u]=c.useState(new Set),[g,j]=c.useState(null),[y,C]=c.useState(""),[L,S]=c.useState(!1),[h,p]=c.useState(""),[v,w]=c.useState(""),[z,B]=c.useState(!1),[_,W]=c.useState(""),[K,Z]=c.useState(!1),[R,q]=c.useState(""),[M,X]=c.useState(new Set),A=c.useCallback(async()=>{m(!0);try{const t=await k.get("/env-vars");d(t)}catch(t){s.error(`Load failed: ${t.message}`),a==null||a(t.message)}finally{m(!1)}},[s,a]);c.useEffect(()=>{A()},[A]);const H=t=>{u(N=>{const f=new Set(N);return f.has(t)?f.delete(t):f.add(t),f})},D=async()=>{const t=h.trim().toUpperCase(),N=v.trim();if(!t||!/^BIZAR_[A-Z0-9_]+$/.test(t)){s.warning("Name must match BIZAR_<NAME> (e.g. BIZAR_MINIMAX_KEY)");return}if(!N){s.warning("Value is required.");return}if(l.some(f=>f.name===t)){s.warning(`${t} already exists.`);return}r(!0);try{await k.post("/env-vars",{name:t,value:N}),s.success(`${t} created.`),S(!1),p(""),w(""),await A()}catch(f){s.error(`Create failed: ${f.message}`)}finally{r(!1)}},o=t=>{j(t.name),C(t.value===t.value.replace(/\*/g,"")?t.value:""),u(N=>{const f=new Set(N);return f.add(t.name),f})},U=async t=>{if(!y.trim()){s.warning("Value cannot be empty.");return}r(!0);try{await k.put(`/env-vars/${encodeURIComponent(t)}`,{value:y.trim()}),s.success(`${t} updated.`),j(null),await A()}catch(N){s.error(`Update failed: ${N.message}`)}finally{r(!1)}},re=async t=>{if(confirm(`Delete ${t}? This cannot be undone.`))try{await k.del(`/env-vars/${encodeURIComponent(t)}`),s.success(`${t} deleted.`),await A()}catch(N){s.error(`Delete failed: ${N.message}`)}},ge=async()=>{if(!_.trim()){s.warning("Nothing to import.");return}Z(!0);try{const t=await k.post("/env-vars/bulk-import",{envContent:_});s.success(`Imported ${t.imported}, skipped ${t.skipped}.`),t.errors.length>0&&s.warning(`${t.errors.length} lines had errors: ${t.errors.slice(0,3).join("; ")}${t.errors.length>3?"…":""}`),W(""),B(!1),await A()}catch(t){s.error(`Bulk import failed: ${t.message}`)}finally{Z(!1)}},je=async()=>{try{const t=await k.get("/env-vars/export"),N=new Blob([t],{type:"text/plain"}),f=URL.createObjectURL(N),I=document.createElement("a");I.href=f,I.download=".env",I.click(),URL.revokeObjectURL(f),s.success("Exported .env file.")}catch(t){s.error(`Export failed: ${t.message}`)}},F=c.useMemo(()=>{if(!R.trim())return l;const t=R.toLowerCase();return l.filter(N=>N.name.toLowerCase().includes(t))},[l,R]),Q=c.useMemo(()=>{const t={};for(const N of F){const f=N.name.split("_")[0]+"_";(t[f]??(t[f]=[])).push(N)}return t},[F]),ve=t=>{X(N=>{const f=new Set(N);return f.has(t)?f.delete(t):f.add(t),f})},le=c.useMemo(()=>{const t=["BIZAR_","PROVIDER_","MODEL_","API_"];return Object.keys(Q).sort((f,I)=>{const J=t.indexOf(f),ee=t.indexOf(I);return J===-1&&ee===-1?f.localeCompare(I):J===-1?1:ee===-1?-1:J-ee})},[Q]);if(i)return e.jsx("div",{className:"muted",style:{padding:"16px 0",fontSize:13},children:"Loading env vars…"});const fe=le.length>1;return e.jsxs("div",{className:"env-var-manager",children:[e.jsxs("div",{className:"env-var-toolbar",children:[e.jsxs(b,{variant:"primary",size:"sm",onClick:()=>S(!0),children:[e.jsx(Pe,{size:12})," New variable"]}),e.jsxs(b,{variant:"secondary",size:"sm",onClick:()=>B(t=>!t),className:z?"active":"",children:[e.jsx(Te,{size:12})," Bulk import"]}),e.jsxs(b,{variant:"ghost",size:"sm",onClick:je,title:"Export as .env",children:[e.jsx(G,{size:12})," Export"]}),e.jsxs("div",{className:"env-var-search-wrap",children:[e.jsx(te,{size:12,className:"env-var-search-icon"}),e.jsx("input",{className:"env-var-search input",placeholder:"Filter…",value:R,onChange:t=>q(t.target.value)})]}),e.jsx(b,{variant:"ghost",size:"sm",onClick:A,title:"Reload",children:e.jsx(O,{size:12})})]}),z&&e.jsxs("div",{className:"env-var-bulk-panel",children:[e.jsxs("div",{className:"env-var-bulk-header",children:[e.jsxs("span",{children:["Paste ",e.jsx("code",{children:"KEY=value"})," lines (one per line):"]}),e.jsx(b,{variant:"ghost",size:"sm",onClick:()=>B(!1),children:e.jsx(oe,{size:12})})]}),e.jsx("textarea",{className:"input mono env-var-bulk-textarea",placeholder:`BIZAR_API_KEY=your-key-here
|
|
3
3
|
PROVIDER_OPENAI_KEY=sk-...
|
|
4
|
-
MODEL_KEY=gem-...`,value:_,onChange:t=>W(t.target.value),rows:6}),e.jsxs("div",{className:"env-var-bulk-footer",children:[e.jsx(b,{variant:"primary",size:"sm",onClick:ge,disabled:K||!_.trim(),children:K?"Importing…":"Import"}),e.jsx("span",{className:"muted",style:{fontSize:11},children:"Existing keys are skipped unless re-created individually. Invalid lines are reported."})]})]}),l.length===0&&!L&&e.jsxs("div",{className:"env-var-empty",children:[e.jsx(xe,{size:20}),e.jsx("span",{children:"No BIZAR_* env vars yet."}),e.jsx("span",{style:{fontSize:11},children:"Create one to store API keys securely."})]}),L&&e.jsxs("div",{className:"env-var-add-form",children:[e.jsxs("div",{className:"env-var-add-row",children:[e.jsx("input",{className:"input mono",style:{width:240},placeholder:"BIZAR_NAME",value:h,onChange:t=>p(t.target.value.toUpperCase()),onKeyDown:t=>{t.key==="Enter"&&D(),t.key==="Escape"&&S(!1)},autoFocus:!0}),e.jsx("input",{className:"input mono",type:"password",placeholder:"value (API key, token, etc.)",value:v,onChange:t=>w(t.target.value),onKeyDown:t=>{t.key==="Enter"&&D(),t.key==="Escape"&&S(!1)}}),e.jsxs(b,{variant:"primary",size:"sm",onClick:D,disabled:x,children:[e.jsx(V,{size:12})," Create"]}),e.jsx(b,{variant:"ghost",size:"sm",onClick:()=>{S(!1),p(""),w("")},children:e.jsx(oe,{size:12})})]}),e.jsxs("p",{style:{fontSize:11,color:"var(--text-dim)",margin:0},children:["Names must match ",e.jsxs("code",{children:["BIZAR_",e.jsx("var",{children:"NAME"})]})," (uppercase letters, digits, underscores)."]})]}),F.length>0&&(fe?e.jsx("div",{className:"env-var-groups",children:le.map(t=>{const N=Q[t],f=M.has(t);return e.jsxs("div",{className:"env-var-group",children:[e.jsxs("button",{type:"button",className:"env-var-group-header",onClick:()=>ve(t),children:[f?e.jsx(
|
|
4
|
+
MODEL_KEY=gem-...`,value:_,onChange:t=>W(t.target.value),rows:6}),e.jsxs("div",{className:"env-var-bulk-footer",children:[e.jsx(b,{variant:"primary",size:"sm",onClick:ge,disabled:K||!_.trim(),children:K?"Importing…":"Import"}),e.jsx("span",{className:"muted",style:{fontSize:11},children:"Existing keys are skipped unless re-created individually. Invalid lines are reported."})]})]}),l.length===0&&!L&&e.jsxs("div",{className:"env-var-empty",children:[e.jsx(xe,{size:20}),e.jsx("span",{children:"No BIZAR_* env vars yet."}),e.jsx("span",{style:{fontSize:11},children:"Create one to store API keys securely."})]}),L&&e.jsxs("div",{className:"env-var-add-form",children:[e.jsxs("div",{className:"env-var-add-row",children:[e.jsx("input",{className:"input mono",style:{width:240},placeholder:"BIZAR_NAME",value:h,onChange:t=>p(t.target.value.toUpperCase()),onKeyDown:t=>{t.key==="Enter"&&D(),t.key==="Escape"&&S(!1)},autoFocus:!0}),e.jsx("input",{className:"input mono",type:"password",placeholder:"value (API key, token, etc.)",value:v,onChange:t=>w(t.target.value),onKeyDown:t=>{t.key==="Enter"&&D(),t.key==="Escape"&&S(!1)}}),e.jsxs(b,{variant:"primary",size:"sm",onClick:D,disabled:x,children:[e.jsx(V,{size:12})," Create"]}),e.jsx(b,{variant:"ghost",size:"sm",onClick:()=>{S(!1),p(""),w("")},children:e.jsx(oe,{size:12})})]}),e.jsxs("p",{style:{fontSize:11,color:"var(--text-dim)",margin:0},children:["Names must match ",e.jsxs("code",{children:["BIZAR_",e.jsx("var",{children:"NAME"})]})," (uppercase letters, digits, underscores)."]})]}),F.length>0&&(fe?e.jsx("div",{className:"env-var-groups",children:le.map(t=>{const N=Q[t],f=M.has(t);return e.jsxs("div",{className:"env-var-group",children:[e.jsxs("button",{type:"button",className:"env-var-group-header",onClick:()=>ve(t),children:[f?e.jsx($e,{size:12}):e.jsx(Be,{size:12}),e.jsx("span",{className:"env-var-group-prefix mono",children:t}),e.jsxs("span",{className:"env-var-group-count muted",children:["(",N.length,")"]})]}),!f&&e.jsx("div",{className:"env-var-list",children:N.map(I=>e.jsx(he,{v:I,editing:g,editValue:y,isRevealed:n.has(I.name),onToggleReveal:H,onStartEdit:o,onEditValueChange:C,onHandleUpdate:U,onCancelEdit:()=>j(null),onDelete:re,saving:x},I.name))})]},t)})}):e.jsx("div",{className:"env-var-list",children:F.map(t=>e.jsx(he,{v:t,editing:g,editValue:y,isRevealed:n.has(t.name),onToggleReveal:H,onStartEdit:o,onEditValueChange:C,onHandleUpdate:U,onCancelEdit:()=>j(null),onDelete:re,saving:x},t.name))})),F.length===0&&l.length>0&&e.jsxs("div",{className:"env-var-empty",children:[e.jsx(te,{size:16}),e.jsxs("span",{children:['No env vars match "',R,'"']})]})]})}function he({v:a,editing:s,editValue:l,isRevealed:d,onToggleReveal:i,onStartEdit:m,onEditValueChange:x,onHandleUpdate:r,onCancelEdit:n,onDelete:u,saving:g}){const j=s===a.name;return e.jsxs("div",{className:$("env-var-row",j&&"env-var-row-editing"),children:[e.jsx("span",{className:"env-var-name mono",children:a.name}),j?e.jsx("input",{className:"input mono",type:"password",style:{flex:1,minWidth:200},value:l,onChange:y=>x(y.target.value),onKeyDown:y=>{y.key==="Enter"&&r(a.name),y.key==="Escape"&&n()},autoFocus:!0}):e.jsx("span",{className:$("env-var-value mono",!d&&"env-var-value-masked"),children:a.value}),e.jsx("span",{className:"env-var-source muted",children:a.source}),e.jsxs("div",{className:"env-var-actions",children:[!j&&e.jsx("button",{type:"button",className:"icon-btn",title:d?"Hide":"Reveal",onClick:()=>i(a.name),children:d?e.jsx(Me,{size:12}):e.jsx(ne,{size:12})}),j?e.jsxs(e.Fragment,{children:[e.jsx(b,{variant:"primary",size:"sm",onClick:()=>r(a.name),disabled:g,children:"Save"}),e.jsx(b,{variant:"ghost",size:"sm",onClick:n,children:"Cancel"})]}):e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",className:"icon-btn",title:"Edit",onClick:()=>m(a),children:e.jsx(De,{size:12})}),e.jsx("button",{type:"button",className:"icon-btn icon-btn-danger",title:"Delete",onClick:()=>u(a.name),children:e.jsx(Ue,{size:12})})]})]})]})}function ns(){return e.jsxs(E,{id:"settings-env-vars","data-section":"env-vars",children:[e.jsxs(P,{children:[e.jsx(xe,{size:14})," Environment Variables"]}),e.jsxs(T,{children:["Manage BIZAR_* env vars (API keys, secrets). Values are stored in ",e.jsx("code",{children:"~/.config/bizar/env.json"})," (mode 0600)."]}),e.jsx(Ke,{})]})}export{de as A,b as B,E as C,ns as E,Je as G,as as H,ss as S,es as T,Qe as U,P as a,T as b,ts as c};
|