@polderlabs/bizar 5.4.0 → 5.4.1

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 (31) hide show
  1. package/bizar-dash/dist/assets/{EnvVarsSection-DqvB8ZcJ.js → EnvVarsSection-DhLHZ5ua.js} +1 -1
  2. package/bizar-dash/dist/assets/{EnvVarsSection-DqvB8ZcJ.js.map → EnvVarsSection-DhLHZ5ua.js.map} +1 -1
  3. package/bizar-dash/dist/assets/{MobileChat-DRXP2ERQ.js → MobileChat-9UpvDP6-.js} +1 -1
  4. package/bizar-dash/dist/assets/{MobileChat-DRXP2ERQ.js.map → MobileChat-9UpvDP6-.js.map} +1 -1
  5. package/bizar-dash/dist/assets/{MobileSettings-CVW9VhEo.js → MobileSettings-BFmN9ZWR.js} +1 -1
  6. package/bizar-dash/dist/assets/{MobileSettings-CVW9VhEo.js.map → MobileSettings-BFmN9ZWR.js.map} +1 -1
  7. package/bizar-dash/dist/assets/{Toast-CcZVVN4i.js → Toast-BlcKl_dN.js} +1 -1
  8. package/bizar-dash/dist/assets/{Toast-CcZVVN4i.js.map → Toast-BlcKl_dN.js.map} +1 -1
  9. package/bizar-dash/dist/assets/{icons-OMEGx5KA.js → icons-CMPxNV8t.js} +124 -129
  10. package/bizar-dash/dist/assets/icons-CMPxNV8t.js.map +1 -0
  11. package/bizar-dash/dist/assets/{main-CMAGZouj.js → main-Dhrvp9Gt.js} +1 -1
  12. package/bizar-dash/dist/assets/{main-CMAGZouj.js.map → main-Dhrvp9Gt.js.map} +1 -1
  13. package/bizar-dash/dist/assets/mobile-DDY1lquG.js +1 -0
  14. package/bizar-dash/dist/assets/{mobile-XN2P7YfM.js.map → mobile-DDY1lquG.js.map} +1 -1
  15. package/bizar-dash/dist/assets/mobile-layout-BjkoHh1W.js +2 -0
  16. package/bizar-dash/dist/assets/mobile-layout-BjkoHh1W.js.map +1 -0
  17. package/bizar-dash/dist/assets/{mobile-layout-D6V-7WnA.css → mobile-layout-CJnZNLy3.css} +1 -1
  18. package/bizar-dash/dist/assets/{useSlashCommands-iyoW95UB.js → useSlashCommands-eFCiWHVt.js} +2 -2
  19. package/bizar-dash/dist/assets/{useSlashCommands-iyoW95UB.js.map → useSlashCommands-eFCiWHVt.js.map} +1 -1
  20. package/bizar-dash/dist/index.html +7 -7
  21. package/bizar-dash/dist/mobile.html +4 -4
  22. package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  23. package/bizar-dash/src/web/MobileApp.tsx +1 -10
  24. package/bizar-dash/src/web/styles/mobile-layout.css +7 -5
  25. package/bizar-dash/src/web/styles/settings.css +46 -0
  26. package/bizar-dash/tests/mobile-layout.test.tsx +36 -0
  27. package/package.json +1 -1
  28. package/bizar-dash/dist/assets/icons-OMEGx5KA.js.map +0 -1
  29. package/bizar-dash/dist/assets/mobile-XN2P7YfM.js +0 -1
  30. package/bizar-dash/dist/assets/mobile-layout-DqTxvXZp.js +0 -2
  31. package/bizar-dash/dist/assets/mobile-layout-DqTxvXZp.js.map +0 -1
@@ -1 +1 @@
1
- import{j as n,r as t}from"./react-vendor-Dn4wqh4Z.js";import{C as N,u as T,a as k,b as R,c as E}from"./useSlashCommands-iyoW95UB.js";import{u as F}from"./Toast-CcZVVN4i.js";import"./icons-OMEGx5KA.js";import"./mobile-layout-DqTxvXZp.js";import"./markdown-C6mXtQxD.js";import"./vendor-CeHGtduv.js";function $(o){const{activeSource:c}=o;return n.jsx("div",{className:`chat-composer-wrap chat-composer-source-${c??"none"} legacy`,children:n.jsx("div",{className:"chat-composer-pill",children:n.jsx(N,{...o})})})}function G({snapshot:o,settings:c,setActiveTab:g,initialTaskId:j,onClearTaskId:z}){const i=F(),s=T(o,c,j??"");t.useEffect(()=>{s.setToast({error:e=>i.error(e),success:e=>i.success(e),info:e=>i.info(e),warning:e=>i.warning(e)})},[s,i]);const[r,l]=t.useState(""),[f,x]=t.useState(c.defaultAgent||"odin"),[p,C]=t.useState(c.defaultModel||""),[h,v]=t.useState([]),u=t.useRef(null),{suggestions:y,setQuery:m}=k(o);t.useEffect(()=>{m(r)},[r,m]);const P=()=>{var e;return(e=u.current)==null?void 0:e.click()},w=e=>{const d=e.target.files;if(!d)return;const S=[];for(let a=0;a<d.length;a++)S.push(d[a].name);v(a=>{const O=S.filter(M=>!a.includes(M));return[...a,...O]}),u.current&&(u.current.value="")},I=async()=>{const e=r.trim();if(!e)return;l(""),m(""),(await s.onSend(e,f,p,h)).ok&&s.jumpToLatest()};return n.jsxs("div",{className:"chat-shell",children:[n.jsx(R,{activeProject:o.activeProject,sessionCount:s.sessions.length,sessionsOpen:!1,infoOpen:!1,onToggleSessions:()=>{},onToggleInfo:()=>{},onOpenOverview:()=>g==null?void 0:g("overview")}),n.jsx("div",{className:"chat-body",children:n.jsxs("main",{className:"chat-main",children:[n.jsx(E,{messages:s.activeSource==="opencode"?s.opencodeMessages:s.bizarMessages,loading:s.loading,activeProject:o.activeProject,sessionId:s.activeSource==="opencode"?s.activeOpencodeSessionId??s.sessionId:s.sessionId,pinned:s.pinned,activeSource:s.activeSource,onPickSuggestion:e=>l(e),onCopy:e=>s.copyMessage(e),onDelete:()=>{},onTogglePin:s.togglePin,onRegenerate:s.onRegenerate}),n.jsx($,{agent:f,setAgent:x,model:p,setModel:C,text:r,setText:l,sending:s.sending,activeSource:s.activeSource,onSend:I,attachments:h,setAttachments:v,suggestions:y,onPickSuggestion:e=>l(`${e.split(" ")[0]} `),agents:o.agents||[],onAttach:P,sessionsOpen:!1,infoOpen:!1}),n.jsx("input",{ref:u,type:"file",multiple:!0,style:{display:"none"},onChange:w})]})})]})}export{G as MobileChat};
1
+ import{j as n,r as t}from"./react-vendor-Dn4wqh4Z.js";import{C as N,u as T,a as k,b as R,c as E}from"./useSlashCommands-eFCiWHVt.js";import{u as F}from"./Toast-BlcKl_dN.js";import"./icons-CMPxNV8t.js";import"./mobile-layout-BjkoHh1W.js";import"./markdown-C6mXtQxD.js";import"./vendor-CeHGtduv.js";function $(o){const{activeSource:c}=o;return n.jsx("div",{className:`chat-composer-wrap chat-composer-source-${c??"none"} legacy`,children:n.jsx("div",{className:"chat-composer-pill",children:n.jsx(N,{...o})})})}function G({snapshot:o,settings:c,setActiveTab:g,initialTaskId:j,onClearTaskId:z}){const i=F(),s=T(o,c,j??"");t.useEffect(()=>{s.setToast({error:e=>i.error(e),success:e=>i.success(e),info:e=>i.info(e),warning:e=>i.warning(e)})},[s,i]);const[r,l]=t.useState(""),[f,x]=t.useState(c.defaultAgent||"odin"),[p,C]=t.useState(c.defaultModel||""),[h,v]=t.useState([]),u=t.useRef(null),{suggestions:y,setQuery:m}=k(o);t.useEffect(()=>{m(r)},[r,m]);const P=()=>{var e;return(e=u.current)==null?void 0:e.click()},w=e=>{const d=e.target.files;if(!d)return;const S=[];for(let a=0;a<d.length;a++)S.push(d[a].name);v(a=>{const O=S.filter(M=>!a.includes(M));return[...a,...O]}),u.current&&(u.current.value="")},I=async()=>{const e=r.trim();if(!e)return;l(""),m(""),(await s.onSend(e,f,p,h)).ok&&s.jumpToLatest()};return n.jsxs("div",{className:"chat-shell",children:[n.jsx(R,{activeProject:o.activeProject,sessionCount:s.sessions.length,sessionsOpen:!1,infoOpen:!1,onToggleSessions:()=>{},onToggleInfo:()=>{},onOpenOverview:()=>g==null?void 0:g("overview")}),n.jsx("div",{className:"chat-body",children:n.jsxs("main",{className:"chat-main",children:[n.jsx(E,{messages:s.activeSource==="opencode"?s.opencodeMessages:s.bizarMessages,loading:s.loading,activeProject:o.activeProject,sessionId:s.activeSource==="opencode"?s.activeOpencodeSessionId??s.sessionId:s.sessionId,pinned:s.pinned,activeSource:s.activeSource,onPickSuggestion:e=>l(e),onCopy:e=>s.copyMessage(e),onDelete:()=>{},onTogglePin:s.togglePin,onRegenerate:s.onRegenerate}),n.jsx($,{agent:f,setAgent:x,model:p,setModel:C,text:r,setText:l,sending:s.sending,activeSource:s.activeSource,onSend:I,attachments:h,setAttachments:v,suggestions:y,onPickSuggestion:e=>l(`${e.split(" ")[0]} `),agents:o.agents||[],onAttach:P,sessionsOpen:!1,infoOpen:!1}),n.jsx("input",{ref:u,type:"file",multiple:!0,style:{display:"none"},onChange:w})]})})]})}export{G as MobileChat};
@@ -1 +1 @@
1
- {"version":3,"file":"MobileChat-DRXP2ERQ.js","sources":["../../src/web/components/chat/FloatingComposer.tsx","../../src/web/mobile/MobileChat.tsx"],"sourcesContent":["// src/components/chat/FloatingComposer.tsx — sticky bottom wrapper for the composer pill.\n\nimport { Composer } from './Composer';\n\ninterface Props {\n agent: string;\n setAgent: (a: string) => void;\n model: string;\n setModel: (m: string) => void;\n text: string;\n setText: (t: string) => void;\n sending: boolean;\n onSend: () => void;\n attachments: string[];\n setAttachments: (a: string[] | ((prev: string[]) => string[])) => void;\n suggestions: Array<{ cmd: string; desc: string }>;\n onPickSuggestion: (cmd: string) => void;\n agents: Array<{ name: string }>;\n onAttach: () => void;\n sessionsOpen: boolean;\n infoOpen: boolean;\n /** Which stream will receive the next message — propagates the\n * pill border color and a small \"→ opencode\" hint. */\n activeSource?: 'bizar' | 'opencode' | null;\n}\n\nexport function FloatingComposer(props: Props) {\n const { activeSource } = props;\n return (\n <div\n className={`chat-composer-wrap chat-composer-source-${activeSource ?? 'none'} legacy`}\n >\n <div className=\"chat-composer-pill\">\n <Composer {...props} />\n </div>\n </div>\n );\n}","// src/web/mobile/MobileChat.tsx — mobile chat UI without info/sessions sidebars.\n// No OCR capture, no clipper, no sessions panel — pure chat thread.\nimport { useEffect, useRef, useState } from 'react';\nimport { ChatTopBar } from '../components/chat/ChatTopBar';\nimport { ChatThread } from '../components/chat/ChatThread';\nimport { FloatingComposer } from '../components/chat/FloatingComposer';\nimport { useChat } from '../components/chat/useChat';\nimport { useSlashCommands } from '../components/chat/useSlashCommands';\nimport { useToast } from '../components/Toast';\nimport type { Snapshot, Settings } from '../lib/types';\n\ninterface Props {\n snapshot: Snapshot;\n settings: Settings;\n setActiveTab?: (id: string) => void;\n initialTaskId?: string | null;\n onClearTaskId?: () => void;\n}\n\nexport function MobileChat({\n snapshot,\n settings,\n setActiveTab,\n initialTaskId,\n onClearTaskId,\n}: Props) {\n const toast = useToast();\n const chat = useChat(snapshot, settings, initialTaskId ?? '');\n useEffect(() => {\n chat.setToast({\n error: (msg: string) => toast.error(msg),\n success: (msg: string) => toast.success(msg),\n info: (msg: string) => toast.info(msg),\n warning: (msg: string) => toast.warning(msg),\n });\n }, [chat, toast]);\n\n const [text, setText] = useState('');\n const [agent, setAgent] = useState(settings.defaultAgent || 'odin');\n const [model, setModel] = useState(settings.defaultModel || '');\n const [attachments, setAttachments] = useState<string[]>([]);\n\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const { suggestions, setQuery } = useSlashCommands(snapshot);\n useEffect(() => {\n setQuery(text);\n }, [text, setQuery]);\n\n const onAttach = () => fileInputRef.current?.click();\n const onFiles = (e: React.ChangeEvent<HTMLInputElement>) => {\n const files = e.target.files;\n if (!files) return;\n const next: string[] = [];\n for (let i = 0; i < files.length; i++) next.push(files[i].name);\n setAttachments((cur) => {\n const newNames = next.filter((n) => !cur.includes(n));\n return [...cur, ...newNames];\n });\n if (fileInputRef.current) fileInputRef.current.value = '';\n };\n\n const handleSend = async () => {\n const msg = text.trim();\n if (!msg) return;\n setText('');\n setQuery('');\n const result = await chat.onSend(msg, agent, model, attachments);\n if (result.ok) chat.jumpToLatest();\n };\n\n return (\n <div className=\"chat-shell\">\n <ChatTopBar\n activeProject={snapshot.activeProject}\n sessionCount={chat.sessions.length}\n sessionsOpen={false}\n infoOpen={false}\n onToggleSessions={() => undefined}\n onToggleInfo={() => undefined}\n onOpenOverview={() => setActiveTab?.('overview')}\n />\n <div className=\"chat-body\">\n <main className=\"chat-main\">\n <ChatThread\n messages={\n chat.activeSource === 'opencode'\n ? chat.opencodeMessages\n : chat.bizarMessages\n }\n loading={chat.loading}\n activeProject={snapshot.activeProject}\n sessionId={\n chat.activeSource === 'opencode'\n ? chat.activeOpencodeSessionId ?? chat.sessionId\n : chat.sessionId\n }\n pinned={chat.pinned}\n activeSource={chat.activeSource}\n onPickSuggestion={(t) => setText(t)}\n onCopy={(m) =>\n chat.copyMessage(m as Parameters<typeof chat.copyMessage>[0])\n }\n onDelete={() => undefined}\n onTogglePin={chat.togglePin}\n onRegenerate={chat.onRegenerate}\n />\n <FloatingComposer\n agent={agent}\n setAgent={setAgent}\n model={model}\n setModel={setModel}\n text={text}\n setText={setText}\n sending={chat.sending}\n activeSource={chat.activeSource}\n onSend={handleSend}\n attachments={attachments}\n setAttachments={setAttachments}\n suggestions={suggestions}\n onPickSuggestion={(cmd) => setText(`${cmd.split(' ')[0]} `)}\n agents={snapshot.agents || []}\n onAttach={onAttach}\n sessionsOpen={false}\n infoOpen={false}\n />\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple\n style={{ display: 'none' }}\n onChange={onFiles}\n />\n </main>\n </div>\n </div>\n );\n}\n"],"names":["FloatingComposer","props","activeSource","jsx","Composer","MobileChat","snapshot","settings","setActiveTab","initialTaskId","onClearTaskId","toast","useToast","chat","useChat","useEffect","msg","text","setText","useState","agent","setAgent","model","setModel","attachments","setAttachments","fileInputRef","useRef","suggestions","setQuery","useSlashCommands","onAttach","_a","onFiles","files","next","i","cur","newNames","n","handleSend","jsxs","ChatTopBar","ChatThread","t","m","cmd"],"mappings":"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"}
1
+ {"version":3,"file":"MobileChat-9UpvDP6-.js","sources":["../../src/web/components/chat/FloatingComposer.tsx","../../src/web/mobile/MobileChat.tsx"],"sourcesContent":["// src/components/chat/FloatingComposer.tsx — sticky bottom wrapper for the composer pill.\n\nimport { Composer } from './Composer';\n\ninterface Props {\n agent: string;\n setAgent: (a: string) => void;\n model: string;\n setModel: (m: string) => void;\n text: string;\n setText: (t: string) => void;\n sending: boolean;\n onSend: () => void;\n attachments: string[];\n setAttachments: (a: string[] | ((prev: string[]) => string[])) => void;\n suggestions: Array<{ cmd: string; desc: string }>;\n onPickSuggestion: (cmd: string) => void;\n agents: Array<{ name: string }>;\n onAttach: () => void;\n sessionsOpen: boolean;\n infoOpen: boolean;\n /** Which stream will receive the next message — propagates the\n * pill border color and a small \"→ opencode\" hint. */\n activeSource?: 'bizar' | 'opencode' | null;\n}\n\nexport function FloatingComposer(props: Props) {\n const { activeSource } = props;\n return (\n <div\n className={`chat-composer-wrap chat-composer-source-${activeSource ?? 'none'} legacy`}\n >\n <div className=\"chat-composer-pill\">\n <Composer {...props} />\n </div>\n </div>\n );\n}","// src/web/mobile/MobileChat.tsx — mobile chat UI without info/sessions sidebars.\n// No OCR capture, no clipper, no sessions panel — pure chat thread.\nimport { useEffect, useRef, useState } from 'react';\nimport { ChatTopBar } from '../components/chat/ChatTopBar';\nimport { ChatThread } from '../components/chat/ChatThread';\nimport { FloatingComposer } from '../components/chat/FloatingComposer';\nimport { useChat } from '../components/chat/useChat';\nimport { useSlashCommands } from '../components/chat/useSlashCommands';\nimport { useToast } from '../components/Toast';\nimport type { Snapshot, Settings } from '../lib/types';\n\ninterface Props {\n snapshot: Snapshot;\n settings: Settings;\n setActiveTab?: (id: string) => void;\n initialTaskId?: string | null;\n onClearTaskId?: () => void;\n}\n\nexport function MobileChat({\n snapshot,\n settings,\n setActiveTab,\n initialTaskId,\n onClearTaskId,\n}: Props) {\n const toast = useToast();\n const chat = useChat(snapshot, settings, initialTaskId ?? '');\n useEffect(() => {\n chat.setToast({\n error: (msg: string) => toast.error(msg),\n success: (msg: string) => toast.success(msg),\n info: (msg: string) => toast.info(msg),\n warning: (msg: string) => toast.warning(msg),\n });\n }, [chat, toast]);\n\n const [text, setText] = useState('');\n const [agent, setAgent] = useState(settings.defaultAgent || 'odin');\n const [model, setModel] = useState(settings.defaultModel || '');\n const [attachments, setAttachments] = useState<string[]>([]);\n\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const { suggestions, setQuery } = useSlashCommands(snapshot);\n useEffect(() => {\n setQuery(text);\n }, [text, setQuery]);\n\n const onAttach = () => fileInputRef.current?.click();\n const onFiles = (e: React.ChangeEvent<HTMLInputElement>) => {\n const files = e.target.files;\n if (!files) return;\n const next: string[] = [];\n for (let i = 0; i < files.length; i++) next.push(files[i].name);\n setAttachments((cur) => {\n const newNames = next.filter((n) => !cur.includes(n));\n return [...cur, ...newNames];\n });\n if (fileInputRef.current) fileInputRef.current.value = '';\n };\n\n const handleSend = async () => {\n const msg = text.trim();\n if (!msg) return;\n setText('');\n setQuery('');\n const result = await chat.onSend(msg, agent, model, attachments);\n if (result.ok) chat.jumpToLatest();\n };\n\n return (\n <div className=\"chat-shell\">\n <ChatTopBar\n activeProject={snapshot.activeProject}\n sessionCount={chat.sessions.length}\n sessionsOpen={false}\n infoOpen={false}\n onToggleSessions={() => undefined}\n onToggleInfo={() => undefined}\n onOpenOverview={() => setActiveTab?.('overview')}\n />\n <div className=\"chat-body\">\n <main className=\"chat-main\">\n <ChatThread\n messages={\n chat.activeSource === 'opencode'\n ? chat.opencodeMessages\n : chat.bizarMessages\n }\n loading={chat.loading}\n activeProject={snapshot.activeProject}\n sessionId={\n chat.activeSource === 'opencode'\n ? chat.activeOpencodeSessionId ?? chat.sessionId\n : chat.sessionId\n }\n pinned={chat.pinned}\n activeSource={chat.activeSource}\n onPickSuggestion={(t) => setText(t)}\n onCopy={(m) =>\n chat.copyMessage(m as Parameters<typeof chat.copyMessage>[0])\n }\n onDelete={() => undefined}\n onTogglePin={chat.togglePin}\n onRegenerate={chat.onRegenerate}\n />\n <FloatingComposer\n agent={agent}\n setAgent={setAgent}\n model={model}\n setModel={setModel}\n text={text}\n setText={setText}\n sending={chat.sending}\n activeSource={chat.activeSource}\n onSend={handleSend}\n attachments={attachments}\n setAttachments={setAttachments}\n suggestions={suggestions}\n onPickSuggestion={(cmd) => setText(`${cmd.split(' ')[0]} `)}\n agents={snapshot.agents || []}\n onAttach={onAttach}\n sessionsOpen={false}\n infoOpen={false}\n />\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple\n style={{ display: 'none' }}\n onChange={onFiles}\n />\n </main>\n </div>\n </div>\n );\n}\n"],"names":["FloatingComposer","props","activeSource","jsx","Composer","MobileChat","snapshot","settings","setActiveTab","initialTaskId","onClearTaskId","toast","useToast","chat","useChat","useEffect","msg","text","setText","useState","agent","setAgent","model","setModel","attachments","setAttachments","fileInputRef","useRef","suggestions","setQuery","useSlashCommands","onAttach","_a","onFiles","files","next","i","cur","newNames","n","handleSend","jsxs","ChatTopBar","ChatThread","t","m","cmd"],"mappings":"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"}
@@ -1 +1 @@
1
- import{r as c,j as e}from"./react-vendor-Dn4wqh4Z.js";import{a as b,S,c as g}from"./mobile-layout-DqTxvXZp.js";import{C as L,a as z,b as T,B as k,G as E,E as R,S as B,U as M,H as U,T as G,c as w}from"./EnvVarsSection-DqvB8ZcJ.js";import{u as A}from"./Toast-CcZVVN4i.js";import{j as f,O as I,aS as H,a9 as P,s as V,aB as $,x as v,R as C,aE as D,J as K,e as O}from"./icons-OMEGx5KA.js";function F(){const s=A(),[i,t]=c.useState(!0),[a,n]=c.useState(!1),[r,d]=c.useState(""),[j]=c.useState(""),[y,u]=c.useState(0);c.useEffect(()=>{b.get("/memory/config/global").then(l=>{var m,p;d(((p=(m=l.config)==null?void 0:m.git)==null?void 0:p.remoteUrl)||""),t(!1)}).catch(()=>t(!1))},[y]);const h=async()=>{n(!0);try{await b.put("/memory/config/global",{git:{remoteUrl:r}}),s.success("Memory config saved."),u(l=>l+1)}catch(l){s.error(`Save failed: ${l.message}`)}finally{n(!1)}};return e.jsxs(L,{id:"settings-memory","data-section":"memory",children:[e.jsxs(z,{children:[e.jsx(f,{size:14})," Memory vault"]}),e.jsx(T,{children:"The vault lives at a default location on disk. Only the git remote URL needs to be configured to enable sync across machines."}),i?e.jsx("div",{className:"flex-center",style:{padding:24},children:e.jsx(S,{size:"sm"})}):e.jsxs("div",{className:"settings-fields",children:[e.jsxs("div",{className:"field",children:[e.jsx("label",{className:"field-label",children:"Vault path"}),e.jsx("div",{className:"field-readonly mono muted",style:{fontSize:12,padding:"6px 0"},children:j||"~/.local/share/bizar/memory"})]}),e.jsxs("div",{className:"field",children:[e.jsxs("label",{className:"field-label",htmlFor:"set-memory-git-remote",children:[e.jsx(I,{size:12,style:{display:"inline",marginRight:4}}),"Git remote URL"]}),e.jsx("input",{id:"set-memory-git-remote",className:"input mono",type:"text",value:r,onChange:l=>d(l.target.value),placeholder:"git@github.com:org/repo.git"}),e.jsx("span",{className:"field-hint",children:"Leave empty to use local-only mode (no git sync)."})]}),e.jsx("div",{style:{marginTop:12},children:e.jsxs(k,{variant:"primary",size:"sm",onClick:h,disabled:a,children:[a?e.jsx(H,{size:12,className:"memory-spin"}):e.jsx(P,{size:12}),"Save memory config"]})})]})]})}function J({settings:s,onSettingsChange:i,autoSave:t}){const a=(r,d)=>{i==null||i(r,d),t==null||t(r,d)},n=r=>{i==null||i("ui",{...s.ui,...r}),t==null||t("ui",{...s.ui,...r})};return e.jsx(E,{settings:s,patchUi:n,patchTop:a,autoSave:t})}function W({settings:s,onSettingsChange:i,autoSave:t}){return e.jsxs("div",{style:{fontSize:13,color:"var(--text-dim)",padding:"8px 0"},children:[e.jsx("p",{style:{marginBottom:8},children:"Provider management is available on desktop."}),e.jsx("a",{href:"/?desktop=1#settings-providers",className:"mobile-btn mobile-btn-secondary",style:{display:"inline-block",fontSize:12,padding:"6px 12px"},children:"Open desktop to manage providers"})]})}function q(){return e.jsx(R,{})}function Q(){return e.jsx(F,{})}function X({settings:s,onSettingsChange:i,autoSave:t}){const a=(n,r)=>{i==null||i(n,r),t==null||t(n,r)};return e.jsx(B,{settings:s,patchTop:a})}function Y(){return e.jsx(M,{})}function Z({settings:s}){const[i,t]=c.useState(s),[a,n]=c.useState(!1);return e.jsx(U,{settings:i,setSettings:t,setDirty:n})}function _(){return e.jsx(G,{})}function ee({settings:s}){const i=s.about||{version:"—",homepage:"https://github.com/DrB0rk/BizarHarness",license:"MIT"};return e.jsx(w,{about:i})}function ae({settings:s,onSettingsChange:i,autoSave:t,snapshot:a}){var h,l,m,p;const[n,r]=c.useState(""),[d,j]=c.useState(null),u=[{id:"general",title:"General",icon:V,description:"Theme, accent, layout",component:e.jsx(J,{settings:s,onSettingsChange:i,autoSave:t})},{id:"providers",title:"AI Providers",icon:f,description:`${((h=a==null?void 0:a.providers)==null?void 0:h.length)??0} configured`,component:e.jsx(W,{settings:s,onSettingsChange:i,autoSave:t})},{id:"env-vars",title:"Environment Variables",icon:$,description:"API keys, secrets",component:e.jsx(q,{})},{id:"memory",title:"Memory Vault",icon:f,description:"Git remote, LightRAG config",component:e.jsx(Q,{})},{id:"system-llm",title:"System LLM",icon:v,description:((l=s.systemLlm)==null?void 0:l.model)||"not set",component:e.jsx(X,{settings:s,onSettingsChange:i,autoSave:t})},{id:"updates",title:"Updates",icon:C,description:"Check for updates",component:e.jsx(Y,{})},{id:"headroom",title:"Headroom",icon:v,description:(m=s.headroom)!=null&&m.enabled?"Enabled":"Disabled",component:e.jsx(Z,{settings:s})},{id:"tailscale",title:"Tailscale",icon:D,description:"Tailscale serve & auth",component:e.jsx(_,{})},{id:"about",title:"About",icon:K,description:`Bizar v${((p=s.about)==null?void 0:p.version)||"—"}`,component:e.jsx(ee,{settings:s})}].filter(o=>!n||o.title.toLowerCase().includes(n.toLowerCase())||o.description.toLowerCase().includes(n.toLowerCase()));return e.jsxs("div",{className:"mobile-settings",children:[e.jsxs("div",{className:"mobile-settings-search",children:[e.jsx(se,{}),e.jsx("input",{value:n,onChange:o=>r(o.target.value),placeholder:"Search settings...","aria-label":"Search settings"})]}),e.jsxs("div",{className:"mobile-settings-list",children:[u.map(o=>{const N=o.icon,x=d===o.id;return e.jsxs("div",{className:g("mobile-settings-item",x&&"is-expanded"),children:[e.jsxs("button",{className:"mobile-settings-item-head",onClick:()=>j(x?null:o.id),"aria-expanded":x,"aria-controls":`mobile-settings-body-${o.id}`,children:[e.jsx("div",{className:"mobile-settings-item-icon",children:e.jsx(N,{size:18})}),e.jsxs("div",{className:"mobile-settings-item-text",children:[e.jsx("div",{className:"mobile-settings-item-title",children:o.title}),e.jsx("div",{className:"mobile-settings-item-desc",children:o.description})]}),e.jsx(O,{size:16,className:g("mobile-settings-item-chevron",x&&"is-rotated")})]}),x&&e.jsx("div",{id:`mobile-settings-body-${o.id}`,className:"mobile-settings-item-body",children:o.component})]},o.id)}),u.length===0&&e.jsxs("div",{className:"mobile-settings-empty",children:['No settings match "',n,'"']})]})]})}function se(){return e.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("circle",{cx:"11",cy:"11",r:"8"}),e.jsx("path",{d:"m21 21-4.35-4.35"})]})}export{ae as MobileSettings};
1
+ import{r as c,j as e}from"./react-vendor-Dn4wqh4Z.js";import{a as b,S,c as g}from"./mobile-layout-BjkoHh1W.js";import{C as L,a as z,b as T,B as k,G as E,E as R,S as B,U as M,H as U,T as G,c as w}from"./EnvVarsSection-DhLHZ5ua.js";import{u as A}from"./Toast-BlcKl_dN.js";import{j as f,O as I,aS as H,a9 as P,s as V,aB as $,x as v,R as C,aE as D,J as K,e as O}from"./icons-CMPxNV8t.js";function F(){const s=A(),[i,t]=c.useState(!0),[a,n]=c.useState(!1),[r,d]=c.useState(""),[j]=c.useState(""),[y,u]=c.useState(0);c.useEffect(()=>{b.get("/memory/config/global").then(l=>{var m,p;d(((p=(m=l.config)==null?void 0:m.git)==null?void 0:p.remoteUrl)||""),t(!1)}).catch(()=>t(!1))},[y]);const h=async()=>{n(!0);try{await b.put("/memory/config/global",{git:{remoteUrl:r}}),s.success("Memory config saved."),u(l=>l+1)}catch(l){s.error(`Save failed: ${l.message}`)}finally{n(!1)}};return e.jsxs(L,{id:"settings-memory","data-section":"memory",children:[e.jsxs(z,{children:[e.jsx(f,{size:14})," Memory vault"]}),e.jsx(T,{children:"The vault lives at a default location on disk. Only the git remote URL needs to be configured to enable sync across machines."}),i?e.jsx("div",{className:"flex-center",style:{padding:24},children:e.jsx(S,{size:"sm"})}):e.jsxs("div",{className:"settings-fields",children:[e.jsxs("div",{className:"field",children:[e.jsx("label",{className:"field-label",children:"Vault path"}),e.jsx("div",{className:"field-readonly mono muted",style:{fontSize:12,padding:"6px 0"},children:j||"~/.local/share/bizar/memory"})]}),e.jsxs("div",{className:"field",children:[e.jsxs("label",{className:"field-label",htmlFor:"set-memory-git-remote",children:[e.jsx(I,{size:12,style:{display:"inline",marginRight:4}}),"Git remote URL"]}),e.jsx("input",{id:"set-memory-git-remote",className:"input mono",type:"text",value:r,onChange:l=>d(l.target.value),placeholder:"git@github.com:org/repo.git"}),e.jsx("span",{className:"field-hint",children:"Leave empty to use local-only mode (no git sync)."})]}),e.jsx("div",{style:{marginTop:12},children:e.jsxs(k,{variant:"primary",size:"sm",onClick:h,disabled:a,children:[a?e.jsx(H,{size:12,className:"memory-spin"}):e.jsx(P,{size:12}),"Save memory config"]})})]})]})}function J({settings:s,onSettingsChange:i,autoSave:t}){const a=(r,d)=>{i==null||i(r,d),t==null||t(r,d)},n=r=>{i==null||i("ui",{...s.ui,...r}),t==null||t("ui",{...s.ui,...r})};return e.jsx(E,{settings:s,patchUi:n,patchTop:a,autoSave:t})}function W({settings:s,onSettingsChange:i,autoSave:t}){return e.jsxs("div",{style:{fontSize:13,color:"var(--text-dim)",padding:"8px 0"},children:[e.jsx("p",{style:{marginBottom:8},children:"Provider management is available on desktop."}),e.jsx("a",{href:"/?desktop=1#settings-providers",className:"mobile-btn mobile-btn-secondary",style:{display:"inline-block",fontSize:12,padding:"6px 12px"},children:"Open desktop to manage providers"})]})}function q(){return e.jsx(R,{})}function Q(){return e.jsx(F,{})}function X({settings:s,onSettingsChange:i,autoSave:t}){const a=(n,r)=>{i==null||i(n,r),t==null||t(n,r)};return e.jsx(B,{settings:s,patchTop:a})}function Y(){return e.jsx(M,{})}function Z({settings:s}){const[i,t]=c.useState(s),[a,n]=c.useState(!1);return e.jsx(U,{settings:i,setSettings:t,setDirty:n})}function _(){return e.jsx(G,{})}function ee({settings:s}){const i=s.about||{version:"—",homepage:"https://github.com/DrB0rk/BizarHarness",license:"MIT"};return e.jsx(w,{about:i})}function ae({settings:s,onSettingsChange:i,autoSave:t,snapshot:a}){var h,l,m,p;const[n,r]=c.useState(""),[d,j]=c.useState(null),u=[{id:"general",title:"General",icon:V,description:"Theme, accent, layout",component:e.jsx(J,{settings:s,onSettingsChange:i,autoSave:t})},{id:"providers",title:"AI Providers",icon:f,description:`${((h=a==null?void 0:a.providers)==null?void 0:h.length)??0} configured`,component:e.jsx(W,{settings:s,onSettingsChange:i,autoSave:t})},{id:"env-vars",title:"Environment Variables",icon:$,description:"API keys, secrets",component:e.jsx(q,{})},{id:"memory",title:"Memory Vault",icon:f,description:"Git remote, LightRAG config",component:e.jsx(Q,{})},{id:"system-llm",title:"System LLM",icon:v,description:((l=s.systemLlm)==null?void 0:l.model)||"not set",component:e.jsx(X,{settings:s,onSettingsChange:i,autoSave:t})},{id:"updates",title:"Updates",icon:C,description:"Check for updates",component:e.jsx(Y,{})},{id:"headroom",title:"Headroom",icon:v,description:(m=s.headroom)!=null&&m.enabled?"Enabled":"Disabled",component:e.jsx(Z,{settings:s})},{id:"tailscale",title:"Tailscale",icon:D,description:"Tailscale serve & auth",component:e.jsx(_,{})},{id:"about",title:"About",icon:K,description:`Bizar v${((p=s.about)==null?void 0:p.version)||"—"}`,component:e.jsx(ee,{settings:s})}].filter(o=>!n||o.title.toLowerCase().includes(n.toLowerCase())||o.description.toLowerCase().includes(n.toLowerCase()));return e.jsxs("div",{className:"mobile-settings",children:[e.jsxs("div",{className:"mobile-settings-search",children:[e.jsx(se,{}),e.jsx("input",{value:n,onChange:o=>r(o.target.value),placeholder:"Search settings...","aria-label":"Search settings"})]}),e.jsxs("div",{className:"mobile-settings-list",children:[u.map(o=>{const N=o.icon,x=d===o.id;return e.jsxs("div",{className:g("mobile-settings-item",x&&"is-expanded"),children:[e.jsxs("button",{className:"mobile-settings-item-head",onClick:()=>j(x?null:o.id),"aria-expanded":x,"aria-controls":`mobile-settings-body-${o.id}`,children:[e.jsx("div",{className:"mobile-settings-item-icon",children:e.jsx(N,{size:18})}),e.jsxs("div",{className:"mobile-settings-item-text",children:[e.jsx("div",{className:"mobile-settings-item-title",children:o.title}),e.jsx("div",{className:"mobile-settings-item-desc",children:o.description})]}),e.jsx(O,{size:16,className:g("mobile-settings-item-chevron",x&&"is-rotated")})]}),x&&e.jsx("div",{id:`mobile-settings-body-${o.id}`,className:"mobile-settings-item-body",children:o.component})]},o.id)}),u.length===0&&e.jsxs("div",{className:"mobile-settings-empty",children:['No settings match "',n,'"']})]})]})}function se(){return e.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("circle",{cx:"11",cy:"11",r:"8"}),e.jsx("path",{d:"m21 21-4.35-4.35"})]})}export{ae as MobileSettings};
@@ -1 +1 @@
1
- {"version":3,"file":"MobileSettings-CVW9VhEo.js","sources":["../../src/web/views/settings/MemorySection.tsx","../../src/web/mobile/MobileSettings.tsx"],"sourcesContent":["// src/web/views/settings/MemorySection.tsx — memory vault + git config for Settings.\nimport React, { useEffect, useState } from 'react';\nimport { Brain, GitBranch, Loader2, Save } from 'lucide-react';\nimport { Button } from '../../components/Button';\nimport { Card, CardTitle, CardMeta } from '../../components/Card';\nimport { Spinner } from '../../components/Spinner';\nimport { useToast } from '../../components/Toast';\nimport { api } from '../../lib/api';\n\ntype GitConfig = {\n remoteUrl?: string;\n};\n\ntype GlobalConfig = {\n git?: GitConfig;\n};\n\nexport function MemorySection() {\n const toast = useToast();\n const [loading, setLoading] = useState(true);\n const [saving, setSaving] = useState(false);\n const [remoteUrl, setRemoteUrl] = useState('');\n const [vaultPath] = useState<string>(''); // server-side default, not user-editable\n const [refreshKey, setRefreshKey] = useState(0);\n\n useEffect(() => {\n api.get<{ config: GlobalConfig; path?: string }>('/memory/config/global')\n .then((r) => {\n setRemoteUrl(r.config?.git?.remoteUrl || '');\n setLoading(false);\n })\n .catch(() => setLoading(false));\n }, [refreshKey]);\n\n const onSave = async () => {\n setSaving(true);\n try {\n await api.put('/memory/config/global', { git: { remoteUrl } });\n toast.success('Memory config saved.');\n setRefreshKey((k) => k + 1);\n } catch (err) {\n toast.error(`Save failed: ${(err as Error).message}`);\n } finally {\n setSaving(false);\n }\n };\n\n return (\n <Card id=\"settings-memory\" data-section=\"memory\">\n <CardTitle><Brain size={14} /> Memory vault</CardTitle>\n <CardMeta>\n The vault lives at a default location on disk. Only the git remote URL\n needs to be configured to enable sync across machines.\n </CardMeta>\n\n {loading ? (\n <div className=\"flex-center\" style={{ padding: 24 }}>\n <Spinner size=\"sm\" />\n </div>\n ) : (\n <div className=\"settings-fields\">\n <div className=\"field\">\n <label className=\"field-label\">Vault path</label>\n <div className=\"field-readonly mono muted\" style={{ fontSize: 12, padding: '6px 0' }}>\n {vaultPath || '~/.local/share/bizar/memory'}\n </div>\n </div>\n\n <div className=\"field\">\n <label className=\"field-label\" htmlFor=\"set-memory-git-remote\">\n <GitBranch size={12} style={{ display: 'inline', marginRight: 4 }} />\n Git remote URL\n </label>\n <input\n id=\"set-memory-git-remote\"\n className=\"input mono\"\n type=\"text\"\n value={remoteUrl}\n onChange={(e) => setRemoteUrl(e.target.value)}\n placeholder=\"git@github.com:org/repo.git\"\n />\n <span className=\"field-hint\">Leave empty to use local-only mode (no git sync).</span>\n </div>\n\n <div style={{ marginTop: 12 }}>\n <Button\n variant=\"primary\"\n size=\"sm\"\n onClick={onSave}\n disabled={saving}\n >\n {saving ? <Loader2 size={12} className=\"memory-spin\" /> : <Save size={12} />}\n Save memory config\n </Button>\n </div>\n </div>\n )}\n </Card>\n );\n}\n","// src/web/mobile/MobileSettings.tsx — v5.4 mobile settings with full desktop parity.\n// All 9 sections in an accordion layout with search.\nimport { useState } from 'react';\nimport {\n Settings2, Brain, KeyRound, Cpu, RefreshCw, Globe, Info, ChevronRight,\n} from 'lucide-react';\nimport { cn } from '../lib/utils';\nimport type { Settings, Snapshot } from '../lib/types';\n\n// Sub-section components — each renders its section content inline.\nimport { GeneralSection } from '../views/settings/GeneralSection';\nimport { EnvVarsSection } from '../views/settings/EnvVarsSection';\nimport { MemorySection } from '../views/settings/MemorySection';\nimport { SystemLlmSection } from '../views/settings/SystemLlmSection';\nimport { UpdatesSection } from '../views/settings/UpdatesSection';\nimport { HeadroomSection } from '../views/settings/HeadroomSection';\nimport { TailscaleSettings } from '../components/TailscaleSettings';\nimport { ActivitySection } from '../views/settings/ActivitySection';\n\n// Lazy-load heavy sections that pull in large dependencies.\nimport React from 'react';\n\ntype Props = {\n settings: Settings;\n /** Called when the user changes any top-level setting */\n onSettingsChange?: <K extends keyof Settings>(key: K, value: Settings[K]) => void;\n /** Debounced auto-save to API (key, value) */\n autoSave?: (key: keyof Settings, value: Settings[keyof Settings]) => void;\n /** Optional snapshot for counts / agent list */\n snapshot?: Snapshot | null;\n /** v5.3 compatibility — called after settings are saved (MobileApp.tsx passes refreshSnapshot) */\n onRefresh?: () => Promise<void>;\n};\n\n// ─── Section definitions ─────────────────────────────────────────────────────\n\nfunction GeneralSettings({ settings, onSettingsChange, autoSave }: Props) {\n const patchTop = <K extends keyof Settings>(key: K, value: Settings[K]) => {\n onSettingsChange?.(key, value);\n autoSave?.(key, value);\n };\n const patchUi = (patch: Partial<Settings['ui']>) => {\n onSettingsChange?.('ui', { ...settings.ui, ...patch });\n autoSave?.('ui', { ...settings.ui, ...patch });\n };\n return (\n <GeneralSection\n settings={settings}\n patchUi={patchUi}\n patchTop={patchTop}\n autoSave={autoSave}\n />\n );\n}\n\nfunction ProvidersSettings({ settings, onSettingsChange, autoSave }: Props) {\n // Providers are managed server-side; show a link to the desktop providers view.\n // Mobile can't add/edit providers without more complex auth flow.\n void settings; void onSettingsChange; void autoSave;\n return (\n <div style={{ fontSize: 13, color: 'var(--text-dim)', padding: '8px 0' }}>\n <p style={{ marginBottom: 8 }}>\n Provider management is available on desktop.\n </p>\n <a href=\"/?desktop=1#settings-providers\" className=\"mobile-btn mobile-btn-secondary\" style={{ display: 'inline-block', fontSize: 12, padding: '6px 12px' }}>\n Open desktop to manage providers\n </a>\n </div>\n );\n}\n\nfunction EnvVarsSettings() {\n return <EnvVarsSection />;\n}\n\nfunction MemorySettings() {\n return <MemorySection />;\n}\n\nfunction SystemLlmSettings({ settings, onSettingsChange, autoSave }: Props) {\n const patchTop = <K extends keyof Settings>(key: K, value: Settings[K]) => {\n onSettingsChange?.(key, value);\n autoSave?.(key, value);\n };\n return <SystemLlmSection settings={settings} patchTop={patchTop} />;\n}\n\nfunction UpdatesSettings() {\n return <UpdatesSection />;\n}\n\nfunction HeadroomSettingsSection({ settings }: { settings: Settings }) {\n const [localSettings, setLocalSettings] = useState(settings);\n const [dirty, setDirty] = useState(false);\n return (\n <HeadroomSection\n settings={localSettings}\n setSettings={setLocalSettings as React.Dispatch<React.SetStateAction<Settings>>}\n setDirty={setDirty}\n />\n );\n}\n\nfunction TailscaleSettingsMobile() {\n return <TailscaleSettings />;\n}\n\nfunction AboutSection({ settings }: { settings: Settings }) {\n const about = settings.about || { version: '—', homepage: 'https://github.com/DrB0rk/BizarHarness', license: 'MIT' };\n return <ActivitySection about={about} />;\n}\n\n// ─── Main component ──────────────────────────────────────────────────────────\n\nexport function MobileSettings({ settings, onSettingsChange, autoSave, snapshot }: Props) {\n const [search, setSearch] = useState('');\n const [expandedSection, setExpandedSection] = useState<string | null>(null);\n\n const sections = [\n {\n id: 'general',\n title: 'General',\n icon: Settings2,\n description: 'Theme, accent, layout',\n component: <GeneralSettings settings={settings} onSettingsChange={onSettingsChange} autoSave={autoSave} />,\n },\n {\n id: 'providers',\n title: 'AI Providers',\n icon: Brain,\n description: `${snapshot?.providers?.length ?? 0} configured`,\n component: <ProvidersSettings settings={settings} onSettingsChange={onSettingsChange} autoSave={autoSave} />,\n },\n {\n id: 'env-vars',\n title: 'Environment Variables',\n icon: KeyRound,\n description: 'API keys, secrets',\n component: <EnvVarsSettings />,\n },\n {\n id: 'memory',\n title: 'Memory Vault',\n icon: Brain,\n description: 'Git remote, LightRAG config',\n component: <MemorySettings />,\n },\n {\n id: 'system-llm',\n title: 'System LLM',\n icon: Cpu,\n description: settings.systemLlm?.model || 'not set',\n component: <SystemLlmSettings settings={settings} onSettingsChange={onSettingsChange} autoSave={autoSave} />,\n },\n {\n id: 'updates',\n title: 'Updates',\n icon: RefreshCw,\n description: 'Check for updates',\n component: <UpdatesSettings />,\n },\n {\n id: 'headroom',\n title: 'Headroom',\n icon: Cpu,\n description: settings.headroom?.enabled ? 'Enabled' : 'Disabled',\n component: <HeadroomSettingsSection settings={settings} />,\n },\n {\n id: 'tailscale',\n title: 'Tailscale',\n icon: Globe,\n description: 'Tailscale serve & auth',\n component: <TailscaleSettingsMobile />,\n },\n {\n id: 'about',\n title: 'About',\n icon: Info,\n description: `Bizar v${settings.about?.version || '—'}`,\n component: <AboutSection settings={settings} />,\n },\n ];\n\n const filtered = sections.filter(\n (s) =>\n !search ||\n s.title.toLowerCase().includes(search.toLowerCase()) ||\n s.description.toLowerCase().includes(search.toLowerCase()),\n );\n\n return (\n <div className=\"mobile-settings\">\n <div className=\"mobile-settings-search\">\n <SearchIcon />\n <input\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder=\"Search settings...\"\n aria-label=\"Search settings\"\n />\n </div>\n\n <div className=\"mobile-settings-list\">\n {filtered.map((s) => {\n const Icon = s.icon;\n const isExpanded = expandedSection === s.id;\n return (\n <div key={s.id} className={cn('mobile-settings-item', isExpanded && 'is-expanded')}>\n <button\n className=\"mobile-settings-item-head\"\n onClick={() => setExpandedSection(isExpanded ? null : s.id)}\n aria-expanded={isExpanded}\n aria-controls={`mobile-settings-body-${s.id}`}\n >\n <div className=\"mobile-settings-item-icon\">\n <Icon size={18} />\n </div>\n <div className=\"mobile-settings-item-text\">\n <div className=\"mobile-settings-item-title\">{s.title}</div>\n <div className=\"mobile-settings-item-desc\">{s.description}</div>\n </div>\n <ChevronRight\n size={16}\n className={cn('mobile-settings-item-chevron', isExpanded && 'is-rotated')}\n />\n </button>\n {isExpanded && (\n <div id={`mobile-settings-body-${s.id}`} className=\"mobile-settings-item-body\">\n {s.component}\n </div>\n )}\n </div>\n );\n })}\n {filtered.length === 0 && (\n <div className=\"mobile-settings-empty\">No settings match \"{search}\"</div>\n )}\n </div>\n </div>\n );\n}\n\nfunction SearchIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <path d=\"m21 21-4.35-4.35\" />\n </svg>\n );\n}\n"],"names":["MemorySection","toast","useToast","loading","setLoading","useState","saving","setSaving","remoteUrl","setRemoteUrl","vaultPath","refreshKey","setRefreshKey","useEffect","api","r","_b","_a","onSave","k","err","jsxs","Card","CardTitle","jsx","Brain","CardMeta","Spinner","GitBranch","e","Button","Loader2","Save","GeneralSettings","settings","onSettingsChange","autoSave","patchTop","key","value","patchUi","patch","GeneralSection","ProvidersSettings","EnvVarsSettings","EnvVarsSection","MemorySettings","SystemLlmSettings","SystemLlmSection","UpdatesSettings","UpdatesSection","HeadroomSettingsSection","localSettings","setLocalSettings","dirty","setDirty","HeadroomSection","TailscaleSettingsMobile","TailscaleSettings","AboutSection","about","ActivitySection","MobileSettings","snapshot","search","setSearch","expandedSection","setExpandedSection","filtered","Settings2","KeyRound","Cpu","RefreshCw","_c","Globe","Info","_d","s","SearchIcon","Icon","isExpanded","cn","ChevronRight"],"mappings":"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"}
1
+ {"version":3,"file":"MobileSettings-BFmN9ZWR.js","sources":["../../src/web/views/settings/MemorySection.tsx","../../src/web/mobile/MobileSettings.tsx"],"sourcesContent":["// src/web/views/settings/MemorySection.tsx — memory vault + git config for Settings.\nimport React, { useEffect, useState } from 'react';\nimport { Brain, GitBranch, Loader2, Save } from 'lucide-react';\nimport { Button } from '../../components/Button';\nimport { Card, CardTitle, CardMeta } from '../../components/Card';\nimport { Spinner } from '../../components/Spinner';\nimport { useToast } from '../../components/Toast';\nimport { api } from '../../lib/api';\n\ntype GitConfig = {\n remoteUrl?: string;\n};\n\ntype GlobalConfig = {\n git?: GitConfig;\n};\n\nexport function MemorySection() {\n const toast = useToast();\n const [loading, setLoading] = useState(true);\n const [saving, setSaving] = useState(false);\n const [remoteUrl, setRemoteUrl] = useState('');\n const [vaultPath] = useState<string>(''); // server-side default, not user-editable\n const [refreshKey, setRefreshKey] = useState(0);\n\n useEffect(() => {\n api.get<{ config: GlobalConfig; path?: string }>('/memory/config/global')\n .then((r) => {\n setRemoteUrl(r.config?.git?.remoteUrl || '');\n setLoading(false);\n })\n .catch(() => setLoading(false));\n }, [refreshKey]);\n\n const onSave = async () => {\n setSaving(true);\n try {\n await api.put('/memory/config/global', { git: { remoteUrl } });\n toast.success('Memory config saved.');\n setRefreshKey((k) => k + 1);\n } catch (err) {\n toast.error(`Save failed: ${(err as Error).message}`);\n } finally {\n setSaving(false);\n }\n };\n\n return (\n <Card id=\"settings-memory\" data-section=\"memory\">\n <CardTitle><Brain size={14} /> Memory vault</CardTitle>\n <CardMeta>\n The vault lives at a default location on disk. Only the git remote URL\n needs to be configured to enable sync across machines.\n </CardMeta>\n\n {loading ? (\n <div className=\"flex-center\" style={{ padding: 24 }}>\n <Spinner size=\"sm\" />\n </div>\n ) : (\n <div className=\"settings-fields\">\n <div className=\"field\">\n <label className=\"field-label\">Vault path</label>\n <div className=\"field-readonly mono muted\" style={{ fontSize: 12, padding: '6px 0' }}>\n {vaultPath || '~/.local/share/bizar/memory'}\n </div>\n </div>\n\n <div className=\"field\">\n <label className=\"field-label\" htmlFor=\"set-memory-git-remote\">\n <GitBranch size={12} style={{ display: 'inline', marginRight: 4 }} />\n Git remote URL\n </label>\n <input\n id=\"set-memory-git-remote\"\n className=\"input mono\"\n type=\"text\"\n value={remoteUrl}\n onChange={(e) => setRemoteUrl(e.target.value)}\n placeholder=\"git@github.com:org/repo.git\"\n />\n <span className=\"field-hint\">Leave empty to use local-only mode (no git sync).</span>\n </div>\n\n <div style={{ marginTop: 12 }}>\n <Button\n variant=\"primary\"\n size=\"sm\"\n onClick={onSave}\n disabled={saving}\n >\n {saving ? <Loader2 size={12} className=\"memory-spin\" /> : <Save size={12} />}\n Save memory config\n </Button>\n </div>\n </div>\n )}\n </Card>\n );\n}\n","// src/web/mobile/MobileSettings.tsx — v5.4 mobile settings with full desktop parity.\n// All 9 sections in an accordion layout with search.\nimport { useState } from 'react';\nimport {\n Settings2, Brain, KeyRound, Cpu, RefreshCw, Globe, Info, ChevronRight,\n} from 'lucide-react';\nimport { cn } from '../lib/utils';\nimport type { Settings, Snapshot } from '../lib/types';\n\n// Sub-section components — each renders its section content inline.\nimport { GeneralSection } from '../views/settings/GeneralSection';\nimport { EnvVarsSection } from '../views/settings/EnvVarsSection';\nimport { MemorySection } from '../views/settings/MemorySection';\nimport { SystemLlmSection } from '../views/settings/SystemLlmSection';\nimport { UpdatesSection } from '../views/settings/UpdatesSection';\nimport { HeadroomSection } from '../views/settings/HeadroomSection';\nimport { TailscaleSettings } from '../components/TailscaleSettings';\nimport { ActivitySection } from '../views/settings/ActivitySection';\n\n// Lazy-load heavy sections that pull in large dependencies.\nimport React from 'react';\n\ntype Props = {\n settings: Settings;\n /** Called when the user changes any top-level setting */\n onSettingsChange?: <K extends keyof Settings>(key: K, value: Settings[K]) => void;\n /** Debounced auto-save to API (key, value) */\n autoSave?: (key: keyof Settings, value: Settings[keyof Settings]) => void;\n /** Optional snapshot for counts / agent list */\n snapshot?: Snapshot | null;\n /** v5.3 compatibility — called after settings are saved (MobileApp.tsx passes refreshSnapshot) */\n onRefresh?: () => Promise<void>;\n};\n\n// ─── Section definitions ─────────────────────────────────────────────────────\n\nfunction GeneralSettings({ settings, onSettingsChange, autoSave }: Props) {\n const patchTop = <K extends keyof Settings>(key: K, value: Settings[K]) => {\n onSettingsChange?.(key, value);\n autoSave?.(key, value);\n };\n const patchUi = (patch: Partial<Settings['ui']>) => {\n onSettingsChange?.('ui', { ...settings.ui, ...patch });\n autoSave?.('ui', { ...settings.ui, ...patch });\n };\n return (\n <GeneralSection\n settings={settings}\n patchUi={patchUi}\n patchTop={patchTop}\n autoSave={autoSave}\n />\n );\n}\n\nfunction ProvidersSettings({ settings, onSettingsChange, autoSave }: Props) {\n // Providers are managed server-side; show a link to the desktop providers view.\n // Mobile can't add/edit providers without more complex auth flow.\n void settings; void onSettingsChange; void autoSave;\n return (\n <div style={{ fontSize: 13, color: 'var(--text-dim)', padding: '8px 0' }}>\n <p style={{ marginBottom: 8 }}>\n Provider management is available on desktop.\n </p>\n <a href=\"/?desktop=1#settings-providers\" className=\"mobile-btn mobile-btn-secondary\" style={{ display: 'inline-block', fontSize: 12, padding: '6px 12px' }}>\n Open desktop to manage providers\n </a>\n </div>\n );\n}\n\nfunction EnvVarsSettings() {\n return <EnvVarsSection />;\n}\n\nfunction MemorySettings() {\n return <MemorySection />;\n}\n\nfunction SystemLlmSettings({ settings, onSettingsChange, autoSave }: Props) {\n const patchTop = <K extends keyof Settings>(key: K, value: Settings[K]) => {\n onSettingsChange?.(key, value);\n autoSave?.(key, value);\n };\n return <SystemLlmSection settings={settings} patchTop={patchTop} />;\n}\n\nfunction UpdatesSettings() {\n return <UpdatesSection />;\n}\n\nfunction HeadroomSettingsSection({ settings }: { settings: Settings }) {\n const [localSettings, setLocalSettings] = useState(settings);\n const [dirty, setDirty] = useState(false);\n return (\n <HeadroomSection\n settings={localSettings}\n setSettings={setLocalSettings as React.Dispatch<React.SetStateAction<Settings>>}\n setDirty={setDirty}\n />\n );\n}\n\nfunction TailscaleSettingsMobile() {\n return <TailscaleSettings />;\n}\n\nfunction AboutSection({ settings }: { settings: Settings }) {\n const about = settings.about || { version: '—', homepage: 'https://github.com/DrB0rk/BizarHarness', license: 'MIT' };\n return <ActivitySection about={about} />;\n}\n\n// ─── Main component ──────────────────────────────────────────────────────────\n\nexport function MobileSettings({ settings, onSettingsChange, autoSave, snapshot }: Props) {\n const [search, setSearch] = useState('');\n const [expandedSection, setExpandedSection] = useState<string | null>(null);\n\n const sections = [\n {\n id: 'general',\n title: 'General',\n icon: Settings2,\n description: 'Theme, accent, layout',\n component: <GeneralSettings settings={settings} onSettingsChange={onSettingsChange} autoSave={autoSave} />,\n },\n {\n id: 'providers',\n title: 'AI Providers',\n icon: Brain,\n description: `${snapshot?.providers?.length ?? 0} configured`,\n component: <ProvidersSettings settings={settings} onSettingsChange={onSettingsChange} autoSave={autoSave} />,\n },\n {\n id: 'env-vars',\n title: 'Environment Variables',\n icon: KeyRound,\n description: 'API keys, secrets',\n component: <EnvVarsSettings />,\n },\n {\n id: 'memory',\n title: 'Memory Vault',\n icon: Brain,\n description: 'Git remote, LightRAG config',\n component: <MemorySettings />,\n },\n {\n id: 'system-llm',\n title: 'System LLM',\n icon: Cpu,\n description: settings.systemLlm?.model || 'not set',\n component: <SystemLlmSettings settings={settings} onSettingsChange={onSettingsChange} autoSave={autoSave} />,\n },\n {\n id: 'updates',\n title: 'Updates',\n icon: RefreshCw,\n description: 'Check for updates',\n component: <UpdatesSettings />,\n },\n {\n id: 'headroom',\n title: 'Headroom',\n icon: Cpu,\n description: settings.headroom?.enabled ? 'Enabled' : 'Disabled',\n component: <HeadroomSettingsSection settings={settings} />,\n },\n {\n id: 'tailscale',\n title: 'Tailscale',\n icon: Globe,\n description: 'Tailscale serve & auth',\n component: <TailscaleSettingsMobile />,\n },\n {\n id: 'about',\n title: 'About',\n icon: Info,\n description: `Bizar v${settings.about?.version || '—'}`,\n component: <AboutSection settings={settings} />,\n },\n ];\n\n const filtered = sections.filter(\n (s) =>\n !search ||\n s.title.toLowerCase().includes(search.toLowerCase()) ||\n s.description.toLowerCase().includes(search.toLowerCase()),\n );\n\n return (\n <div className=\"mobile-settings\">\n <div className=\"mobile-settings-search\">\n <SearchIcon />\n <input\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder=\"Search settings...\"\n aria-label=\"Search settings\"\n />\n </div>\n\n <div className=\"mobile-settings-list\">\n {filtered.map((s) => {\n const Icon = s.icon;\n const isExpanded = expandedSection === s.id;\n return (\n <div key={s.id} className={cn('mobile-settings-item', isExpanded && 'is-expanded')}>\n <button\n className=\"mobile-settings-item-head\"\n onClick={() => setExpandedSection(isExpanded ? null : s.id)}\n aria-expanded={isExpanded}\n aria-controls={`mobile-settings-body-${s.id}`}\n >\n <div className=\"mobile-settings-item-icon\">\n <Icon size={18} />\n </div>\n <div className=\"mobile-settings-item-text\">\n <div className=\"mobile-settings-item-title\">{s.title}</div>\n <div className=\"mobile-settings-item-desc\">{s.description}</div>\n </div>\n <ChevronRight\n size={16}\n className={cn('mobile-settings-item-chevron', isExpanded && 'is-rotated')}\n />\n </button>\n {isExpanded && (\n <div id={`mobile-settings-body-${s.id}`} className=\"mobile-settings-item-body\">\n {s.component}\n </div>\n )}\n </div>\n );\n })}\n {filtered.length === 0 && (\n <div className=\"mobile-settings-empty\">No settings match \"{search}\"</div>\n )}\n </div>\n </div>\n );\n}\n\nfunction SearchIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <path d=\"m21 21-4.35-4.35\" />\n </svg>\n );\n}\n"],"names":["MemorySection","toast","useToast","loading","setLoading","useState","saving","setSaving","remoteUrl","setRemoteUrl","vaultPath","refreshKey","setRefreshKey","useEffect","api","r","_b","_a","onSave","k","err","jsxs","Card","CardTitle","jsx","Brain","CardMeta","Spinner","GitBranch","e","Button","Loader2","Save","GeneralSettings","settings","onSettingsChange","autoSave","patchTop","key","value","patchUi","patch","GeneralSection","ProvidersSettings","EnvVarsSettings","EnvVarsSection","MemorySettings","SystemLlmSettings","SystemLlmSection","UpdatesSettings","UpdatesSection","HeadroomSettingsSection","localSettings","setLocalSettings","dirty","setDirty","HeadroomSection","TailscaleSettingsMobile","TailscaleSettings","AboutSection","about","ActivitySection","MobileSettings","snapshot","search","setSearch","expandedSection","setExpandedSection","filtered","Settings2","KeyRound","Cpu","RefreshCw","_c","Globe","Info","_d","s","SearchIcon","Icon","isExpanded","cn","ChevronRight"],"mappings":"gYAiBO,SAASA,GAAgB,CAC9B,MAAMC,EAAQC,EAAA,EACR,CAACC,EAASC,CAAU,EAAIC,EAAAA,SAAS,EAAI,EACrC,CAACC,EAAQC,CAAS,EAAIF,EAAAA,SAAS,EAAK,EACpC,CAACG,EAAWC,CAAY,EAAIJ,EAAAA,SAAS,EAAE,EACvC,CAACK,CAAS,EAAIL,EAAAA,SAAiB,EAAE,EACjC,CAACM,EAAYC,CAAa,EAAIP,EAAAA,SAAS,CAAC,EAE9CQ,EAAAA,UAAU,IAAM,CACdC,EAAI,IAA6C,uBAAuB,EACrE,KAAMC,GAAM,SACXN,IAAaO,GAAAC,EAAAF,EAAE,SAAF,YAAAE,EAAU,MAAV,YAAAD,EAAe,YAAa,EAAE,EAC3CZ,EAAW,EAAK,CAClB,CAAC,EACA,MAAM,IAAMA,EAAW,EAAK,CAAC,CAClC,EAAG,CAACO,CAAU,CAAC,EAEf,MAAMO,EAAS,SAAY,CACzBX,EAAU,EAAI,EACd,GAAI,CACF,MAAMO,EAAI,IAAI,wBAAyB,CAAE,IAAK,CAAE,UAAAN,CAAA,EAAa,EAC7DP,EAAM,QAAQ,sBAAsB,EACpCW,EAAeO,GAAMA,EAAI,CAAC,CAC5B,OAASC,EAAK,CACZnB,EAAM,MAAM,gBAAiBmB,EAAc,OAAO,EAAE,CACtD,QAAA,CACEb,EAAU,EAAK,CACjB,CACF,EAEA,OACEc,EAAAA,KAACC,EAAA,CAAK,GAAG,kBAAkB,eAAa,SACtC,SAAA,CAAAD,OAACE,EAAA,CAAU,SAAA,CAAAC,EAAAA,IAACC,EAAA,CAAM,KAAM,EAAA,CAAI,EAAE,eAAA,EAAa,EAC3CD,EAAAA,IAACE,GAAS,SAAA,+HAAA,CAGV,EAECvB,EACCqB,EAAAA,IAAC,MAAA,CAAI,UAAU,cAAc,MAAO,CAAE,QAAS,EAAA,EAC7C,SAAAA,EAAAA,IAACG,EAAA,CAAQ,KAAK,IAAA,CAAK,EACrB,EAEAN,OAAC,MAAA,CAAI,UAAU,kBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,QACb,SAAA,CAAAG,EAAAA,IAAC,QAAA,CAAM,UAAU,cAAc,SAAA,aAAU,EACzCA,EAAAA,IAAC,MAAA,CAAI,UAAU,4BAA4B,MAAO,CAAE,SAAU,GAAI,QAAS,OAAA,EACxE,SAAAd,GAAa,6BAAA,CAChB,CAAA,EACF,EAEAW,EAAAA,KAAC,MAAA,CAAI,UAAU,QACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,cAAc,QAAQ,wBACrC,SAAA,CAAAG,EAAAA,IAACI,EAAA,CAAU,KAAM,GAAI,MAAO,CAAE,QAAS,SAAU,YAAa,CAAA,CAAE,CAAG,EAAE,gBAAA,EAEvE,EACAJ,EAAAA,IAAC,QAAA,CACC,GAAG,wBACH,UAAU,aACV,KAAK,OACL,MAAOhB,EACP,SAAWqB,GAAMpB,EAAaoB,EAAE,OAAO,KAAK,EAC5C,YAAY,6BAAA,CAAA,EAEdL,EAAAA,IAAC,OAAA,CAAK,UAAU,aAAa,SAAA,mDAAA,CAAiD,CAAA,EAChF,QAEC,MAAA,CAAI,MAAO,CAAE,UAAW,IACvB,SAAAH,EAAAA,KAACS,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAASZ,EACT,SAAUZ,EAET,SAAA,CAAAA,EAASkB,EAAAA,IAACO,EAAA,CAAQ,KAAM,GAAI,UAAU,cAAc,EAAKP,EAAAA,IAACQ,EAAA,CAAK,KAAM,EAAA,CAAI,EAAG,oBAAA,CAAA,CAAA,CAE/E,CACF,CAAA,CAAA,CACF,CAAA,EAEJ,CAEJ,CC/DA,SAASC,EAAgB,CAAE,SAAAC,EAAU,iBAAAC,EAAkB,SAAAC,GAAmB,CACxE,MAAMC,EAAW,CAA2BC,EAAQC,IAAuB,CACzEJ,GAAA,MAAAA,EAAmBG,EAAKC,GACxBH,GAAA,MAAAA,EAAWE,EAAKC,EAClB,EACMC,EAAWC,GAAmC,CAClDN,GAAA,MAAAA,EAAmB,KAAM,CAAE,GAAGD,EAAS,GAAI,GAAGO,IAC9CL,GAAA,MAAAA,EAAW,KAAM,CAAE,GAAGF,EAAS,GAAI,GAAGO,GACxC,EACA,OACEjB,EAAAA,IAACkB,EAAA,CACC,SAAAR,EACA,QAAAM,EACA,SAAAH,EACA,SAAAD,CAAA,CAAA,CAGN,CAEA,SAASO,EAAkB,CAAE,SAAAT,EAAU,iBAAAC,EAAkB,SAAAC,GAAmB,CAI1E,OACEf,OAAC,MAAA,CAAI,MAAO,CAAE,SAAU,GAAI,MAAO,kBAAmB,QAAS,OAAA,EAC7D,SAAA,CAAAG,MAAC,KAAE,MAAO,CAAE,aAAc,CAAA,EAAK,SAAA,+CAE/B,EACAA,EAAAA,IAAC,IAAA,CAAE,KAAK,iCAAiC,UAAU,kCAAkC,MAAO,CAAE,QAAS,eAAgB,SAAU,GAAI,QAAS,UAAA,EAAc,SAAA,kCAAA,CAE5J,CAAA,EACF,CAEJ,CAEA,SAASoB,GAAkB,CACzB,aAAQC,EAAA,EAAe,CACzB,CAEA,SAASC,GAAiB,CACxB,aAAQ9C,EAAA,EAAc,CACxB,CAEA,SAAS+C,EAAkB,CAAE,SAAAb,EAAU,iBAAAC,EAAkB,SAAAC,GAAmB,CAC1E,MAAMC,EAAW,CAA2BC,EAAQC,IAAuB,CACzEJ,GAAA,MAAAA,EAAmBG,EAAKC,GACxBH,GAAA,MAAAA,EAAWE,EAAKC,EAClB,EACA,OAAOf,EAAAA,IAACwB,EAAA,CAAiB,SAAAd,EAAoB,SAAAG,CAAA,CAAoB,CACnE,CAEA,SAASY,GAAkB,CACzB,aAAQC,EAAA,EAAe,CACzB,CAEA,SAASC,EAAwB,CAAE,SAAAjB,GAAoC,CACrE,KAAM,CAACkB,EAAeC,CAAgB,EAAIhD,EAAAA,SAAS6B,CAAQ,EACrD,CAACoB,EAAOC,CAAQ,EAAIlD,EAAAA,SAAS,EAAK,EACxC,OACEmB,EAAAA,IAACgC,EAAA,CACC,SAAUJ,EACV,YAAaC,EACb,SAAAE,CAAA,CAAA,CAGN,CAEA,SAASE,GAA0B,CACjC,aAAQC,EAAA,EAAkB,CAC5B,CAEA,SAASC,GAAa,CAAE,SAAAzB,GAAoC,CAC1D,MAAM0B,EAAQ1B,EAAS,OAAS,CAAE,QAAS,IAAK,SAAU,yCAA0C,QAAS,KAAA,EAC7G,OAAOV,MAACqC,GAAgB,MAAAD,EAAc,CACxC,CAIO,SAASE,GAAe,CAAE,SAAA5B,EAAU,iBAAAC,EAAkB,SAAAC,EAAU,SAAA2B,GAAmB,aACxF,KAAM,CAACC,EAAQC,CAAS,EAAI5D,EAAAA,SAAS,EAAE,EACjC,CAAC6D,EAAiBC,CAAkB,EAAI9D,EAAAA,SAAwB,IAAI,EAoEpE+D,EAlEW,CACf,CACE,GAAI,UACJ,MAAO,UACP,KAAMC,EACN,YAAa,wBACb,UAAW7C,EAAAA,IAACS,EAAA,CAAgB,SAAAC,EAAoB,iBAAAC,EAAoC,SAAAC,CAAA,CAAoB,CAAA,EAE1G,CACE,GAAI,YACJ,MAAO,eACP,KAAMX,EACN,YAAa,KAAGR,EAAA8C,GAAA,YAAAA,EAAU,YAAV,YAAA9C,EAAqB,SAAU,CAAC,cAChD,UAAWO,EAAAA,IAACmB,EAAA,CAAkB,SAAAT,EAAoB,iBAAAC,EAAoC,SAAAC,CAAA,CAAoB,CAAA,EAE5G,CACE,GAAI,WACJ,MAAO,wBACP,KAAMkC,EACN,YAAa,oBACb,gBAAY1B,EAAA,CAAA,CAAgB,CAAA,EAE9B,CACE,GAAI,SACJ,MAAO,eACP,KAAMnB,EACN,YAAa,8BACb,gBAAYqB,EAAA,CAAA,CAAe,CAAA,EAE7B,CACE,GAAI,aACJ,MAAO,aACP,KAAMyB,EACN,cAAavD,EAAAkB,EAAS,YAAT,YAAAlB,EAAoB,QAAS,UAC1C,UAAWQ,EAAAA,IAACuB,EAAA,CAAkB,SAAAb,EAAoB,iBAAAC,EAAoC,SAAAC,CAAA,CAAoB,CAAA,EAE5G,CACE,GAAI,UACJ,MAAO,UACP,KAAMoC,EACN,YAAa,oBACb,gBAAYvB,EAAA,CAAA,CAAgB,CAAA,EAE9B,CACE,GAAI,WACJ,MAAO,WACP,KAAMsB,EACN,aAAaE,EAAAvC,EAAS,WAAT,MAAAuC,EAAmB,QAAU,UAAY,WACtD,UAAWjD,EAAAA,IAAC2B,EAAA,CAAwB,SAAAjB,CAAA,CAAoB,CAAA,EAE1D,CACE,GAAI,YACJ,MAAO,YACP,KAAMwC,EACN,YAAa,yBACb,gBAAYjB,EAAA,CAAA,CAAwB,CAAA,EAEtC,CACE,GAAI,QACJ,MAAO,QACP,KAAMkB,EACN,YAAa,YAAUC,EAAA1C,EAAS,QAAT,YAAA0C,EAAgB,UAAW,GAAG,GACrD,UAAWpD,EAAAA,IAACmC,GAAA,CAAa,SAAAzB,CAAA,CAAoB,CAAA,CAC/C,EAGwB,OACvB2C,GACC,CAACb,GACDa,EAAE,MAAM,YAAA,EAAc,SAASb,EAAO,aAAa,GACnDa,EAAE,YAAY,YAAA,EAAc,SAASb,EAAO,aAAa,CAAA,EAG7D,OACE3C,EAAAA,KAAC,MAAA,CAAI,UAAU,kBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,yBACb,SAAA,CAAAG,EAAAA,IAACsD,GAAA,EAAW,EACZtD,EAAAA,IAAC,QAAA,CACC,MAAOwC,EACP,SAAWnC,GAAMoC,EAAUpC,EAAE,OAAO,KAAK,EACzC,YAAY,qBACZ,aAAW,iBAAA,CAAA,CACb,EACF,EAEAR,EAAAA,KAAC,MAAA,CAAI,UAAU,uBACZ,SAAA,CAAA+C,EAAS,IAAKS,GAAM,CACnB,MAAME,EAAOF,EAAE,KACTG,EAAad,IAAoBW,EAAE,GACzC,cACG,MAAA,CAAe,UAAWI,EAAG,uBAAwBD,GAAc,aAAa,EAC/E,SAAA,CAAA3D,EAAAA,KAAC,SAAA,CACC,UAAU,4BACV,QAAS,IAAM8C,EAAmBa,EAAa,KAAOH,EAAE,EAAE,EAC1D,gBAAeG,EACf,gBAAe,wBAAwBH,EAAE,EAAE,GAE3C,SAAA,CAAArD,EAAAA,IAAC,OAAI,UAAU,4BACb,eAACuD,EAAA,CAAK,KAAM,GAAI,CAAA,CAClB,EACA1D,EAAAA,KAAC,MAAA,CAAI,UAAU,4BACb,SAAA,CAAAG,EAAAA,IAAC,MAAA,CAAI,UAAU,6BAA8B,SAAAqD,EAAE,MAAM,EACrDrD,EAAAA,IAAC,MAAA,CAAI,UAAU,4BAA6B,WAAE,WAAA,CAAY,CAAA,EAC5D,EACAA,EAAAA,IAAC0D,EAAA,CACC,KAAM,GACN,UAAWD,EAAG,+BAAgCD,GAAc,YAAY,CAAA,CAAA,CAC1E,CAAA,CAAA,EAEDA,GACCxD,EAAAA,IAAC,MAAA,CAAI,GAAI,wBAAwBqD,EAAE,EAAE,GAAI,UAAU,4BAChD,SAAAA,EAAE,SAAA,CACL,CAAA,CAAA,EAtBMA,EAAE,EAwBZ,CAEJ,CAAC,EACAT,EAAS,SAAW,GACnB/C,EAAAA,KAAC,MAAA,CAAI,UAAU,wBAAwB,SAAA,CAAA,sBAAoB2C,EAAO,GAAA,CAAA,CAAC,CAAA,CAAA,CAEvE,CAAA,EACF,CAEJ,CAEA,SAASc,IAAa,CACpB,cACG,MAAA,CAAI,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,KAAK,OAAO,OAAO,eAAe,YAAY,IAAI,cAAc,QAAQ,eAAe,QACrI,SAAA,CAAAtD,MAAC,UAAO,GAAG,KAAK,GAAG,KAAK,EAAE,IAAI,EAC9BA,EAAAA,IAAC,OAAA,CAAK,EAAE,kBAAA,CAAmB,CAAA,EAC7B,CAEJ"}
@@ -1 +1 @@
1
- import{r,j as o}from"./react-vendor-Dn4wqh4Z.js";import{E as C,C as j,I as p,J as T,X as g}from"./icons-OMEGx5KA.js";const d=r.createContext(null);function I(){const t=r.useContext(d);return t||{show:()=>{},info:()=>{},success:()=>{},error:()=>{},warning:()=>{},dismiss:()=>{},toasts:[]}}const h={info:T,success:p,error:j,warning:C};function R({children:t}){const[i,n]=r.useState([]),x=r.useRef(1),c=r.useRef(new Map),u=r.useCallback(s=>{n(m=>m.filter(l=>l.id!==s));const e=c.current.get(s);e&&(clearTimeout(e),c.current.delete(s))},[]),a=r.useCallback((s,e="info",m=4e3)=>{const l=x.current++;if(n(f=>[...f,{id:l,kind:e,message:s}]),m>0){const f=setTimeout(()=>u(l),m);c.current.set(l,f)}},[u]);r.useEffect(()=>()=>{for(const s of c.current.values())clearTimeout(s);c.current.clear()},[]);const v=r.useMemo(()=>({show:a,info:(s,e)=>a(s,"info",e),success:(s,e)=>a(s,"success",e),error:(s,e)=>a(s,"error",e),warning:(s,e)=>a(s,"warning",e),dismiss:u,toasts:i}),[a,u,i]);return o.jsxs(d.Provider,{value:v,children:[t,o.jsx(k,{toasts:i,onDismiss:u})]})}function k({toasts:t,onDismiss:i}){return o.jsx("div",{className:"toast-stack","aria-live":"polite",children:t.map(n=>o.jsx(w,{toast:n,onDismiss:i},n.id))})}function w({toast:t,onDismiss:i}){const n=h[t.kind];return o.jsxs("div",{className:`toast toast-${t.kind}`,role:"alert","aria-live":"assertive","aria-atomic":"true",children:[o.jsx(n,{size:16,className:"toast-icon"}),o.jsx("span",{className:"toast-message",children:t.message}),o.jsx("button",{type:"button",className:"toast-close","aria-label":"Dismiss",onClick:()=>i(t.id),children:o.jsx(g,{size:14})})]})}export{R as T,I as u};
1
+ import{r,j as o}from"./react-vendor-Dn4wqh4Z.js";import{E as C,C as j,I as p,J as T,X as g}from"./icons-CMPxNV8t.js";const d=r.createContext(null);function I(){const t=r.useContext(d);return t||{show:()=>{},info:()=>{},success:()=>{},error:()=>{},warning:()=>{},dismiss:()=>{},toasts:[]}}const h={info:T,success:p,error:j,warning:C};function R({children:t}){const[i,n]=r.useState([]),x=r.useRef(1),c=r.useRef(new Map),u=r.useCallback(s=>{n(m=>m.filter(l=>l.id!==s));const e=c.current.get(s);e&&(clearTimeout(e),c.current.delete(s))},[]),a=r.useCallback((s,e="info",m=4e3)=>{const l=x.current++;if(n(f=>[...f,{id:l,kind:e,message:s}]),m>0){const f=setTimeout(()=>u(l),m);c.current.set(l,f)}},[u]);r.useEffect(()=>()=>{for(const s of c.current.values())clearTimeout(s);c.current.clear()},[]);const v=r.useMemo(()=>({show:a,info:(s,e)=>a(s,"info",e),success:(s,e)=>a(s,"success",e),error:(s,e)=>a(s,"error",e),warning:(s,e)=>a(s,"warning",e),dismiss:u,toasts:i}),[a,u,i]);return o.jsxs(d.Provider,{value:v,children:[t,o.jsx(k,{toasts:i,onDismiss:u})]})}function k({toasts:t,onDismiss:i}){return o.jsx("div",{className:"toast-stack","aria-live":"polite",children:t.map(n=>o.jsx(w,{toast:n,onDismiss:i},n.id))})}function w({toast:t,onDismiss:i}){const n=h[t.kind];return o.jsxs("div",{className:`toast toast-${t.kind}`,role:"alert","aria-live":"assertive","aria-atomic":"true",children:[o.jsx(n,{size:16,className:"toast-icon"}),o.jsx("span",{className:"toast-message",children:t.message}),o.jsx("button",{type:"button",className:"toast-close","aria-label":"Dismiss",onClick:()=>i(t.id),children:o.jsx(g,{size:14})})]})}export{R as T,I as u};
@@ -1 +1 @@
1
- {"version":3,"file":"Toast-CcZVVN4i.js","sources":["../../src/web/components/Toast.tsx"],"sourcesContent":["// src/components/Toast.tsx — toast context, provider hook, container.\n\nimport {\n createContext,\n useEffect,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { CheckCircle2, AlertTriangle, AlertCircle, Info, X } from 'lucide-react';\n\nexport type ToastKind = 'info' | 'success' | 'error' | 'warning';\n\nexport type Toast = {\n id: number;\n kind: ToastKind;\n message: string;\n};\n\nexport type ToastApi = {\n show: (message: string, kind?: ToastKind, durationMs?: number) => void;\n info: (message: string, durationMs?: number) => void;\n success: (message: string, durationMs?: number) => void;\n error: (message: string, durationMs?: number) => void;\n warning: (message: string, durationMs?: number) => void;\n dismiss: (id: number) => void;\n toasts: Toast[];\n};\n\nconst ToastContext = createContext<ToastApi | null>(null);\n\nexport function useToast(): ToastApi {\n const ctx = useContext(ToastContext);\n if (!ctx) {\n // Fallback no-op so tests/Storybook don't crash\n return {\n show: () => undefined,\n info: () => undefined,\n success: () => undefined,\n error: () => undefined,\n warning: () => undefined,\n dismiss: () => undefined,\n toasts: [],\n };\n }\n return ctx;\n}\n\nconst ICONS: Record<ToastKind, typeof Info> = {\n info: Info,\n success: CheckCircle2,\n error: AlertCircle,\n warning: AlertTriangle,\n};\n\nexport function ToastProvider({ children }: { children: React.ReactNode }) {\n const [toasts, setToasts] = useState<Toast[]>([]);\n const idRef = useRef(1);\n const timersRef = useRef<Map<number, ReturnType<typeof setTimeout>>>(new Map());\n\n const dismiss = useCallback((id: number) => {\n setToasts((cur) => cur.filter((t) => t.id !== id));\n const timer = timersRef.current.get(id);\n if (timer) {\n clearTimeout(timer);\n timersRef.current.delete(id);\n }\n }, []);\n\n const show = useCallback<ToastApi['show']>(\n (message, kind = 'info', durationMs = 4000) => {\n const id = idRef.current++;\n setToasts((cur) => [...cur, { id, kind, message }]);\n if (durationMs > 0) {\n const timer = setTimeout(() => dismiss(id), durationMs);\n timersRef.current.set(id, timer);\n }\n },\n [dismiss],\n );\n\n useEffect(() => {\n return () => {\n for (const timer of timersRef.current.values()) clearTimeout(timer);\n timersRef.current.clear();\n };\n }, []);\n\n const api = useMemo<ToastApi>(\n () => ({\n show,\n info: (m, d) => show(m, 'info', d),\n success: (m, d) => show(m, 'success', d),\n error: (m, d) => show(m, 'error', d),\n warning: (m, d) => show(m, 'warning', d),\n dismiss,\n toasts,\n }),\n [show, dismiss, toasts],\n );\n\n return (\n <ToastContext.Provider value={api}>\n {children}\n <ToastContainer toasts={toasts} onDismiss={dismiss} />\n </ToastContext.Provider>\n );\n}\n\nexport function ToastContainer({\n toasts,\n onDismiss,\n}: {\n toasts: Toast[];\n onDismiss: (id: number) => void;\n}) {\n return (\n <div className=\"toast-stack\" aria-live=\"polite\">\n {toasts.map((t) => (\n <ToastItem key={t.id} toast={t} onDismiss={onDismiss} />\n ))}\n </div>\n );\n}\n\nfunction ToastItem({\n toast,\n onDismiss,\n}: {\n toast: Toast;\n onDismiss: (id: number) => void;\n}) {\n const Icon = ICONS[toast.kind];\n return (\n <div className={`toast toast-${toast.kind}`} role=\"alert\" aria-live=\"assertive\" aria-atomic=\"true\">\n <Icon size={16} className=\"toast-icon\" />\n <span className=\"toast-message\">{toast.message}</span>\n <button\n type=\"button\"\n className=\"toast-close\"\n aria-label=\"Dismiss\"\n onClick={() => onDismiss(toast.id)}\n >\n <X size={14} />\n </button>\n </div>\n );\n}\n"],"names":["ToastContext","createContext","useToast","ctx","useContext","ICONS","Info","CheckCircle2","AlertCircle","AlertTriangle","ToastProvider","children","toasts","setToasts","useState","idRef","useRef","timersRef","dismiss","useCallback","id","cur","t","timer","show","message","kind","durationMs","useEffect","api","useMemo","m","d","jsxs","jsx","ToastContainer","onDismiss","ToastItem","toast","Icon","X"],"mappings":"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"}
1
+ {"version":3,"file":"Toast-BlcKl_dN.js","sources":["../../src/web/components/Toast.tsx"],"sourcesContent":["// src/components/Toast.tsx — toast context, provider hook, container.\n\nimport {\n createContext,\n useEffect,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { CheckCircle2, AlertTriangle, AlertCircle, Info, X } from 'lucide-react';\n\nexport type ToastKind = 'info' | 'success' | 'error' | 'warning';\n\nexport type Toast = {\n id: number;\n kind: ToastKind;\n message: string;\n};\n\nexport type ToastApi = {\n show: (message: string, kind?: ToastKind, durationMs?: number) => void;\n info: (message: string, durationMs?: number) => void;\n success: (message: string, durationMs?: number) => void;\n error: (message: string, durationMs?: number) => void;\n warning: (message: string, durationMs?: number) => void;\n dismiss: (id: number) => void;\n toasts: Toast[];\n};\n\nconst ToastContext = createContext<ToastApi | null>(null);\n\nexport function useToast(): ToastApi {\n const ctx = useContext(ToastContext);\n if (!ctx) {\n // Fallback no-op so tests/Storybook don't crash\n return {\n show: () => undefined,\n info: () => undefined,\n success: () => undefined,\n error: () => undefined,\n warning: () => undefined,\n dismiss: () => undefined,\n toasts: [],\n };\n }\n return ctx;\n}\n\nconst ICONS: Record<ToastKind, typeof Info> = {\n info: Info,\n success: CheckCircle2,\n error: AlertCircle,\n warning: AlertTriangle,\n};\n\nexport function ToastProvider({ children }: { children: React.ReactNode }) {\n const [toasts, setToasts] = useState<Toast[]>([]);\n const idRef = useRef(1);\n const timersRef = useRef<Map<number, ReturnType<typeof setTimeout>>>(new Map());\n\n const dismiss = useCallback((id: number) => {\n setToasts((cur) => cur.filter((t) => t.id !== id));\n const timer = timersRef.current.get(id);\n if (timer) {\n clearTimeout(timer);\n timersRef.current.delete(id);\n }\n }, []);\n\n const show = useCallback<ToastApi['show']>(\n (message, kind = 'info', durationMs = 4000) => {\n const id = idRef.current++;\n setToasts((cur) => [...cur, { id, kind, message }]);\n if (durationMs > 0) {\n const timer = setTimeout(() => dismiss(id), durationMs);\n timersRef.current.set(id, timer);\n }\n },\n [dismiss],\n );\n\n useEffect(() => {\n return () => {\n for (const timer of timersRef.current.values()) clearTimeout(timer);\n timersRef.current.clear();\n };\n }, []);\n\n const api = useMemo<ToastApi>(\n () => ({\n show,\n info: (m, d) => show(m, 'info', d),\n success: (m, d) => show(m, 'success', d),\n error: (m, d) => show(m, 'error', d),\n warning: (m, d) => show(m, 'warning', d),\n dismiss,\n toasts,\n }),\n [show, dismiss, toasts],\n );\n\n return (\n <ToastContext.Provider value={api}>\n {children}\n <ToastContainer toasts={toasts} onDismiss={dismiss} />\n </ToastContext.Provider>\n );\n}\n\nexport function ToastContainer({\n toasts,\n onDismiss,\n}: {\n toasts: Toast[];\n onDismiss: (id: number) => void;\n}) {\n return (\n <div className=\"toast-stack\" aria-live=\"polite\">\n {toasts.map((t) => (\n <ToastItem key={t.id} toast={t} onDismiss={onDismiss} />\n ))}\n </div>\n );\n}\n\nfunction ToastItem({\n toast,\n onDismiss,\n}: {\n toast: Toast;\n onDismiss: (id: number) => void;\n}) {\n const Icon = ICONS[toast.kind];\n return (\n <div className={`toast toast-${toast.kind}`} role=\"alert\" aria-live=\"assertive\" aria-atomic=\"true\">\n <Icon size={16} className=\"toast-icon\" />\n <span className=\"toast-message\">{toast.message}</span>\n <button\n type=\"button\"\n className=\"toast-close\"\n aria-label=\"Dismiss\"\n onClick={() => onDismiss(toast.id)}\n >\n <X size={14} />\n </button>\n </div>\n );\n}\n"],"names":["ToastContext","createContext","useToast","ctx","useContext","ICONS","Info","CheckCircle2","AlertCircle","AlertTriangle","ToastProvider","children","toasts","setToasts","useState","idRef","useRef","timersRef","dismiss","useCallback","id","cur","t","timer","show","message","kind","durationMs","useEffect","api","useMemo","m","d","jsxs","jsx","ToastContainer","onDismiss","ToastItem","toast","Icon","X"],"mappings":"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"}