@shawnstack/quickforge 1.6.11 → 1.6.13

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 (43) hide show
  1. package/README.md +292 -452
  2. package/dist/assets/AgentProfilesPage-Be0oZDW5.js +1 -0
  3. package/dist/assets/ChatPanelHost-CxEotTsy.js +291 -0
  4. package/dist/assets/{PluginsPage-B_4nlPca.js → PluginsPage-DZlqGFLn.js} +1 -1
  5. package/dist/assets/ScheduledTasksPage-DTkj-0O4.js +2 -0
  6. package/dist/assets/{SettingsWorkspacePage-BtgkwIKN.js → SettingsWorkspacePage-BJq11OPD.js} +397 -403
  7. package/dist/assets/{SharedConversationPage-B5FS3eSl.js → SharedConversationPage-BCR8xzii.js} +1 -1
  8. package/dist/assets/TerminalDock-Bs5b-YNp.js +2 -0
  9. package/dist/assets/WorkspaceInspector-BP0XyAlE.js +13 -0
  10. package/dist/assets/icons-DAxUA0e-.js +1 -0
  11. package/dist/assets/index-BZC61KZg.css +3 -0
  12. package/dist/assets/index-DGQbvw7v.js +63 -0
  13. package/dist/assets/{mcp-servers-dialog-BPk4a4nW.js → mcp-servers-dialog-BHljnwYv.js} +2 -2
  14. package/dist/assets/{monaco-CdOyGlWD.js → monaco-DEQoYzYI.js} +1 -1
  15. package/dist/assets/{react-vendor-VqdnQHHS.js → react-vendor-CZsiwuxm.js} +1 -1
  16. package/dist/assets/{skills-dialog-DcxeFWSt.js → skills-dialog-8rn1XU9U.js} +1 -1
  17. package/dist/index.html +6 -6
  18. package/dist/licenses/material-icon-theme.txt +8 -0
  19. package/package.json +1 -1
  20. package/server/agent-manager.mjs +163 -25
  21. package/server/custom-commands.mjs +17 -0
  22. package/server/image-generation.mjs +130 -0
  23. package/server/index.mjs +6 -0
  24. package/server/provider-config.mjs +78 -0
  25. package/server/routes/agent.mjs +9 -0
  26. package/server/routes/project.mjs +3 -18
  27. package/server/routes/session-assets.mjs +49 -0
  28. package/server/routes/shared-conversation.mjs +10 -0
  29. package/server/routes/tools.mjs +1 -1
  30. package/server/routes/workspace.mjs +5 -2
  31. package/server/session-assets.mjs +134 -0
  32. package/server/storage.mjs +13 -1
  33. package/server/tools/definitions.mjs +10 -0
  34. package/server/tools/index.mjs +2 -0
  35. package/server/utils/platform.mjs +20 -3
  36. package/dist/assets/AgentProfilesPage-CvoB0OId.js +0 -1
  37. package/dist/assets/ChatPanelHost-Cyi1yi_P.js +0 -244
  38. package/dist/assets/ScheduledTasksPage-Zbsuo8o6.js +0 -2
  39. package/dist/assets/TerminalDock-CiJCmyqg.js +0 -2
  40. package/dist/assets/WorkspaceInspector-C9HyQIvF.js +0 -13
  41. package/dist/assets/icons-C7j5jdKo.js +0 -1
  42. package/dist/assets/index-BFKildY3.js +0 -63
  43. package/dist/assets/index-CsKSKUn-.css +0 -3
@@ -1,5 +1,5 @@
1
- import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{B as t,C as n,D as r,Rt as i,Vt as a,a as o,g as s,st as c,x as l,y as u}from"./icons-C7j5jdKo.js";import{n as d}from"./react-vendor-VqdnQHHS.js";import{H as f,ct as p,dt as m,ht as h,ut as g,x as _}from"./index-BFKildY3.js";var v=e(a(),1),y=d();function b(e){return e===`connected`?`bg-emerald-500/12 text-emerald-700 dark:text-emerald-300`:e===`error`?`bg-destructive/12 text-destructive`:e===`disabled`?`bg-muted text-muted-foreground`:`bg-amber-500/12 text-amber-700 dark:text-amber-300`}var x=12;function S({server:e,toggling:n,reconnecting:i,onToggle:a,onEdit:s,onDelete:c,onReconnect:l}){let d=e.tools?.slice(0,x)??[],f=e.toolCount??e.tools?.length??0,p=Math.max(0,f-d.length),_=e.enabled&&e.status!==`connected`;return(0,y.jsxs)(`div`,{className:`rounded-lg border border-border p-3`,children:[(0,y.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,y.jsxs)(`div`,{className:`min-w-0`,children:[(0,y.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,y.jsx)(`div`,{className:`truncate text-sm font-medium text-foreground/90`,children:e.name}),(0,y.jsx)(`span`,{className:m(`rounded-full px-2 py-0.5 text-[11px]`,b(e.status)),children:e.status||`unknown`}),(0,y.jsx)(`span`,{className:`text-[11px] text-muted-foreground/60`,children:h(`mcpToolsCount`,{count:f})})]}),(0,y.jsx)(`div`,{className:`mt-1 truncate text-xs text-muted-foreground/65`,children:e.transport===`stdio`?`${e.command} ${(e.args||[]).join(` `)}`:e.url}),e.error?(0,y.jsx)(`div`,{className:`mt-1 text-xs text-destructive`,children:e.error}):null]}),(0,y.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1`,children:[(0,y.jsx)(`button`,{type:`button`,role:`switch`,"aria-checked":e.enabled,disabled:n,className:m(`relative h-6 w-11 rounded-full transition-colors disabled:cursor-not-allowed disabled:opacity-60`,e.enabled?`bg-emerald-500`:`bg-muted-foreground/30`),onClick:()=>a(e),title:e.enabled?h(`pauseTask`):h(`enable`),children:(0,y.jsx)(`span`,{className:m(`absolute left-0.5 top-0.5 size-5 rounded-full bg-white shadow transition-transform`,e.enabled?`translate-x-5`:`translate-x-0`)})}),_?(0,y.jsx)(g,{type:`button`,variant:`ghost`,size:`icon`,className:`size-8 text-muted-foreground`,onClick:()=>l(e.name),disabled:i,"aria-label":h(`mcpReconnectServer`),title:h(`mcpReconnectServer`),children:i?(0,y.jsx)(t,{className:`size-4 animate-spin`}):(0,y.jsx)(u,{className:`size-4`})}):null,(0,y.jsx)(g,{type:`button`,variant:`ghost`,size:`icon`,className:`size-8 text-muted-foreground`,onClick:()=>s(e),"aria-label":h(`editTask`),title:h(`editTask`),children:(0,y.jsx)(r,{className:`size-4`})}),(0,y.jsx)(g,{type:`button`,variant:`ghost`,size:`icon`,className:`size-8 text-destructive`,onClick:()=>c(e.name),"aria-label":h(`delete`),title:h(`delete`),children:(0,y.jsx)(o,{className:`size-4`})})]})]}),d.length>0?(0,y.jsxs)(`div`,{className:`mt-2 flex flex-wrap gap-1.5`,children:[d.map(e=>(0,y.jsx)(`span`,{className:`rounded-md bg-muted/28 px-1.5 py-0.5 text-[11px] text-muted-foreground/75`,title:e.quickForgeName,children:e.name},e.quickForgeName)),p>0?(0,y.jsx)(`span`,{className:`rounded-md px-1.5 py-0.5 text-[11px] text-muted-foreground/55`,children:h(`mcpMoreTools`,{count:p})}):null]}):null]})}function C(){return{name:``,transport:`stdio`,command:``,args:[],url:``,cwd:``,env:{}}}function w(e){return{name:e.name,transport:e.transport,command:e.command,args:e.args||[],url:e.url||``,cwd:e.cwd||``,env:e.env||{}}}function T(e){return(e||[]).join(`
1
+ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{Ot as t,R as n,T as r,Tt as i,X as a,_ as o,a as s,h as c,x as l,y as u}from"./icons-DAxUA0e-.js";import{n as d}from"./react-vendor-CZsiwuxm.js";import{V as f,b as p,lt as m,mt as h,st as g,ut as _}from"./index-DGQbvw7v.js";var v=e(t(),1),y=d();function b(e){return e===`connected`?`bg-emerald-500/12 text-emerald-700 dark:text-emerald-300`:e===`error`?`bg-destructive/12 text-destructive`:e===`disabled`?`bg-muted text-muted-foreground`:`bg-amber-500/12 text-amber-700 dark:text-amber-300`}var x=12;function S({server:e,toggling:t,reconnecting:i,onToggle:a,onEdit:c,onDelete:l,onReconnect:u}){let d=e.tools?.slice(0,x)??[],f=e.toolCount??e.tools?.length??0,p=Math.max(0,f-d.length),g=e.enabled&&e.status!==`connected`;return(0,y.jsxs)(`div`,{className:`rounded-lg border border-border p-3`,children:[(0,y.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,y.jsxs)(`div`,{className:`min-w-0`,children:[(0,y.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,y.jsx)(`div`,{className:`truncate text-sm font-medium text-foreground/90`,children:e.name}),(0,y.jsx)(`span`,{className:_(`rounded-full px-2 py-0.5 text-[11px]`,b(e.status)),children:e.status||`unknown`}),(0,y.jsx)(`span`,{className:`text-[11px] text-muted-foreground/60`,children:h(`mcpToolsCount`,{count:f})})]}),(0,y.jsx)(`div`,{className:`mt-1 truncate text-xs text-muted-foreground/65`,children:e.transport===`stdio`?`${e.command} ${(e.args||[]).join(` `)}`:e.url}),e.error?(0,y.jsx)(`div`,{className:`mt-1 text-xs text-destructive`,children:e.error}):null]}),(0,y.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1`,children:[(0,y.jsx)(`button`,{type:`button`,role:`switch`,"aria-checked":e.enabled,disabled:t,className:_(`relative h-6 w-11 rounded-full transition-colors disabled:cursor-not-allowed disabled:opacity-60`,e.enabled?`bg-emerald-500`:`bg-muted-foreground/30`),onClick:()=>a(e),title:e.enabled?h(`pauseTask`):h(`enable`),children:(0,y.jsx)(`span`,{className:_(`absolute left-0.5 top-0.5 size-5 rounded-full bg-white shadow transition-transform`,e.enabled?`translate-x-5`:`translate-x-0`)})}),g?(0,y.jsx)(m,{type:`button`,variant:`ghost`,size:`icon`,className:`size-8 text-muted-foreground`,onClick:()=>u(e.name),disabled:i,"aria-label":h(`mcpReconnectServer`),title:h(`mcpReconnectServer`),children:i?(0,y.jsx)(n,{className:`size-4 animate-spin`}):(0,y.jsx)(o,{className:`size-4`})}):null,(0,y.jsx)(m,{type:`button`,variant:`ghost`,size:`icon`,className:`size-8 text-muted-foreground`,onClick:()=>c(e),"aria-label":h(`editTask`),title:h(`editTask`),children:(0,y.jsx)(r,{className:`size-4`})}),(0,y.jsx)(m,{type:`button`,variant:`ghost`,size:`icon`,className:`size-8 text-destructive`,onClick:()=>l(e.name),"aria-label":h(`delete`),title:h(`delete`),children:(0,y.jsx)(s,{className:`size-4`})})]})]}),d.length>0?(0,y.jsxs)(`div`,{className:`mt-2 flex flex-wrap gap-1.5`,children:[d.map(e=>(0,y.jsx)(`span`,{className:`rounded-md bg-muted/28 px-1.5 py-0.5 text-[11px] text-muted-foreground/75`,title:e.quickForgeName,children:e.name},e.quickForgeName)),p>0?(0,y.jsx)(`span`,{className:`rounded-md px-1.5 py-0.5 text-[11px] text-muted-foreground/55`,children:h(`mcpMoreTools`,{count:p})}):null]}):null]})}function C(){return{name:``,transport:`stdio`,command:``,args:[],url:``,cwd:``,env:{}}}function w(e){return{name:e.name,transport:e.transport,command:e.command,args:e.args||[],url:e.url||``,cwd:e.cwd||``,env:e.env||{}}}function T(e){return(e||[]).join(`
2
2
  `)}function E(e){return Object.entries(e||{}).map(([e,t])=>`${e}=${t}`).join(`
3
3
  `)}function D(e){return e.split(`
4
4
  `).map(e=>e.trim()).filter(Boolean)}function O(e){let t={};for(let n of e.split(`
5
- `)){let e=n.trim();if(!e)continue;let r=e.indexOf(`=`);if(r<=0)continue;let i=e.slice(0,r).trim(),a=e.slice(r+1).trim();i&&(t[i]=a)}return t}function k(e){let t={type:e.transport||`stdio`};e.transport===`stdio`?(t.command=e.command||``,t.args=e.args||[],e.cwd&&(t.cwd=e.cwd),e.env&&Object.keys(e.env).length>0&&(t.env=e.env)):(t.url=e.url||``,e.env&&Object.keys(e.env).length>0&&(t.headers=e.env));let n=e.name||`server`;return JSON.stringify({mcpServers:{[n]:t}},null,2)}function A(e){return!!(e&&typeof e==`object`&&!Array.isArray(e))}function j(e){let t;try{t=JSON.parse(e)}catch{throw Error(h(`mcpInvalidJson`))}if(!A(t))throw Error(h(`mcpInvalidConfigJson`));let n=``,r=null;if(A(t.mcpServers)){let e=Object.entries(t.mcpServers);if(e.length===0)throw Error(h(`mcpEmptyConfigJson`));let[i,a]=e[0];n=i,A(a)&&(r=a)}else r=t;if(!r)throw Error(h(`mcpInvalidConfigJson`));let i=String(r.transport||r.type||`stdio`);if(![`stdio`,`http`,`sse`].includes(i))throw Error(h(`mcpInvalidTransport`,{name:n||`server`}));let a=r.env??r.headers??{};return{name:n,transport:i,command:String(r.command||``),args:Array.isArray(r.args)?r.args:[],url:String(r.url||``),cwd:String(r.cwd||``),env:A(a)?a:{}}}var M=`mb-1 block text-xs text-muted-foreground/72`,N=`min-h-20 w-full resize-y rounded-md border border-input bg-background px-2 py-1.5 font-mono text-xs text-foreground outline-none focus:border-ring`,P=`flex h-9 w-full rounded-md border border-input bg-transparent px-3 text-sm outline-none focus:border-ring`;function F({value:e,onChange:t,isEdit:n,disabled:r}){let i=e.transport===`stdio`,a=n=>t({...e,...n});return(0,y.jsxs)(`div`,{className:`space-y-3 p-3`,children:[(0,y.jsx)(`div`,{className:`text-xs text-muted-foreground/60`,children:h(n?`mcpEditServer`:`mcpAddServer`)}),(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`label`,{className:M,htmlFor:`mcp-server-name`,children:h(`mcpServerName`)}),(0,y.jsx)(_,{id:`mcp-server-name`,value:e.name,onChange:e=>a({name:e.target.value}),placeholder:h(`mcpNamePlaceholder`),disabled:n||r})]}),(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`label`,{className:M,htmlFor:`mcp-server-transport`,children:h(`mcpTransport`)}),(0,y.jsxs)(`select`,{id:`mcp-server-transport`,className:P,value:e.transport,onChange:e=>a({transport:e.target.value}),disabled:r,children:[(0,y.jsx)(`option`,{value:`stdio`,children:`stdio`}),(0,y.jsx)(`option`,{value:`http`,children:`http`}),(0,y.jsx)(`option`,{value:`sse`,children:`sse`})]})]}),i?(0,y.jsxs)(y.Fragment,{children:[(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`label`,{className:M,htmlFor:`mcp-server-command`,children:h(`mcpCommand`)}),(0,y.jsx)(_,{id:`mcp-server-command`,value:e.command,onChange:e=>a({command:e.target.value}),placeholder:h(`mcpCommandPlaceholder`),disabled:r})]}),(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`label`,{className:M,htmlFor:`mcp-server-args`,children:h(`mcpArgs`)}),(0,y.jsx)(`textarea`,{id:`mcp-server-args`,className:N,value:T(e.args),onChange:e=>a({args:D(e.target.value)}),spellCheck:!1,disabled:r})]}),(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`label`,{className:M,htmlFor:`mcp-server-cwd`,children:h(`mcpCwd`)}),(0,y.jsx)(_,{id:`mcp-server-cwd`,value:e.cwd,onChange:e=>a({cwd:e.target.value}),disabled:r})]}),(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`label`,{className:M,htmlFor:`mcp-server-env`,children:h(`mcpEnv`)}),(0,y.jsx)(`textarea`,{id:`mcp-server-env`,className:N,value:E(e.env),onChange:e=>a({env:O(e.target.value)}),spellCheck:!1,disabled:r})]})]}):(0,y.jsxs)(y.Fragment,{children:[(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`label`,{className:M,htmlFor:`mcp-server-url`,children:h(`mcpUrl`)}),(0,y.jsx)(_,{id:`mcp-server-url`,value:e.url,onChange:e=>a({url:e.target.value}),placeholder:h(`mcpUrlPlaceholder`),disabled:r})]}),(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`label`,{className:M,htmlFor:`mcp-server-headers`,children:h(`mcpHeaders`)}),(0,y.jsx)(`textarea`,{id:`mcp-server-headers`,className:N,value:E(e.env),onChange:e=>a({env:O(e.target.value)}),spellCheck:!1,disabled:r})]})]})]})}async function I(e){let t=await e.json().catch(()=>null);if(!e.ok)throw Error(t?.error||`HTTP ${e.status}`);return t}function L({active:e=!0,className:r}){let[a,o]=(0,v.useState)([]),[u,d]=(0,v.useState)(!1),[_,b]=(0,v.useState)(!1),[x,T]=(0,v.useState)(new Set),[E,D]=(0,v.useState)(null),[O,A]=(0,v.useState)(``),[M,N]=(0,v.useState)(!1),[P,L]=(0,v.useState)(null),[R,z]=(0,v.useState)(C),[B,V]=(0,v.useState)(`form`),[H,U]=(0,v.useState)(``),[W,G]=(0,v.useState)(``),K=(0,v.useCallback)(e=>{o(e?.servers??[])},[]),q=(0,v.useCallback)(async()=>{d(!0),A(``);try{K(await I(await fetch(`/api/mcp/servers`)))}catch(e){A(e instanceof Error?e.message:h(`mcpLoadFailed`))}finally{d(!1)}},[K]);if((0,v.useEffect)(()=>{if(!e)return;let t=window.setTimeout(()=>{q()},0);return()=>window.clearTimeout(t)},[e,q]),!e)return null;let J=e=>{e===`json`&&(U(k(R)),G(``)),V(e)},Y=()=>{L(null),z(C()),V(`form`),N(!0),A(``)},X=e=>{let t=w(e);L(e),z(t),U(k(t)),G(``),V(`form`),N(!0),A(``)},Z=()=>{N(!1),L(null),U(``),G(``),A(``)},Q=e=>{z(e)},ee=e=>{U(e);try{let t=j(e);z(e=>({...t,name:t.name||e.name})),G(``)}catch(e){G(e instanceof Error?e.message:h(`mcpInvalidJson`))}},te=async()=>{if(!_){if(W&&B===`json`){A(W);return}b(!0),A(``);try{K(await I(await fetch(`/api/mcp/servers`,{method:`PUT`,headers:{"content-type":`application/json`},body:JSON.stringify({server:{...R,enabled:P?.enabled??!0}})}))),Z()}catch(e){A(e instanceof Error?e.message:h(`mcpSaveFailed`))}finally{b(!1)}}},ne=async e=>{if(await f({description:h(`mcpDeleteConfirm`,{name:e}),confirmLabel:h(`confirmDelete`),cancelLabel:h(`cancel`),variant:`destructive`})){A(``);try{K(await I(await fetch(`/api/mcp/servers/${encodeURIComponent(e)}`,{method:`DELETE`})))}catch(e){A(e instanceof Error?e.message:h(`mcpDeleteFailed`))}}},re=async e=>{if(!x.has(e.name)){T(t=>new Set(t).add(e.name)),A(``);try{K(await I(await fetch(`/api/mcp/servers/${encodeURIComponent(e.name)}/enabled`,{method:`PUT`,headers:{"content-type":`application/json`},body:JSON.stringify({enabled:!e.enabled})})))}catch(e){A(e instanceof Error?e.message:h(`mcpSaveFailed`))}finally{T(t=>{let n=new Set(t);return n.delete(e.name),n})}}},ie=async()=>{d(!0),A(``);try{K(await I(await fetch(`/api/mcp/reconnect`,{method:`POST`})))}catch(e){A(e instanceof Error?e.message:h(`mcpReconnectFailed`))}finally{d(!1)}},ae=async e=>{if(!E){D(e),A(``);try{K(await I(await fetch(`/api/mcp/reconnect/${encodeURIComponent(e)}`,{method:`POST`})))}catch(e){A(e instanceof Error?e.message:h(`mcpReconnectFailed`))}finally{D(null)}}},$=!!P,oe=!!R.name.trim()&&!!(R.transport===`stdio`?R.command.trim():R.url.trim());return M?(0,y.jsxs)(`div`,{className:m(`flex min-h-0 flex-1 flex-col overflow-hidden bg-background`,r),children:[(0,y.jsx)(`div`,{className:`border-b border-border px-6 py-5`,children:(0,y.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,y.jsxs)(`button`,{type:`button`,className:`inline-flex items-center gap-1.5 text-sm text-muted-foreground hover:text-foreground`,onClick:Z,children:[(0,y.jsx)(i,{className:`size-4`}),h(`mcpConfiguredServers`)]}),(0,y.jsx)(`span`,{className:`text-sm font-medium text-foreground/90`,children:h($?`mcpEditServer`:`mcpAddServer`)})]})}),O?(0,y.jsx)(`div`,{className:`m-6 mb-0 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive`,children:O}):null,(0,y.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto p-6`,children:(0,y.jsxs)(`div`,{className:`mx-auto max-w-5xl space-y-5`,children:[(0,y.jsxs)(`div`,{className:`flex border-b border-border`,children:[(0,y.jsxs)(`button`,{type:`button`,onClick:()=>J(`form`),className:m(`flex flex-1 items-center justify-center gap-1.5 px-3 py-2.5 text-xs font-medium transition-colors`,B===`form`?`border-b-2 border-primary text-foreground/90 -mb-px`:`text-muted-foreground/60 hover:text-foreground/85`),children:[(0,y.jsx)(s,{className:`size-3.5`}),h(`mcpTabServer`)]}),(0,y.jsxs)(`button`,{type:`button`,onClick:()=>J(`json`),className:m(`flex flex-1 items-center justify-center gap-1.5 px-3 py-2.5 text-xs font-medium transition-colors`,B===`json`?`border-b-2 border-primary text-foreground/90 -mb-px`:`text-muted-foreground/60 hover:text-foreground/85`),children:[(0,y.jsx)(c,{className:`size-3.5`}),h(`mcpTabJson`)]})]}),(0,y.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto`,children:B===`form`?(0,y.jsx)(F,{value:R,onChange:Q,isEdit:$,disabled:_}):(0,y.jsxs)(`div`,{className:`space-y-2`,children:[(0,y.jsx)(`textarea`,{className:`min-h-96 w-full resize-y rounded-md border border-input bg-background px-2 py-1.5 font-mono text-xs text-foreground outline-none focus:border-ring`,value:H,onChange:e=>ee(e.target.value),spellCheck:!1}),W?(0,y.jsx)(`div`,{className:`rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive`,children:W}):null,(0,y.jsxs)(`div`,{className:`inline-flex items-center gap-1.5 text-[11px] font-medium text-foreground/90`,children:[h(`mcpTabJson`),(0,y.jsx)(p,{label:h(`mcpImportConfigDescription`)})]})]})}),(0,y.jsxs)(`div`,{className:`flex justify-end gap-2 border-t border-border pt-3`,children:[(0,y.jsx)(g,{type:`button`,variant:`outline`,size:`sm`,onClick:Z,disabled:_,children:h(`cancel`)}),(0,y.jsxs)(g,{type:`button`,size:`sm`,onClick:()=>{te()},disabled:_||!oe,children:[_?(0,y.jsx)(t,{className:`mr-1.5 size-3.5 animate-spin`}):null,h(`save`)]})]})]})})]}):(0,y.jsxs)(`div`,{className:m(`flex min-h-0 flex-1 flex-col overflow-hidden bg-background`,r),children:[(0,y.jsx)(`div`,{className:`border-b border-border px-6 py-5`,children:(0,y.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,y.jsx)(`h3`,{className:`text-sm font-medium text-foreground/90`,children:h(`mcpConfiguredServers`)}),(0,y.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,y.jsxs)(g,{type:`button`,variant:`ghost`,size:`sm`,onClick:Y,children:[(0,y.jsx)(n,{className:`mr-1.5 size-3.5`}),h(`mcpAddServer`)]}),(0,y.jsxs)(g,{type:`button`,variant:`ghost`,size:`sm`,onClick:ie,disabled:u,children:[u?(0,y.jsx)(t,{className:`mr-1.5 size-3.5 animate-spin`}):(0,y.jsx)(l,{className:`mr-1.5 size-3.5`}),h(`mcpReconnect`)]})]})]})}),O?(0,y.jsx)(`div`,{className:`m-6 mb-0 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive`,children:O}):null,(0,y.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto p-6`,children:(0,y.jsx)(`div`,{className:`mx-auto max-w-5xl space-y-5`,children:u&&a.length===0?(0,y.jsxs)(`div`,{className:`flex items-center justify-center gap-2 rounded-lg border border-border py-8 text-sm text-muted-foreground`,children:[(0,y.jsx)(t,{className:`size-4 animate-spin`}),h(`loading`)]}):a.length===0?(0,y.jsx)(`div`,{className:`rounded-lg border border-border bg-muted/15 p-4 text-sm text-muted-foreground/72`,children:h(`mcpNoServersDescription`)}):a.map(e=>(0,y.jsx)(S,{server:e,toggling:x.has(e.name),reconnecting:E===e.name,onToggle:e=>{re(e)},onEdit:X,onDelete:e=>{ne(e)},onReconnect:e=>{ae(e)}},e.name))})})]})}export{L as McpServersPanel};
5
+ `)){let e=n.trim();if(!e)continue;let r=e.indexOf(`=`);if(r<=0)continue;let i=e.slice(0,r).trim(),a=e.slice(r+1).trim();i&&(t[i]=a)}return t}function k(e){let t={type:e.transport||`stdio`};e.transport===`stdio`?(t.command=e.command||``,t.args=e.args||[],e.cwd&&(t.cwd=e.cwd),e.env&&Object.keys(e.env).length>0&&(t.env=e.env)):(t.url=e.url||``,e.env&&Object.keys(e.env).length>0&&(t.headers=e.env));let n=e.name||`server`;return JSON.stringify({mcpServers:{[n]:t}},null,2)}function A(e){return!!(e&&typeof e==`object`&&!Array.isArray(e))}function j(e){let t;try{t=JSON.parse(e)}catch{throw Error(h(`mcpInvalidJson`))}if(!A(t))throw Error(h(`mcpInvalidConfigJson`));let n=``,r=null;if(A(t.mcpServers)){let e=Object.entries(t.mcpServers);if(e.length===0)throw Error(h(`mcpEmptyConfigJson`));let[i,a]=e[0];n=i,A(a)&&(r=a)}else r=t;if(!r)throw Error(h(`mcpInvalidConfigJson`));let i=String(r.transport||r.type||`stdio`);if(![`stdio`,`http`,`sse`].includes(i))throw Error(h(`mcpInvalidTransport`,{name:n||`server`}));let a=r.env??r.headers??{};return{name:n,transport:i,command:String(r.command||``),args:Array.isArray(r.args)?r.args:[],url:String(r.url||``),cwd:String(r.cwd||``),env:A(a)?a:{}}}var M=`mb-1 block text-xs text-muted-foreground/72`,N=`min-h-20 w-full resize-y rounded-md border border-input bg-background px-2 py-1.5 font-mono text-xs text-foreground outline-none focus:border-ring`,P=`flex h-9 w-full rounded-md border border-input bg-transparent px-3 text-sm outline-none focus:border-ring`;function F({value:e,onChange:t,isEdit:n,disabled:r}){let i=e.transport===`stdio`,a=n=>t({...e,...n});return(0,y.jsxs)(`div`,{className:`space-y-3 p-3`,children:[(0,y.jsx)(`div`,{className:`text-xs text-muted-foreground/60`,children:h(n?`mcpEditServer`:`mcpAddServer`)}),(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`label`,{className:M,htmlFor:`mcp-server-name`,children:h(`mcpServerName`)}),(0,y.jsx)(p,{id:`mcp-server-name`,value:e.name,onChange:e=>a({name:e.target.value}),placeholder:h(`mcpNamePlaceholder`),disabled:n||r})]}),(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`label`,{className:M,htmlFor:`mcp-server-transport`,children:h(`mcpTransport`)}),(0,y.jsxs)(`select`,{id:`mcp-server-transport`,className:P,value:e.transport,onChange:e=>a({transport:e.target.value}),disabled:r,children:[(0,y.jsx)(`option`,{value:`stdio`,children:`stdio`}),(0,y.jsx)(`option`,{value:`http`,children:`http`}),(0,y.jsx)(`option`,{value:`sse`,children:`sse`})]})]}),i?(0,y.jsxs)(y.Fragment,{children:[(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`label`,{className:M,htmlFor:`mcp-server-command`,children:h(`mcpCommand`)}),(0,y.jsx)(p,{id:`mcp-server-command`,value:e.command,onChange:e=>a({command:e.target.value}),placeholder:h(`mcpCommandPlaceholder`),disabled:r})]}),(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`label`,{className:M,htmlFor:`mcp-server-args`,children:h(`mcpArgs`)}),(0,y.jsx)(`textarea`,{id:`mcp-server-args`,className:N,value:T(e.args),onChange:e=>a({args:D(e.target.value)}),spellCheck:!1,disabled:r})]}),(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`label`,{className:M,htmlFor:`mcp-server-cwd`,children:h(`mcpCwd`)}),(0,y.jsx)(p,{id:`mcp-server-cwd`,value:e.cwd,onChange:e=>a({cwd:e.target.value}),disabled:r})]}),(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`label`,{className:M,htmlFor:`mcp-server-env`,children:h(`mcpEnv`)}),(0,y.jsx)(`textarea`,{id:`mcp-server-env`,className:N,value:E(e.env),onChange:e=>a({env:O(e.target.value)}),spellCheck:!1,disabled:r})]})]}):(0,y.jsxs)(y.Fragment,{children:[(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`label`,{className:M,htmlFor:`mcp-server-url`,children:h(`mcpUrl`)}),(0,y.jsx)(p,{id:`mcp-server-url`,value:e.url,onChange:e=>a({url:e.target.value}),placeholder:h(`mcpUrlPlaceholder`),disabled:r})]}),(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`label`,{className:M,htmlFor:`mcp-server-headers`,children:h(`mcpHeaders`)}),(0,y.jsx)(`textarea`,{id:`mcp-server-headers`,className:N,value:E(e.env),onChange:e=>a({env:O(e.target.value)}),spellCheck:!1,disabled:r})]})]})]})}async function I(e){let t=await e.json().catch(()=>null);if(!e.ok)throw Error(t?.error||`HTTP ${e.status}`);return t}function L({active:e=!0,className:t}){let[r,o]=(0,v.useState)([]),[s,d]=(0,v.useState)(!1),[p,b]=(0,v.useState)(!1),[x,T]=(0,v.useState)(new Set),[E,D]=(0,v.useState)(null),[O,A]=(0,v.useState)(``),[M,N]=(0,v.useState)(!1),[P,L]=(0,v.useState)(null),[R,z]=(0,v.useState)(C),[B,V]=(0,v.useState)(`form`),[H,U]=(0,v.useState)(``),[W,G]=(0,v.useState)(``),K=(0,v.useCallback)(e=>{o(e?.servers??[])},[]),q=(0,v.useCallback)(async()=>{d(!0),A(``);try{K(await I(await fetch(`/api/mcp/servers`)))}catch(e){A(e instanceof Error?e.message:h(`mcpLoadFailed`))}finally{d(!1)}},[K]);if((0,v.useEffect)(()=>{if(!e)return;let t=window.setTimeout(()=>{q()},0);return()=>window.clearTimeout(t)},[e,q]),!e)return null;let J=e=>{e===`json`&&(U(k(R)),G(``)),V(e)},Y=()=>{L(null),z(C()),V(`form`),N(!0),A(``)},X=e=>{let t=w(e);L(e),z(t),U(k(t)),G(``),V(`form`),N(!0),A(``)},Z=()=>{N(!1),L(null),U(``),G(``),A(``)},Q=e=>{z(e)},ee=e=>{U(e);try{let t=j(e);z(e=>({...t,name:t.name||e.name})),G(``)}catch(e){G(e instanceof Error?e.message:h(`mcpInvalidJson`))}},te=async()=>{if(!p){if(W&&B===`json`){A(W);return}b(!0),A(``);try{K(await I(await fetch(`/api/mcp/servers`,{method:`PUT`,headers:{"content-type":`application/json`},body:JSON.stringify({server:{...R,enabled:P?.enabled??!0}})}))),Z()}catch(e){A(e instanceof Error?e.message:h(`mcpSaveFailed`))}finally{b(!1)}}},ne=async e=>{if(await f({description:h(`mcpDeleteConfirm`,{name:e}),confirmLabel:h(`confirmDelete`),cancelLabel:h(`cancel`),variant:`destructive`})){A(``);try{K(await I(await fetch(`/api/mcp/servers/${encodeURIComponent(e)}`,{method:`DELETE`})))}catch(e){A(e instanceof Error?e.message:h(`mcpDeleteFailed`))}}},re=async e=>{if(!x.has(e.name)){T(t=>new Set(t).add(e.name)),A(``);try{K(await I(await fetch(`/api/mcp/servers/${encodeURIComponent(e.name)}/enabled`,{method:`PUT`,headers:{"content-type":`application/json`},body:JSON.stringify({enabled:!e.enabled})})))}catch(e){A(e instanceof Error?e.message:h(`mcpSaveFailed`))}finally{T(t=>{let n=new Set(t);return n.delete(e.name),n})}}},ie=async()=>{d(!0),A(``);try{K(await I(await fetch(`/api/mcp/reconnect`,{method:`POST`})))}catch(e){A(e instanceof Error?e.message:h(`mcpReconnectFailed`))}finally{d(!1)}},ae=async e=>{if(!E){D(e),A(``);try{K(await I(await fetch(`/api/mcp/reconnect/${encodeURIComponent(e)}`,{method:`POST`})))}catch(e){A(e instanceof Error?e.message:h(`mcpReconnectFailed`))}finally{D(null)}}},$=!!P,oe=!!R.name.trim()&&!!(R.transport===`stdio`?R.command.trim():R.url.trim());return M?(0,y.jsxs)(`div`,{className:_(`flex min-h-0 flex-1 flex-col overflow-hidden bg-background`,t),children:[(0,y.jsx)(`div`,{className:`border-b border-border px-6 py-5`,children:(0,y.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,y.jsxs)(`button`,{type:`button`,className:`inline-flex items-center gap-1.5 text-sm text-muted-foreground hover:text-foreground`,onClick:Z,children:[(0,y.jsx)(i,{className:`size-4`}),h(`mcpConfiguredServers`)]}),(0,y.jsx)(`span`,{className:`text-sm font-medium text-foreground/90`,children:h($?`mcpEditServer`:`mcpAddServer`)})]})}),O?(0,y.jsx)(`div`,{className:`m-6 mb-0 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive`,children:O}):null,(0,y.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto p-6`,children:(0,y.jsxs)(`div`,{className:`mx-auto max-w-5xl space-y-5`,children:[(0,y.jsxs)(`div`,{className:`flex border-b border-border`,children:[(0,y.jsxs)(`button`,{type:`button`,onClick:()=>J(`form`),className:_(`flex flex-1 items-center justify-center gap-1.5 px-3 py-2.5 text-xs font-medium transition-colors`,B===`form`?`border-b-2 border-primary text-foreground/90 -mb-px`:`text-muted-foreground/60 hover:text-foreground/85`),children:[(0,y.jsx)(c,{className:`size-3.5`}),h(`mcpTabServer`)]}),(0,y.jsxs)(`button`,{type:`button`,onClick:()=>J(`json`),className:_(`flex flex-1 items-center justify-center gap-1.5 px-3 py-2.5 text-xs font-medium transition-colors`,B===`json`?`border-b-2 border-primary text-foreground/90 -mb-px`:`text-muted-foreground/60 hover:text-foreground/85`),children:[(0,y.jsx)(a,{className:`size-3.5`}),h(`mcpTabJson`)]})]}),(0,y.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto`,children:B===`form`?(0,y.jsx)(F,{value:R,onChange:Q,isEdit:$,disabled:p}):(0,y.jsxs)(`div`,{className:`space-y-2`,children:[(0,y.jsx)(`textarea`,{className:`min-h-96 w-full resize-y rounded-md border border-input bg-background px-2 py-1.5 font-mono text-xs text-foreground outline-none focus:border-ring`,value:H,onChange:e=>ee(e.target.value),spellCheck:!1}),W?(0,y.jsx)(`div`,{className:`rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive`,children:W}):null,(0,y.jsxs)(`div`,{className:`inline-flex items-center gap-1.5 text-[11px] font-medium text-foreground/90`,children:[h(`mcpTabJson`),(0,y.jsx)(g,{label:h(`mcpImportConfigDescription`)})]})]})}),(0,y.jsxs)(`div`,{className:`flex justify-end gap-2 border-t border-border pt-3`,children:[(0,y.jsx)(m,{type:`button`,variant:`outline`,size:`sm`,onClick:Z,disabled:p,children:h(`cancel`)}),(0,y.jsxs)(m,{type:`button`,size:`sm`,onClick:()=>{te()},disabled:p||!oe,children:[p?(0,y.jsx)(n,{className:`mr-1.5 size-3.5 animate-spin`}):null,h(`save`)]})]})]})})]}):(0,y.jsxs)(`div`,{className:_(`flex min-h-0 flex-1 flex-col overflow-hidden bg-background`,t),children:[(0,y.jsx)(`div`,{className:`border-b border-border px-6 py-5`,children:(0,y.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,y.jsx)(`h3`,{className:`text-sm font-medium text-foreground/90`,children:h(`mcpConfiguredServers`)}),(0,y.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,y.jsxs)(m,{type:`button`,variant:`ghost`,size:`sm`,onClick:Y,children:[(0,y.jsx)(l,{className:`mr-1.5 size-3.5`}),h(`mcpAddServer`)]}),(0,y.jsxs)(m,{type:`button`,variant:`ghost`,size:`sm`,onClick:ie,disabled:s,children:[s?(0,y.jsx)(n,{className:`mr-1.5 size-3.5 animate-spin`}):(0,y.jsx)(u,{className:`mr-1.5 size-3.5`}),h(`mcpReconnect`)]})]})]})}),O?(0,y.jsx)(`div`,{className:`m-6 mb-0 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive`,children:O}):null,(0,y.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto p-6`,children:(0,y.jsx)(`div`,{className:`mx-auto max-w-5xl space-y-5`,children:s&&r.length===0?(0,y.jsxs)(`div`,{className:`flex items-center justify-center gap-2 rounded-lg border border-border py-8 text-sm text-muted-foreground`,children:[(0,y.jsx)(n,{className:`size-4 animate-spin`}),h(`loading`)]}):r.length===0?(0,y.jsx)(`div`,{className:`rounded-lg border border-border bg-muted/15 p-4 text-sm text-muted-foreground/72`,children:h(`mcpNoServersDescription`)}):r.map(e=>(0,y.jsx)(S,{server:e,toggling:x.has(e.name),reconnecting:E===e.name,onToggle:e=>{re(e)},onEdit:X,onDelete:e=>{ne(e)},onReconnect:e=>{ae(e)}},e.name))})})]})}export{L as McpServersPanel};
@@ -1,4 +1,4 @@
1
- import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{Vt as t}from"./icons-C7j5jdKo.js";function n(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function r(e){if(Array.isArray(e))return e}function i(e,t,n){return(t=p(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=e==null?null:typeof Symbol<`u`&&e[Symbol.iterator]||e[`@@iterator`];if(n!=null){var r,i,a,o,s=[],c=!0,l=!1;try{if(a=(n=n.call(e)).next,t!==0)for(;!(c=(r=a.call(n)).done)&&(s.push(r.value),s.length!==t);c=!0);}catch(e){l=!0,i=e}finally{try{if(!c&&n.return!=null&&(o=n.return(),Object(o)!==o))return}finally{if(l)throw i}}return s}}function o(){throw TypeError(`Invalid attempt to destructure non-iterable instance.
1
+ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{Ot as t}from"./icons-DAxUA0e-.js";function n(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function r(e){if(Array.isArray(e))return e}function i(e,t,n){return(t=p(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=e==null?null:typeof Symbol<`u`&&e[Symbol.iterator]||e[`@@iterator`];if(n!=null){var r,i,a,o,s=[],c=!0,l=!1;try{if(a=(n=n.call(e)).next,t!==0)for(;!(c=(r=a.call(n)).done)&&(s.push(r.value),s.length!==t);c=!0);}catch(e){l=!0,i=e}finally{try{if(!c&&n.return!=null&&(o=n.return(),Object(o)!==o))return}finally{if(l)throw i}}return s}}function o(){throw TypeError(`Invalid attempt to destructure non-iterable instance.
2
2
  In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?s(Object(n),!0).forEach(function(t){i(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):s(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function l(e,t){if(e==null)return{};var n,r,i=u(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function u(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function d(e,t){return r(e)||a(e,t)||m(e,t)||o()}function f(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function p(e){var t=f(e,`string`);return typeof t==`symbol`?t:t+``}function m(e,t){if(e){if(typeof e==`string`)return n(e,t);var r={}.toString.call(e).slice(8,-1);return r===`Object`&&e.constructor&&(r=e.constructor.name),r===`Map`||r===`Set`?Array.from(e):r===`Arguments`||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?n(e,t):void 0}}function h(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function g(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function _(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?g(Object(n),!0).forEach(function(t){h(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):g(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function v(){var e=[...arguments];return function(t){return e.reduceRight(function(e,t){return t(e)},t)}}function y(e){return function t(){var n=this,r=[...arguments];return r.length>=e.length?e.apply(this,r):function(){var e=[...arguments];return t.apply(n,[].concat(r,e))}}}function b(e){return{}.toString.call(e).includes(`Object`)}function x(e){return!Object.keys(e).length}function S(e){return typeof e==`function`}function C(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function w(e,t){return b(t)||k(`changeType`),Object.keys(t).some(function(t){return!C(e,t)})&&k(`changeField`),t}function T(e){S(e)||k(`selectorType`)}function E(e){S(e)||b(e)||k(`handlerType`),b(e)&&Object.values(e).some(function(e){return!S(e)})&&k(`handlersType`)}function D(e){e||k(`initialIsRequired`),b(e)||k(`initialType`),x(e)&&k(`initialContent`)}function O(e,t){throw Error(e[t]||e.default)}var k=y(O)({initialIsRequired:`initial state is required`,initialType:`initial state should be an object`,initialContent:`initial state shouldn't be an empty object`,handlerType:`handler should be an object or a function`,handlersType:`all handlers should be a functions`,selectorType:`selector should be a function`,changeType:`provided value of changes should be an object`,changeField:`it seams you want to change a field in the state which is not specified in the "initial" state`,default:"an unknown error accured in `state-local` package"}),A={changes:w,selector:T,handler:E,initial:D};function j(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};A.initial(e),A.handler(t);var n={current:e},r=y(P)(n,t),i=y(N)(n),a=y(A.changes)(e),o=y(M)(n);function s(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:function(e){return e};return A.selector(e),e(n.current)}function c(e){v(r,i,a,o)(e)}return[s,c]}function M(e,t){return S(t)?t(e.current):t}function N(e,t){return e.current=_(_({},e.current),t),t}function P(e,t,n){return S(t)?t(e.current):Object.keys(n).forEach(function(n){return t[n]?.call(t,e.current[n])}),n}var F={create:j},I={paths:{vs:`https://cdn.jsdelivr.net/npm/monaco-editor@0.55.1/min/vs`}};function ee(e){return function t(){var n=this,r=[...arguments];return r.length>=e.length?e.apply(this,r):function(){var e=[...arguments];return t.apply(n,[].concat(r,e))}}}function te(e){return{}.toString.call(e).includes(`Object`)}function ne(e){return e||R(`configIsRequired`),te(e)||R(`configType`),e.urls?(re(),{paths:{vs:e.urls.monacoBase}}):e}function re(){console.warn(L.deprecation)}function ie(e,t){throw Error(e[t]||e.default)}var L={configIsRequired:`the configuration object is required`,configType:`the configuration object should be an object`,default:"an unknown error accured in `@monaco-editor/loader` package",deprecation:`Deprecation warning!
3
3
  You are using deprecated way of configuration.
4
4
 
@@ -1,4 +1,4 @@
1
- import{t as e}from"./rolldown-runtime-DWdDZTNf.js";import{Vt as t}from"./icons-C7j5jdKo.js";var n=e((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0<n;){var r=n-1>>>1,a=e[r];if(0<i(a,t))e[r]=t,e[n]=a,n=r;else break a}}function n(e){return e.length===0?null:e[0]}function r(e){if(e.length===0)return null;var t=e[0],n=e.pop();if(n!==t){e[0]=n;a:for(var r=0,a=e.length,o=a>>>1;r<o;){var s=2*(r+1)-1,c=e[s],l=s+1,u=e[l];if(0>i(c,n))l<a&&0>i(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(l<a&&0>i(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m)if(n(c)!==null)m=!0,S||(S=!0,D());else{var t=n(l);t!==null&&A(x,t.startTime-e)}}var S=!1,C=-1,ee=5,w=-1;function T(){return g?!0:!(e.unstable_now()-w<ee)}function E(){if(g=!1,S){var t=e.unstable_now();w=t;var i=!0;try{a:{m=!1,h&&(h=!1,v(C),C=-1),p=!0;var a=f;try{b:{for(b(t),d=n(c);d!==null&&!(d.expirationTime>t&&T());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&A(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?D():S=!1}}}var D;if(typeof y==`function`)D=function(){y(E)};else if(typeof MessageChannel<`u`){var O=new MessageChannel,k=O.port2;O.port1.onmessage=E,D=function(){k.postMessage(null)}}else D=function(){_(E,0)};function A(t,n){C=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125<e?console.error(`forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported`):ee=0<e?Math.floor(1e3/e):5},e.unstable_getCurrentPriorityLevel=function(){return f},e.unstable_next=function(e){switch(f){case 1:case 2:case 3:var t=3;break;default:t=f}var n=f;f=t;try{return e()}finally{f=n}},e.unstable_requestPaint=function(){g=!0},e.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=f;f=e;try{return t()}finally{f=n}},e.unstable_scheduleCallback=function(r,i,a){var o=e.unstable_now();switch(typeof a==`object`&&a?(a=a.delay,a=typeof a==`number`&&0<a?o+a:o):a=o,r){case 1:var s=-1;break;case 2:s=250;break;case 5:s=1073741823;break;case 4:s=1e4;break;default:s=5e3}return s=a+s,r={id:u++,callback:i,priorityLevel:r,startTime:a,expirationTime:s,sortIndex:-1},a>o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(C),C=-1):h=!0,A(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,S||(S=!0,D()))),r},e.unstable_shouldYield=T,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),r=e(((e,t)=>{t.exports=n()})),i=e((e=>{var n=t();function r(e){var t=`https://react.dev/errors/`+e;if(1<arguments.length){t+=`?args[]=`+encodeURIComponent(arguments[1]);for(var n=2;n<arguments.length;n++)t+=`&args[]=`+encodeURIComponent(arguments[n])}return`Minified React error #`+e+`; visit `+t+` for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`}function i(){}var a={d:{f:i,r:function(){throw Error(r(522))},D:i,C:i,L:i,m:i,X:i,S:i,M:i},p:0,findDOMNode:null},o=Symbol.for(`react.portal`);function s(e,t,n){var r=3<arguments.length&&arguments[3]!==void 0?arguments[3]:null;return{$$typeof:o,key:r==null?null:``+r,children:e,containerInfo:t,implementation:n}}var c=n.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;function l(e,t){if(e===`font`)return``;if(typeof t==`string`)return t===`use-credentials`?t:``}e.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=a,e.createPortal=function(e,t){var n=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null;if(!t||t.nodeType!==1&&t.nodeType!==9&&t.nodeType!==11)throw Error(r(299));return s(e,t,null,n)},e.flushSync=function(e){var t=c.T,n=a.p;try{if(c.T=null,a.p=2,e)return e()}finally{c.T=t,a.p=n,a.d.f()}},e.preconnect=function(e,t){typeof e==`string`&&(t?(t=t.crossOrigin,t=typeof t==`string`?t===`use-credentials`?t:``:void 0):t=null,a.d.C(e,t))},e.prefetchDNS=function(e){typeof e==`string`&&a.d.D(e)},e.preinit=function(e,t){if(typeof e==`string`&&t&&typeof t.as==`string`){var n=t.as,r=l(n,t.crossOrigin),i=typeof t.integrity==`string`?t.integrity:void 0,o=typeof t.fetchPriority==`string`?t.fetchPriority:void 0;n===`style`?a.d.S(e,typeof t.precedence==`string`?t.precedence:void 0,{crossOrigin:r,integrity:i,fetchPriority:o}):n===`script`&&a.d.X(e,{crossOrigin:r,integrity:i,fetchPriority:o,nonce:typeof t.nonce==`string`?t.nonce:void 0})}},e.preinitModule=function(e,t){if(typeof e==`string`)if(typeof t==`object`&&t){if(t.as==null||t.as===`script`){var n=l(t.as,t.crossOrigin);a.d.M(e,{crossOrigin:n,integrity:typeof t.integrity==`string`?t.integrity:void 0,nonce:typeof t.nonce==`string`?t.nonce:void 0})}}else t??a.d.M(e)},e.preload=function(e,t){if(typeof e==`string`&&typeof t==`object`&&t&&typeof t.as==`string`){var n=t.as,r=l(n,t.crossOrigin);a.d.L(e,n,{crossOrigin:r,integrity:typeof t.integrity==`string`?t.integrity:void 0,nonce:typeof t.nonce==`string`?t.nonce:void 0,type:typeof t.type==`string`?t.type:void 0,fetchPriority:typeof t.fetchPriority==`string`?t.fetchPriority:void 0,referrerPolicy:typeof t.referrerPolicy==`string`?t.referrerPolicy:void 0,imageSrcSet:typeof t.imageSrcSet==`string`?t.imageSrcSet:void 0,imageSizes:typeof t.imageSizes==`string`?t.imageSizes:void 0,media:typeof t.media==`string`?t.media:void 0})}},e.preloadModule=function(e,t){if(typeof e==`string`)if(t){var n=l(t.as,t.crossOrigin);a.d.m(e,{as:typeof t.as==`string`&&t.as!==`script`?t.as:void 0,crossOrigin:n,integrity:typeof t.integrity==`string`?t.integrity:void 0})}else a.d.m(e)},e.requestFormReset=function(e){a.d.r(e)},e.unstable_batchedUpdates=function(e,t){return e(t)},e.useFormState=function(e,t,n){return c.H.useFormState(e,t,n)},e.useFormStatus=function(){return c.H.useHostTransitionStatus()},e.version=`19.2.5`})),a=e(((e,t)=>{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=i()})),o=e((e=>{var n=r(),i=t(),o=a();function s(e){var t=`https://react.dev/errors/`+e;if(1<arguments.length){t+=`?args[]=`+encodeURIComponent(arguments[1]);for(var n=2;n<arguments.length;n++)t+=`&args[]=`+encodeURIComponent(arguments[n])}return`Minified React error #`+e+`; visit `+t+` for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`}function c(e){return!(!e||e.nodeType!==1&&e.nodeType!==9&&e.nodeType!==11)}function l(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do t=e,t.flags&4098&&(n=t.return),e=t.return;while(e)}return t.tag===3?n:null}function u(e){if(e.tag===13){var t=e.memoizedState;if(t===null&&(e=e.alternate,e!==null&&(t=e.memoizedState)),t!==null)return t.dehydrated}return null}function d(e){if(e.tag===31){var t=e.memoizedState;if(t===null&&(e=e.alternate,e!==null&&(t=e.memoizedState)),t!==null)return t.dehydrated}return null}function f(e){if(l(e)!==e)throw Error(s(188))}function p(e){var t=e.alternate;if(!t){if(t=l(e),t===null)throw Error(s(188));return t===e?e:null}for(var n=e,r=t;;){var i=n.return;if(i===null)break;var a=i.alternate;if(a===null){if(r=i.return,r!==null){n=r;continue}break}if(i.child===a.child){for(a=i.child;a;){if(a===n)return f(i),e;if(a===r)return f(i),t;a=a.sibling}throw Error(s(188))}if(n.return!==r.return)n=i,r=a;else{for(var o=!1,c=i.child;c;){if(c===n){o=!0,n=i,r=a;break}if(c===r){o=!0,r=i,n=a;break}c=c.sibling}if(!o){for(c=a.child;c;){if(c===n){o=!0,n=a,r=i;break}if(c===r){o=!0,r=a,n=i;break}c=c.sibling}if(!o)throw Error(s(189))}}if(n.alternate!==r)throw Error(s(190))}if(n.tag!==3)throw Error(s(188));return n.stateNode.current===n?e:t}function m(e){var t=e.tag;if(t===5||t===26||t===27||t===6)return e;for(e=e.child;e!==null;){if(t=m(e),t!==null)return t;e=e.sibling}return null}var h=Object.assign,g=Symbol.for(`react.element`),_=Symbol.for(`react.transitional.element`),v=Symbol.for(`react.portal`),y=Symbol.for(`react.fragment`),b=Symbol.for(`react.strict_mode`),x=Symbol.for(`react.profiler`),S=Symbol.for(`react.consumer`),C=Symbol.for(`react.context`),ee=Symbol.for(`react.forward_ref`),w=Symbol.for(`react.suspense`),T=Symbol.for(`react.suspense_list`),E=Symbol.for(`react.memo`),D=Symbol.for(`react.lazy`),O=Symbol.for(`react.activity`),k=Symbol.for(`react.memo_cache_sentinel`),A=Symbol.iterator;function te(e){return typeof e!=`object`||!e?null:(e=A&&e[A]||e[`@@iterator`],typeof e==`function`?e:null)}var j=Symbol.for(`react.client.reference`);function M(e){if(e==null)return null;if(typeof e==`function`)return e.$$typeof===j?null:e.displayName||e.name||null;if(typeof e==`string`)return e;switch(e){case y:return`Fragment`;case x:return`Profiler`;case b:return`StrictMode`;case w:return`Suspense`;case T:return`SuspenseList`;case O:return`Activity`}if(typeof e==`object`)switch(e.$$typeof){case v:return`Portal`;case C:return e.displayName||`Context`;case S:return(e._context.displayName||`Context`)+`.Consumer`;case ee:var t=e.render;return e=e.displayName,e||=(e=t.displayName||t.name||``,e===``?`ForwardRef`:`ForwardRef(`+e+`)`),e;case E:return t=e.displayName||null,t===null?M(e.type)||`Memo`:t;case D:t=e._payload,e=e._init;try{return M(e(t))}catch{}}return null}var N=Array.isArray,P=i.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,F=o.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,ne={pending:!1,data:null,method:null,action:null},I=[],L=-1;function re(e){return{current:e}}function R(e){0>L||(e.current=I[L],I[L]=null,L--)}function z(e,t){L++,I[L]=e.current,e.current=t}var B=re(null),ie=re(null),ae=re(null),oe=re(null);function se(e,t){switch(z(ae,t),z(ie,e),z(B,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Vd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Vd(t),e=Hd(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}R(B),z(B,e)}function ce(){R(B),R(ie),R(ae)}function V(e){e.memoizedState!==null&&z(oe,e);var t=B.current,n=Hd(t,e.type);t!==n&&(z(ie,e),z(B,n))}function le(e){ie.current===e&&(R(B),R(ie)),oe.current===e&&(R(oe),Qf._currentValue=ne)}var H,ue;function de(e){if(H===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);H=t&&t[1]||``,ue=-1<e.stack.indexOf(`
1
+ import{t as e}from"./rolldown-runtime-DWdDZTNf.js";import{Ot as t}from"./icons-DAxUA0e-.js";var n=e((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0<n;){var r=n-1>>>1,a=e[r];if(0<i(a,t))e[r]=t,e[n]=a,n=r;else break a}}function n(e){return e.length===0?null:e[0]}function r(e){if(e.length===0)return null;var t=e[0],n=e.pop();if(n!==t){e[0]=n;a:for(var r=0,a=e.length,o=a>>>1;r<o;){var s=2*(r+1)-1,c=e[s],l=s+1,u=e[l];if(0>i(c,n))l<a&&0>i(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(l<a&&0>i(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m)if(n(c)!==null)m=!0,S||(S=!0,D());else{var t=n(l);t!==null&&A(x,t.startTime-e)}}var S=!1,C=-1,ee=5,w=-1;function T(){return g?!0:!(e.unstable_now()-w<ee)}function E(){if(g=!1,S){var t=e.unstable_now();w=t;var i=!0;try{a:{m=!1,h&&(h=!1,v(C),C=-1),p=!0;var a=f;try{b:{for(b(t),d=n(c);d!==null&&!(d.expirationTime>t&&T());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&A(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?D():S=!1}}}var D;if(typeof y==`function`)D=function(){y(E)};else if(typeof MessageChannel<`u`){var O=new MessageChannel,k=O.port2;O.port1.onmessage=E,D=function(){k.postMessage(null)}}else D=function(){_(E,0)};function A(t,n){C=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125<e?console.error(`forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported`):ee=0<e?Math.floor(1e3/e):5},e.unstable_getCurrentPriorityLevel=function(){return f},e.unstable_next=function(e){switch(f){case 1:case 2:case 3:var t=3;break;default:t=f}var n=f;f=t;try{return e()}finally{f=n}},e.unstable_requestPaint=function(){g=!0},e.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=f;f=e;try{return t()}finally{f=n}},e.unstable_scheduleCallback=function(r,i,a){var o=e.unstable_now();switch(typeof a==`object`&&a?(a=a.delay,a=typeof a==`number`&&0<a?o+a:o):a=o,r){case 1:var s=-1;break;case 2:s=250;break;case 5:s=1073741823;break;case 4:s=1e4;break;default:s=5e3}return s=a+s,r={id:u++,callback:i,priorityLevel:r,startTime:a,expirationTime:s,sortIndex:-1},a>o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(C),C=-1):h=!0,A(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,S||(S=!0,D()))),r},e.unstable_shouldYield=T,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),r=e(((e,t)=>{t.exports=n()})),i=e((e=>{var n=t();function r(e){var t=`https://react.dev/errors/`+e;if(1<arguments.length){t+=`?args[]=`+encodeURIComponent(arguments[1]);for(var n=2;n<arguments.length;n++)t+=`&args[]=`+encodeURIComponent(arguments[n])}return`Minified React error #`+e+`; visit `+t+` for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`}function i(){}var a={d:{f:i,r:function(){throw Error(r(522))},D:i,C:i,L:i,m:i,X:i,S:i,M:i},p:0,findDOMNode:null},o=Symbol.for(`react.portal`);function s(e,t,n){var r=3<arguments.length&&arguments[3]!==void 0?arguments[3]:null;return{$$typeof:o,key:r==null?null:``+r,children:e,containerInfo:t,implementation:n}}var c=n.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;function l(e,t){if(e===`font`)return``;if(typeof t==`string`)return t===`use-credentials`?t:``}e.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=a,e.createPortal=function(e,t){var n=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null;if(!t||t.nodeType!==1&&t.nodeType!==9&&t.nodeType!==11)throw Error(r(299));return s(e,t,null,n)},e.flushSync=function(e){var t=c.T,n=a.p;try{if(c.T=null,a.p=2,e)return e()}finally{c.T=t,a.p=n,a.d.f()}},e.preconnect=function(e,t){typeof e==`string`&&(t?(t=t.crossOrigin,t=typeof t==`string`?t===`use-credentials`?t:``:void 0):t=null,a.d.C(e,t))},e.prefetchDNS=function(e){typeof e==`string`&&a.d.D(e)},e.preinit=function(e,t){if(typeof e==`string`&&t&&typeof t.as==`string`){var n=t.as,r=l(n,t.crossOrigin),i=typeof t.integrity==`string`?t.integrity:void 0,o=typeof t.fetchPriority==`string`?t.fetchPriority:void 0;n===`style`?a.d.S(e,typeof t.precedence==`string`?t.precedence:void 0,{crossOrigin:r,integrity:i,fetchPriority:o}):n===`script`&&a.d.X(e,{crossOrigin:r,integrity:i,fetchPriority:o,nonce:typeof t.nonce==`string`?t.nonce:void 0})}},e.preinitModule=function(e,t){if(typeof e==`string`)if(typeof t==`object`&&t){if(t.as==null||t.as===`script`){var n=l(t.as,t.crossOrigin);a.d.M(e,{crossOrigin:n,integrity:typeof t.integrity==`string`?t.integrity:void 0,nonce:typeof t.nonce==`string`?t.nonce:void 0})}}else t??a.d.M(e)},e.preload=function(e,t){if(typeof e==`string`&&typeof t==`object`&&t&&typeof t.as==`string`){var n=t.as,r=l(n,t.crossOrigin);a.d.L(e,n,{crossOrigin:r,integrity:typeof t.integrity==`string`?t.integrity:void 0,nonce:typeof t.nonce==`string`?t.nonce:void 0,type:typeof t.type==`string`?t.type:void 0,fetchPriority:typeof t.fetchPriority==`string`?t.fetchPriority:void 0,referrerPolicy:typeof t.referrerPolicy==`string`?t.referrerPolicy:void 0,imageSrcSet:typeof t.imageSrcSet==`string`?t.imageSrcSet:void 0,imageSizes:typeof t.imageSizes==`string`?t.imageSizes:void 0,media:typeof t.media==`string`?t.media:void 0})}},e.preloadModule=function(e,t){if(typeof e==`string`)if(t){var n=l(t.as,t.crossOrigin);a.d.m(e,{as:typeof t.as==`string`&&t.as!==`script`?t.as:void 0,crossOrigin:n,integrity:typeof t.integrity==`string`?t.integrity:void 0})}else a.d.m(e)},e.requestFormReset=function(e){a.d.r(e)},e.unstable_batchedUpdates=function(e,t){return e(t)},e.useFormState=function(e,t,n){return c.H.useFormState(e,t,n)},e.useFormStatus=function(){return c.H.useHostTransitionStatus()},e.version=`19.2.5`})),a=e(((e,t)=>{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=i()})),o=e((e=>{var n=r(),i=t(),o=a();function s(e){var t=`https://react.dev/errors/`+e;if(1<arguments.length){t+=`?args[]=`+encodeURIComponent(arguments[1]);for(var n=2;n<arguments.length;n++)t+=`&args[]=`+encodeURIComponent(arguments[n])}return`Minified React error #`+e+`; visit `+t+` for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`}function c(e){return!(!e||e.nodeType!==1&&e.nodeType!==9&&e.nodeType!==11)}function l(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do t=e,t.flags&4098&&(n=t.return),e=t.return;while(e)}return t.tag===3?n:null}function u(e){if(e.tag===13){var t=e.memoizedState;if(t===null&&(e=e.alternate,e!==null&&(t=e.memoizedState)),t!==null)return t.dehydrated}return null}function d(e){if(e.tag===31){var t=e.memoizedState;if(t===null&&(e=e.alternate,e!==null&&(t=e.memoizedState)),t!==null)return t.dehydrated}return null}function f(e){if(l(e)!==e)throw Error(s(188))}function p(e){var t=e.alternate;if(!t){if(t=l(e),t===null)throw Error(s(188));return t===e?e:null}for(var n=e,r=t;;){var i=n.return;if(i===null)break;var a=i.alternate;if(a===null){if(r=i.return,r!==null){n=r;continue}break}if(i.child===a.child){for(a=i.child;a;){if(a===n)return f(i),e;if(a===r)return f(i),t;a=a.sibling}throw Error(s(188))}if(n.return!==r.return)n=i,r=a;else{for(var o=!1,c=i.child;c;){if(c===n){o=!0,n=i,r=a;break}if(c===r){o=!0,r=i,n=a;break}c=c.sibling}if(!o){for(c=a.child;c;){if(c===n){o=!0,n=a,r=i;break}if(c===r){o=!0,r=a,n=i;break}c=c.sibling}if(!o)throw Error(s(189))}}if(n.alternate!==r)throw Error(s(190))}if(n.tag!==3)throw Error(s(188));return n.stateNode.current===n?e:t}function m(e){var t=e.tag;if(t===5||t===26||t===27||t===6)return e;for(e=e.child;e!==null;){if(t=m(e),t!==null)return t;e=e.sibling}return null}var h=Object.assign,g=Symbol.for(`react.element`),_=Symbol.for(`react.transitional.element`),v=Symbol.for(`react.portal`),y=Symbol.for(`react.fragment`),b=Symbol.for(`react.strict_mode`),x=Symbol.for(`react.profiler`),S=Symbol.for(`react.consumer`),C=Symbol.for(`react.context`),ee=Symbol.for(`react.forward_ref`),w=Symbol.for(`react.suspense`),T=Symbol.for(`react.suspense_list`),E=Symbol.for(`react.memo`),D=Symbol.for(`react.lazy`),O=Symbol.for(`react.activity`),k=Symbol.for(`react.memo_cache_sentinel`),A=Symbol.iterator;function te(e){return typeof e!=`object`||!e?null:(e=A&&e[A]||e[`@@iterator`],typeof e==`function`?e:null)}var j=Symbol.for(`react.client.reference`);function M(e){if(e==null)return null;if(typeof e==`function`)return e.$$typeof===j?null:e.displayName||e.name||null;if(typeof e==`string`)return e;switch(e){case y:return`Fragment`;case x:return`Profiler`;case b:return`StrictMode`;case w:return`Suspense`;case T:return`SuspenseList`;case O:return`Activity`}if(typeof e==`object`)switch(e.$$typeof){case v:return`Portal`;case C:return e.displayName||`Context`;case S:return(e._context.displayName||`Context`)+`.Consumer`;case ee:var t=e.render;return e=e.displayName,e||=(e=t.displayName||t.name||``,e===``?`ForwardRef`:`ForwardRef(`+e+`)`),e;case E:return t=e.displayName||null,t===null?M(e.type)||`Memo`:t;case D:t=e._payload,e=e._init;try{return M(e(t))}catch{}}return null}var N=Array.isArray,P=i.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,F=o.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,ne={pending:!1,data:null,method:null,action:null},I=[],L=-1;function re(e){return{current:e}}function R(e){0>L||(e.current=I[L],I[L]=null,L--)}function z(e,t){L++,I[L]=e.current,e.current=t}var B=re(null),ie=re(null),ae=re(null),oe=re(null);function se(e,t){switch(z(ae,t),z(ie,e),z(B,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Vd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Vd(t),e=Hd(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}R(B),z(B,e)}function ce(){R(B),R(ie),R(ae)}function V(e){e.memoizedState!==null&&z(oe,e);var t=B.current,n=Hd(t,e.type);t!==n&&(z(ie,e),z(B,n))}function le(e){ie.current===e&&(R(B),R(ie)),oe.current===e&&(R(oe),Qf._currentValue=ne)}var H,ue;function de(e){if(H===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);H=t&&t[1]||``,ue=-1<e.stack.indexOf(`
2
2
  at`)?` (<anonymous>)`:-1<e.stack.indexOf(`@`)?`@unknown:0:0`:``}return`
3
3
  `+H+e+ue}var fe=!1;function pe(e,t){if(!e||fe)return``;fe=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{var r={DetermineComponentFrameRoot:function(){try{if(t){var n=function(){throw Error()};if(Object.defineProperty(n.prototype,`props`,{set:function(){throw Error()}}),typeof Reflect==`object`&&Reflect.construct){try{Reflect.construct(n,[])}catch(e){var r=e}Reflect.construct(e,[],n)}else{try{n.call()}catch(e){r=e}e.call(n.prototype)}}else{try{throw Error()}catch(e){r=e}(n=e())&&typeof n.catch==`function`&&n.catch(function(){})}}catch(e){if(e&&r&&typeof e.stack==`string`)return[e.stack,r.stack]}return[null,null]}};r.DetermineComponentFrameRoot.displayName=`DetermineComponentFrameRoot`;var i=Object.getOwnPropertyDescriptor(r.DetermineComponentFrameRoot,`name`);i&&i.configurable&&Object.defineProperty(r.DetermineComponentFrameRoot,`name`,{value:`DetermineComponentFrameRoot`});var a=r.DetermineComponentFrameRoot(),o=a[0],s=a[1];if(o&&s){var c=o.split(`
4
4
  `),l=s.split(`
@@ -1 +1 @@
1
- import{i as e,n as t}from"./rolldown-runtime-DWdDZTNf.js";import{B as n,It as r,Rt as i,Vt as a,_ as o,n as s}from"./icons-C7j5jdKo.js";import{n as c}from"./react-vendor-VqdnQHHS.js";import{ct as l,dt as u,ht as d}from"./index-BFKildY3.js";var f=t({SkillsDialog:()=>_,SkillsManagerPanel:()=>g}),p=e(a(),1),m=c();async function h(e){let t=await e.json().catch(()=>null);if(!e.ok)throw Error(t?.error||`HTTP ${e.status}`);return t}function g({active:e=!0,scope:t,project:a,embedded:c=!1,onClose:f,onSaved:g}){let[_,v]=(0,p.useState)([]),[y,b]=(0,p.useState)(()=>new Set),[x,S]=(0,p.useState)(``),[C,w]=(0,p.useState)([]),[T,E]=(0,p.useState)(!1),[D,O]=(0,p.useState)(!1),[k,A]=(0,p.useState)(``),j=t===`project`,[M,N]=(0,p.useState)(null),[P,F]=(0,p.useState)(null),[I,L]=(0,p.useState)(!1),[R,z]=(0,p.useState)(``),B=(0,p.useCallback)(()=>{N(null),F(null),z(``)},[]),V=(0,p.useCallback)(()=>{B(),f?.()},[f,B]);(0,p.useEffect)(()=>{if(!e||j&&!a)return;let t=!1;return(async()=>{E(!0),A(``);try{let e=j?`/api/skills?projectId=${encodeURIComponent(a.id)}`:`/api/skills?scope=global`,n=await h(await fetch(e));if(t)return;v(Array.isArray(n.skills)?n.skills:[]),b(new Set(Array.isArray(n.selectedSkills)?n.selectedSkills:[])),w(Array.isArray(n.searchPaths)?n.searchPaths:[])}catch(e){t||A(e instanceof Error?e.message:d(`failedToLoadSkills`))}finally{t||E(!1)}})(),()=>{t=!0}},[e,a,j]),(0,p.useEffect)(()=>{if(!e||c)return;let t=e=>{e.key===`Escape`&&(M?B():D||V())};return document.addEventListener(`keydown`,t),()=>document.removeEventListener(`keydown`,t)},[e,V,c,D,M,B]);let H=(0,p.useMemo)(()=>{let e=x.trim().toLowerCase();return e?_.filter(t=>[t.name,t.displayName,t.description,t.source,t.compatibility,t.allowedTools,...t.tags??[],...t.triggers??[]].filter(Boolean).join(` `).toLowerCase().includes(e)):_},[x,_]),U=async e=>{N(e),F(null),z(``),L(!0);try{let t=new URLSearchParams({name:e});j&&a?(t.set(`scope`,`project`),t.set(`projectId`,a.id)):t.set(`scope`,`global`),F(await h(await fetch(`/api/skills/content?${t}`)))}catch(e){z(e instanceof Error?e.message:d(`failedToReadSkill`))}finally{L(!1)}};if(!e||j&&!a)return null;let W=e=>{if(D)return;let t=new Set(y);t.has(e)?t.delete(e):t.add(e),b(t),G(t)},G=async e=>{O(!0),A(``);try{let n=await h(await fetch(j?`/api/skills/project`:`/api/skills/global`,{method:`PUT`,headers:{"content-type":`application/json`},body:JSON.stringify(j?{projectId:a.id,selectedSkills:[...e]}:{selectedSkills:[...e]})}));g({scope:t,project:j?n.projects?.find(e=>e.id===a.id)??{...a,skills:n.selectedSkills}:void 0,projects:n.projects,selectedSkills:n.selectedSkills})}catch(e){b(y),A(e instanceof Error?e.message:d(`failedToSaveSkills`))}finally{O(!1)}},K=d(j?`projectSkills`:`globalSkills`),q=j?d(`projectSkillsDescription`,{project:a.name}):d(`globalSkillsDescription`),J=(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(`div`,{className:`quickforge-settings-divider p-3`,children:(0,m.jsxs)(`div`,{className:`quickforge-settings-inline-field`,children:[(0,m.jsx)(o,{className:`pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground/60`}),(0,m.jsx)(`input`,{value:x,onChange:e=>S(e.target.value),placeholder:d(`searchSkills`),className:`quickforge-settings-input`,disabled:T||D})]})}),k?(0,m.jsx)(`div`,{className:`quickforge-settings-alert quickforge-settings-warning-attached`,children:k}):null,(0,m.jsxs)(`div`,{className:`quickforge-settings-toolbar`,children:[(0,m.jsx)(`span`,{className:`quickforge-settings-row-title`,children:d(`availableSkills`)}),(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-info`,children:d(`selectedSkillsCount`,{count:y.size})})]}),(0,m.jsx)(`div`,{className:c?``:`max-h-[46vh] overflow-y-auto`,children:T?(0,m.jsxs)(`div`,{className:`quickforge-settings-empty-row inline-flex items-center gap-2`,children:[(0,m.jsx)(n,{className:`size-4 animate-spin`}),d(`loading`)]}):H.length===0?(0,m.jsx)(`div`,{className:`quickforge-settings-empty-row`,children:d(`noMatchingSkills`)}):H.map(e=>{let t=y.has(e.name);return(0,m.jsxs)(`div`,{className:u(`quickforge-settings-list-item`,t&&`bg-muted/12`),children:[(0,m.jsxs)(`div`,{className:`quickforge-settings-list-item-main`,children:[(0,m.jsx)(`div`,{className:`quickforge-settings-row-title`,children:e.displayName||e.name}),e.description?(0,m.jsx)(`div`,{className:`quickforge-settings-row-description`,children:e.description}):null,(0,m.jsxs)(`div`,{className:`quickforge-settings-meta`,children:[e.source?(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:e.source}):null,e.compatibility?(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:e.compatibility}):null,e.allowedTools?(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:e.allowedTools}):null,e.tags?.slice(0,5).map(e=>(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:e},e))]})]}),(0,m.jsxs)(`div`,{className:`quickforge-settings-list-item-actions`,onClick:e=>e.stopPropagation(),children:[(0,m.jsxs)(`label`,{className:`quickforge-settings-switch`,"aria-disabled":D?`true`:`false`,children:[(0,m.jsx)(`input`,{type:`checkbox`,checked:t,disabled:D,onChange:()=>W(e.name),"aria-label":t?`Disable ${e.name}`:`Enable ${e.name}`}),(0,m.jsx)(`span`,{"aria-hidden":`true`})]}),(0,m.jsx)(`button`,{type:`button`,className:`quickforge-settings-icon-action`,onClick:()=>void U(e.name),disabled:D||I,title:d(`readSkill`),"aria-label":`${d(`readSkill`)}: ${e.displayName||e.name}`,children:(0,m.jsx)(r,{className:`size-4`})})]})]},e.name)})})]}),Y=(0,m.jsxs)(m.Fragment,{children:[(0,m.jsxs)(`div`,{className:`quickforge-settings-toolbar`,children:[(0,m.jsxs)(`button`,{type:`button`,className:`quickforge-settings-button quickforge-settings-button-secondary`,onClick:B,disabled:I,children:[(0,m.jsx)(i,{className:`mr-2 size-4`}),d(`backToSkillList`)]}),(0,m.jsx)(`div`,{className:`quickforge-settings-row-main min-w-0`,children:(0,m.jsx)(`div`,{className:`quickforge-settings-row-title truncate`,children:P?.displayName||P?.name||M})})]}),(0,m.jsx)(`div`,{className:`p-4`,children:I?(0,m.jsxs)(`div`,{className:`quickforge-settings-empty-row inline-flex items-center gap-2`,children:[(0,m.jsx)(n,{className:`size-4 animate-spin`}),d(`loading`)]}):R?(0,m.jsx)(`div`,{className:`quickforge-settings-alert quickforge-settings-warning-attached`,children:R}):P?(0,m.jsxs)(m.Fragment,{children:[P.description?(0,m.jsx)(`div`,{className:`quickforge-settings-row-description mb-3`,children:P.description}):null,(0,m.jsxs)(`div`,{className:`quickforge-settings-meta mb-3`,children:[P.version?(0,m.jsxs)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:[`v`,P.version]}):null,P.source?(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:P.source}):null,P.compatibility?(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:P.compatibility}):null,P.allowedTools?(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:P.allowedTools}):null,P.license?(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:P.license}):null,P.tags?.map(e=>(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:e},e))]}),P.triggers?.length?(0,m.jsxs)(`div`,{className:`quickforge-settings-row-description mb-3`,children:[`Triggers: `,P.triggers.join(`, `)]}):null,P.instructions?(0,m.jsx)(`pre`,{className:`whitespace-pre-wrap break-words rounded-md border border-border bg-muted/30 px-4 py-3 font-mono text-sm leading-6 text-foreground/80`,children:P.instructions}):(0,m.jsx)(`div`,{className:`quickforge-settings-empty-row`,children:d(`noSkillContent`)})]}):null})]});return c?(0,m.jsx)(`div`,{className:`quickforge-settings-stack`,children:(0,m.jsx)(`section`,{className:`quickforge-settings-section`,"aria-label":K,children:M?Y:(0,m.jsxs)(m.Fragment,{children:[C.length?(0,m.jsx)(`div`,{className:`px-5 pt-4`,children:(0,m.jsxs)(`span`,{className:`quickforge-settings-row-description break-all`,children:[d(`skillSearchPaths`),`: `,C.join(` · `)]})}):null,J]})})}):(0,m.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4`,onClick:e=>{e.target===e.currentTarget&&!D&&V()},children:(0,m.jsxs)(`div`,{className:`flex max-h-[85vh] w-full max-w-2xl flex-col rounded-lg border border-border bg-background shadow-quickforge`,children:[(0,m.jsxs)(`div`,{className:`quickforge-settings-toolbar`,children:[(0,m.jsxs)(`div`,{className:`quickforge-settings-row-main`,children:[(0,m.jsxs)(`div`,{className:`quickforge-settings-row-title`,children:[K,(0,m.jsx)(l,{label:q})]}),(0,m.jsx)(`div`,{className:`quickforge-settings-row-description`,children:q}),C.length?(0,m.jsxs)(`div`,{className:`quickforge-settings-row-description break-all`,children:[d(`skillSearchPaths`),`: `,C.join(` · `)]}):null]}),(0,m.jsx)(`button`,{type:`button`,className:`quickforge-settings-icon-action`,onClick:V,disabled:D,"aria-label":d(`close`),children:(0,m.jsx)(s,{className:`size-4`})})]}),(0,m.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto`,children:M?Y:J})]})})}function _({open:e,scope:t,project:n,onOpenChange:r,onSaved:i}){return(0,m.jsx)(g,{active:e,scope:t,project:n,onClose:()=>r(!1),onSaved:i})}export{f as n,_ as t};
1
+ import{i as e,n as t}from"./rolldown-runtime-DWdDZTNf.js";import{Ct as n,Ot as r,R as i,Tt as a,g as o,n as s}from"./icons-DAxUA0e-.js";import{n as c}from"./react-vendor-CZsiwuxm.js";import{mt as l,st as u,ut as d}from"./index-DGQbvw7v.js";var f=t({SkillsDialog:()=>_,SkillsManagerPanel:()=>g}),p=e(r(),1),m=c();async function h(e){let t=await e.json().catch(()=>null);if(!e.ok)throw Error(t?.error||`HTTP ${e.status}`);return t}function g({active:e=!0,scope:t,project:r,embedded:c=!1,onClose:f,onSaved:g}){let[_,v]=(0,p.useState)([]),[y,b]=(0,p.useState)(()=>new Set),[x,S]=(0,p.useState)(``),[C,w]=(0,p.useState)([]),[T,E]=(0,p.useState)(!1),[D,O]=(0,p.useState)(!1),[k,A]=(0,p.useState)(``),j=t===`project`,[M,N]=(0,p.useState)(null),[P,F]=(0,p.useState)(null),[I,L]=(0,p.useState)(!1),[R,z]=(0,p.useState)(``),B=(0,p.useCallback)(()=>{N(null),F(null),z(``)},[]),V=(0,p.useCallback)(()=>{B(),f?.()},[f,B]);(0,p.useEffect)(()=>{if(!e||j&&!r)return;let t=!1;return(async()=>{E(!0),A(``);try{let e=j?`/api/skills?projectId=${encodeURIComponent(r.id)}`:`/api/skills?scope=global`,n=await h(await fetch(e));if(t)return;v(Array.isArray(n.skills)?n.skills:[]),b(new Set(Array.isArray(n.selectedSkills)?n.selectedSkills:[])),w(Array.isArray(n.searchPaths)?n.searchPaths:[])}catch(e){t||A(e instanceof Error?e.message:l(`failedToLoadSkills`))}finally{t||E(!1)}})(),()=>{t=!0}},[e,r,j]),(0,p.useEffect)(()=>{if(!e||c)return;let t=e=>{e.key===`Escape`&&(M?B():D||V())};return document.addEventListener(`keydown`,t),()=>document.removeEventListener(`keydown`,t)},[e,V,c,D,M,B]);let H=(0,p.useMemo)(()=>{let e=x.trim().toLowerCase();return e?_.filter(t=>[t.name,t.displayName,t.description,t.source,t.compatibility,t.allowedTools,...t.tags??[],...t.triggers??[]].filter(Boolean).join(` `).toLowerCase().includes(e)):_},[x,_]),U=async e=>{N(e),F(null),z(``),L(!0);try{let t=new URLSearchParams({name:e});j&&r?(t.set(`scope`,`project`),t.set(`projectId`,r.id)):t.set(`scope`,`global`),F(await h(await fetch(`/api/skills/content?${t}`)))}catch(e){z(e instanceof Error?e.message:l(`failedToReadSkill`))}finally{L(!1)}};if(!e||j&&!r)return null;let W=e=>{if(D)return;let t=new Set(y);t.has(e)?t.delete(e):t.add(e),b(t),G(t)},G=async e=>{O(!0),A(``);try{let n=await h(await fetch(j?`/api/skills/project`:`/api/skills/global`,{method:`PUT`,headers:{"content-type":`application/json`},body:JSON.stringify(j?{projectId:r.id,selectedSkills:[...e]}:{selectedSkills:[...e]})}));g({scope:t,project:j?n.projects?.find(e=>e.id===r.id)??{...r,skills:n.selectedSkills}:void 0,projects:n.projects,selectedSkills:n.selectedSkills})}catch(e){b(y),A(e instanceof Error?e.message:l(`failedToSaveSkills`))}finally{O(!1)}},K=l(j?`projectSkills`:`globalSkills`),q=j?l(`projectSkillsDescription`,{project:r.name}):l(`globalSkillsDescription`),J=(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(`div`,{className:`quickforge-settings-divider p-3`,children:(0,m.jsxs)(`div`,{className:`quickforge-settings-inline-field`,children:[(0,m.jsx)(o,{className:`pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground/60`}),(0,m.jsx)(`input`,{value:x,onChange:e=>S(e.target.value),placeholder:l(`searchSkills`),className:`quickforge-settings-input`,disabled:T||D})]})}),k?(0,m.jsx)(`div`,{className:`quickforge-settings-alert quickforge-settings-warning-attached`,children:k}):null,(0,m.jsxs)(`div`,{className:`quickforge-settings-toolbar`,children:[(0,m.jsx)(`span`,{className:`quickforge-settings-row-title`,children:l(`availableSkills`)}),(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-info`,children:l(`selectedSkillsCount`,{count:y.size})})]}),(0,m.jsx)(`div`,{className:c?``:`max-h-[46vh] overflow-y-auto`,children:T?(0,m.jsxs)(`div`,{className:`quickforge-settings-empty-row inline-flex items-center gap-2`,children:[(0,m.jsx)(i,{className:`size-4 animate-spin`}),l(`loading`)]}):H.length===0?(0,m.jsx)(`div`,{className:`quickforge-settings-empty-row`,children:l(`noMatchingSkills`)}):H.map(e=>{let t=y.has(e.name);return(0,m.jsxs)(`div`,{className:d(`quickforge-settings-list-item`,t&&`bg-muted/12`),children:[(0,m.jsxs)(`div`,{className:`quickforge-settings-list-item-main`,children:[(0,m.jsx)(`div`,{className:`quickforge-settings-row-title`,children:e.displayName||e.name}),e.description?(0,m.jsx)(`div`,{className:`quickforge-settings-row-description`,children:e.description}):null,(0,m.jsxs)(`div`,{className:`quickforge-settings-meta`,children:[e.source?(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:e.source}):null,e.compatibility?(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:e.compatibility}):null,e.allowedTools?(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:e.allowedTools}):null,e.tags?.slice(0,5).map(e=>(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:e},e))]})]}),(0,m.jsxs)(`div`,{className:`quickforge-settings-list-item-actions`,onClick:e=>e.stopPropagation(),children:[(0,m.jsxs)(`label`,{className:`quickforge-settings-switch`,"aria-disabled":D?`true`:`false`,children:[(0,m.jsx)(`input`,{type:`checkbox`,checked:t,disabled:D,onChange:()=>W(e.name),"aria-label":t?`Disable ${e.name}`:`Enable ${e.name}`}),(0,m.jsx)(`span`,{"aria-hidden":`true`})]}),(0,m.jsx)(`button`,{type:`button`,className:`quickforge-settings-icon-action`,onClick:()=>void U(e.name),disabled:D||I,title:l(`readSkill`),"aria-label":`${l(`readSkill`)}: ${e.displayName||e.name}`,children:(0,m.jsx)(n,{className:`size-4`})})]})]},e.name)})})]}),Y=(0,m.jsxs)(m.Fragment,{children:[(0,m.jsxs)(`div`,{className:`quickforge-settings-toolbar`,children:[(0,m.jsxs)(`button`,{type:`button`,className:`quickforge-settings-button quickforge-settings-button-secondary`,onClick:B,disabled:I,children:[(0,m.jsx)(a,{className:`mr-2 size-4`}),l(`backToSkillList`)]}),(0,m.jsx)(`div`,{className:`quickforge-settings-row-main min-w-0`,children:(0,m.jsx)(`div`,{className:`quickforge-settings-row-title truncate`,children:P?.displayName||P?.name||M})})]}),(0,m.jsx)(`div`,{className:`p-4`,children:I?(0,m.jsxs)(`div`,{className:`quickforge-settings-empty-row inline-flex items-center gap-2`,children:[(0,m.jsx)(i,{className:`size-4 animate-spin`}),l(`loading`)]}):R?(0,m.jsx)(`div`,{className:`quickforge-settings-alert quickforge-settings-warning-attached`,children:R}):P?(0,m.jsxs)(m.Fragment,{children:[P.description?(0,m.jsx)(`div`,{className:`quickforge-settings-row-description mb-3`,children:P.description}):null,(0,m.jsxs)(`div`,{className:`quickforge-settings-meta mb-3`,children:[P.version?(0,m.jsxs)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:[`v`,P.version]}):null,P.source?(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:P.source}):null,P.compatibility?(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:P.compatibility}):null,P.allowedTools?(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:P.allowedTools}):null,P.license?(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:P.license}):null,P.tags?.map(e=>(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:e},e))]}),P.triggers?.length?(0,m.jsxs)(`div`,{className:`quickforge-settings-row-description mb-3`,children:[`Triggers: `,P.triggers.join(`, `)]}):null,P.instructions?(0,m.jsx)(`pre`,{className:`whitespace-pre-wrap break-words rounded-md border border-border bg-muted/30 px-4 py-3 font-mono text-sm leading-6 text-foreground/80`,children:P.instructions}):(0,m.jsx)(`div`,{className:`quickforge-settings-empty-row`,children:l(`noSkillContent`)})]}):null})]});return c?(0,m.jsx)(`div`,{className:`quickforge-settings-stack`,children:(0,m.jsx)(`section`,{className:`quickforge-settings-section`,"aria-label":K,children:M?Y:(0,m.jsxs)(m.Fragment,{children:[C.length?(0,m.jsx)(`div`,{className:`px-5 pt-4`,children:(0,m.jsxs)(`span`,{className:`quickforge-settings-row-description break-all`,children:[l(`skillSearchPaths`),`: `,C.join(` · `)]})}):null,J]})})}):(0,m.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4`,onClick:e=>{e.target===e.currentTarget&&!D&&V()},children:(0,m.jsxs)(`div`,{className:`flex max-h-[85vh] w-full max-w-2xl flex-col rounded-lg border border-border bg-background shadow-quickforge`,children:[(0,m.jsxs)(`div`,{className:`quickforge-settings-toolbar`,children:[(0,m.jsxs)(`div`,{className:`quickforge-settings-row-main`,children:[(0,m.jsxs)(`div`,{className:`quickforge-settings-row-title`,children:[K,(0,m.jsx)(u,{label:q})]}),(0,m.jsx)(`div`,{className:`quickforge-settings-row-description`,children:q}),C.length?(0,m.jsxs)(`div`,{className:`quickforge-settings-row-description break-all`,children:[l(`skillSearchPaths`),`: `,C.join(` · `)]}):null]}),(0,m.jsx)(`button`,{type:`button`,className:`quickforge-settings-icon-action`,onClick:V,disabled:D,"aria-label":l(`close`),children:(0,m.jsx)(s,{className:`size-4`})})]}),(0,m.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto`,children:M?Y:J})]})})}function _({open:e,scope:t,project:n,onOpenChange:r,onSaved:i}){return(0,m.jsx)(g,{active:e,scope:t,project:n,onClose:()=>r(!1),onSaved:i})}export{f as n,_ as t};
package/dist/index.html CHANGED
@@ -11,18 +11,18 @@
11
11
  <meta name="apple-mobile-web-app-title" content="QuickForge" />
12
12
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
13
13
  <title>速构 QuickForge</title>
14
- <script type="module" crossorigin src="/assets/index-BFKildY3.js"></script>
14
+ <script type="module" crossorigin src="/assets/index-DGQbvw7v.js"></script>
15
15
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-DWdDZTNf.js">
16
16
  <link rel="modulepreload" crossorigin href="/assets/pi-ai-Cr3rpCXT.js">
17
17
  <link rel="modulepreload" crossorigin href="/assets/lit-vendor-Dr3cpBGF.js">
18
18
  <link rel="modulepreload" crossorigin href="/assets/pi-web-ui-DoRGtREc.js">
19
19
  <link rel="modulepreload" crossorigin href="/assets/css-utils-rkE68RDy.js">
20
- <link rel="modulepreload" crossorigin href="/assets/icons-C7j5jdKo.js">
21
- <link rel="modulepreload" crossorigin href="/assets/react-vendor-VqdnQHHS.js">
20
+ <link rel="modulepreload" crossorigin href="/assets/icons-DAxUA0e-.js">
21
+ <link rel="modulepreload" crossorigin href="/assets/react-vendor-CZsiwuxm.js">
22
22
  <link rel="modulepreload" crossorigin href="/assets/logger-B65Akg8A.js">
23
- <link rel="modulepreload" crossorigin href="/assets/index-BFKildY3.js">
24
- <link rel="modulepreload" crossorigin href="/assets/skills-dialog-DcxeFWSt.js">
25
- <link rel="stylesheet" crossorigin href="/assets/index-CsKSKUn-.css">
23
+ <link rel="modulepreload" crossorigin href="/assets/index-DGQbvw7v.js">
24
+ <link rel="modulepreload" crossorigin href="/assets/skills-dialog-8rn1XU9U.js">
25
+ <link rel="stylesheet" crossorigin href="/assets/index-BZC61KZg.css">
26
26
  </head>
27
27
  <body>
28
28
  <div id="root"></div>
@@ -0,0 +1,8 @@
1
+ The MIT License (MIT)
2
+ Copyright (c) 2025 Material Extensions
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5
+
6
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7
+
8
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shawnstack/quickforge",
3
- "version": "1.6.11",
3
+ "version": "1.6.13",
4
4
  "description": "AI chat application with Agent access modes for local workspace tools. React + Vite + Tailwind CSS frontend, local Node.js storage server.",
5
5
  "keywords": [
6
6
  "ai",
@@ -93,6 +93,8 @@ async function createServerTools(projectId, projectContext, skillsContext, inclu
93
93
  includeMcpTools = true,
94
94
  includePluginTools = true,
95
95
  parentSessionId = null,
96
+ sessionId = null,
97
+ scope = 'global',
96
98
  } = options
97
99
  const allowedTools = allowedToolNames ? new Set(allowedToolNames) : null
98
100
  const isAllowed = (definition) => !allowedTools || allowedTools.has(definition.name)
@@ -107,7 +109,11 @@ async function createServerTools(projectId, projectContext, skillsContext, inclu
107
109
  projectSkillNames: skillsContext.projectSkillNames,
108
110
  workspaceRoot: projectContext?.workspaceRoot,
109
111
  })
110
- const toolContext = { ...projectContext, ...skillToolContext }
112
+ const toolContext = {
113
+ ...projectContext,
114
+ ...skillToolContext,
115
+ ...(sessionId ? { sessionId, scope, projectId } : {}),
116
+ }
111
117
  const tools = skillTools
112
118
  .filter(isAllowed)
113
119
  .map((definition) => wrapToolDefinition(definition, toolContext, toolPermissions))
@@ -150,8 +156,14 @@ async function rebuildSessionTools(session) {
150
156
  includeSubagentTool: false,
151
157
  includeMcpTools: false,
152
158
  parentSessionId: session.sessionId,
159
+ sessionId: session.sessionId,
160
+ scope: session.scope,
153
161
  }
154
- : { parentSessionId: session.sessionId },
162
+ : {
163
+ parentSessionId: session.sessionId,
164
+ sessionId: session.sessionId,
165
+ scope: session.scope,
166
+ },
155
167
  )
156
168
  }
157
169
 
@@ -700,7 +712,8 @@ async function clearSession(session) {
700
712
  session.startedAt = null
701
713
  session.finishedAt = new Date().toISOString()
702
714
  session.title = 'New chat'
703
- session.titleGenerated = false
715
+ session.titleSource = 'default'
716
+ session.titleGenerationId += 1
704
717
  session.agent.state.isStreaming = false
705
718
  session.agent.state.streamingMessage = undefined
706
719
  session.agent.state.errorMessage = undefined
@@ -776,6 +789,15 @@ async function resolveCommandState(session, userMessage, promptCommand = null) {
776
789
  if (internalResponse?.plan) {
777
790
  return planCommandState(userMessage, internalResponse.args)
778
791
  }
792
+ if (internalResponse?.init) {
793
+ if (!session.projectId) return { textResponse: 'Initialization requires an active project chat.' }
794
+ return {
795
+ userMessage,
796
+ commandPrompt: formatInitCommandPrompt(),
797
+ permissions: { allowEdit: true, allowCommands: true, allowSubagents: true },
798
+ commandName: 'init',
799
+ }
800
+ }
779
801
  if (internalResponse?.review) {
780
802
  return {
781
803
  userMessage,
@@ -817,6 +839,53 @@ async function resolveCommandState(session, userMessage, promptCommand = null) {
817
839
  }
818
840
  }
819
841
 
842
+ function formatInitCommandPrompt() {
843
+ return `<init_command_invocation name="init">
844
+ This /init command applies only to the current user request. Work in the current repository root. Inspect the repository as needed, then create or update the root-level \`AGENTS.md\`. If the file already exists, read it first and preserve useful repository-specific guidance while bringing it in line with the requirements below. Do not modify unrelated files.
845
+
846
+ Generate a file named AGENTS.md that serves as a contributor guide for this repository.
847
+ Your goal is to produce a clear, concise, and well-structured document with descriptive headings and actionable explanations for each section.
848
+ Follow the outline below, but adapt as needed — add sections if relevant, and omit those that do not apply to this project.
849
+
850
+ Document Requirements
851
+
852
+ - Title the document "Repository Guidelines".
853
+ - Use Markdown headings (#, ##, etc.) for structure.
854
+ - Keep the document concise. 200-400 words is optimal.
855
+ - Keep explanations short, direct, and specific to this repository.
856
+ - Provide examples where helpful (commands, directory paths, naming patterns).
857
+ - Maintain a professional, instructional tone.
858
+
859
+ Recommended Sections
860
+
861
+ Project Structure & Module Organization
862
+
863
+ - Outline the project structure, including where the source code, tests, and assets are located.
864
+
865
+ Build, Test, and Development Commands
866
+
867
+ - List key commands for building, testing, and running locally (e.g., npm test, make build).
868
+ - Briefly explain what each command does.
869
+
870
+ Coding Style & Naming Conventions
871
+
872
+ - Specify indentation rules, language-specific style preferences, and naming patterns.
873
+ - Include any formatting or linting tools used.
874
+
875
+ Testing Guidelines
876
+
877
+ - Identify testing frameworks and coverage requirements.
878
+ - State test naming conventions and how to run tests.
879
+
880
+ Commit & Pull Request Guidelines
881
+
882
+ - Summarize commit message conventions found in the project’s Git history.
883
+ - Outline pull request requirements (descriptions, linked issues, screenshots, etc.).
884
+
885
+ (Optional) Add other sections if relevant, such as Security & Configuration Tips, Architecture Overview, or Agent-Specific Instructions.
886
+ </init_command_invocation>`
887
+ }
888
+
820
889
  function formatPlanCommandPrompt(task) {
821
890
  const taskText = String(task || '').trim()
822
891
  return `<plan_command_invocation name="plan">
@@ -1372,6 +1441,7 @@ export async function createAgent(sessionId, config = {}) {
1372
1441
  messages = [],
1373
1442
  systemPrompt = null,
1374
1443
  title = 'New chat',
1444
+ titleSource = title === 'New chat' ? 'default' : 'manual',
1375
1445
  createdAt = new Date().toISOString(),
1376
1446
  lastModified = null,
1377
1447
  contextCompaction = null,
@@ -1450,8 +1520,14 @@ export async function createAgent(sessionId, config = {}) {
1450
1520
  includeSubagentTool: false,
1451
1521
  includeMcpTools: false,
1452
1522
  parentSessionId: sessionId,
1523
+ sessionId,
1524
+ scope,
1453
1525
  }
1454
- : { parentSessionId: sessionId },
1526
+ : {
1527
+ parentSessionId: sessionId,
1528
+ sessionId,
1529
+ scope,
1530
+ },
1455
1531
  )
1456
1532
 
1457
1533
  // Resolve API key
@@ -1531,6 +1607,7 @@ export async function createAgent(sessionId, config = {}) {
1531
1607
  thinkingLevel: resolvedThinkingLevel,
1532
1608
  scope,
1533
1609
  title,
1610
+ titleSource,
1534
1611
  createdAt,
1535
1612
  lastModified,
1536
1613
  globalSkillNames: skillsContext.globalSkillNames,
@@ -1544,7 +1621,10 @@ export async function createAgent(sessionId, config = {}) {
1544
1621
  eventBus,
1545
1622
  idleTimer: null,
1546
1623
  persistTimer: null,
1547
- titleGenerated: false,
1624
+ titleGenerationId: 0,
1625
+ titleGenerationPromise: null,
1626
+ titleGenerationPromiseId: null,
1627
+ sessionCreatedEmitted: messages.length > 0,
1548
1628
  toolTimings: new Map(),
1549
1629
  getApiKey,
1550
1630
  contextCompaction,
@@ -1623,11 +1703,17 @@ export async function createAgent(sessionId, config = {}) {
1623
1703
  const isInitialUserMessage = (event.message?.role === 'user' || event.message?.role === 'user-with-attachments')
1624
1704
  && session.agent.state.messages.length === 1
1625
1705
  if (isInitialUserMessage) {
1626
- // External ACP channels run in a separate process from the web UI. Persist
1627
- // the first user message immediately so the session becomes visible on
1628
- // disk before a long/failed agent run can exit or be restarted.
1706
+ // Persist the first user message before announcing the session or
1707
+ // starting the asynchronous AI title request.
1629
1708
  try {
1630
- await flushSessionPersist(session)
1709
+ const metadata = await flushSessionPersist(session)
1710
+ if (metadata) {
1711
+ if (!session.sessionCreatedEmitted) {
1712
+ session.sessionCreatedEmitted = true
1713
+ emitSessionEvent(session, { type: 'session_created', metadata })
1714
+ }
1715
+ scheduleSessionTitleGeneration(session, event.message)
1716
+ }
1631
1717
  } catch (err) {
1632
1718
  logger.error(`Failed to persist initial user message for session ${sessionId}:`, err, { sessionId })
1633
1719
  }
@@ -1673,7 +1759,7 @@ function sessionLastModifiedFromMessages(messages, fallback) {
1673
1759
  * Persist session data to storage.
1674
1760
  */
1675
1761
  async function persistSession(session) {
1676
- const { sessionId, agent, scope, projectId, title, createdAt, lastModified: storedLastModified, status, startedAt, finishedAt, model, thinkingLevel, accessMode, yoloMode, contextCompaction } = session
1762
+ const { sessionId, agent, scope, projectId, title, titleSource, createdAt, lastModified: storedLastModified, status, startedAt, finishedAt, model, thinkingLevel, accessMode, yoloMode, contextCompaction } = session
1677
1763
  const messages = agent.state.messages
1678
1764
 
1679
1765
  if (messages.length === 0) {
@@ -1694,6 +1780,7 @@ async function persistSession(session) {
1694
1780
  const sessionData = {
1695
1781
  id: sessionId,
1696
1782
  title,
1783
+ titleSource,
1697
1784
  model,
1698
1785
  thinkingLevel,
1699
1786
  accessMode,
@@ -1744,6 +1831,7 @@ async function persistSession(session) {
1744
1831
  const metadata = {
1745
1832
  id: sessionId,
1746
1833
  title,
1834
+ titleSource,
1747
1835
  createdAt: createdAt || now,
1748
1836
  lastModified,
1749
1837
  messageCount: messages.length,
@@ -1788,7 +1876,10 @@ async function persistSession(session) {
1788
1876
  }
1789
1877
  } catch (err) {
1790
1878
  logger.error(`Failed to persist session ${sessionId}:`, err, { sessionId })
1879
+ return null
1791
1880
  }
1881
+
1882
+ return metadata
1792
1883
  }
1793
1884
 
1794
1885
  export async function persistSessionState(session) {
@@ -1830,7 +1921,7 @@ async function flushSessionPersist(session) {
1830
1921
  clearTimeout(session.persistTimer)
1831
1922
  session.persistTimer = null
1832
1923
  }
1833
- await persistSession(session)
1924
+ return persistSession(session)
1834
1925
  }
1835
1926
 
1836
1927
  export function rollbackStartIndexFromMessage(messages, messageIndex) {
@@ -1888,6 +1979,39 @@ export async function rollbackSessionMessages(sessionId, rollbackMessageIndex) {
1888
1979
  return { session: getSessionState(sessionId), rollbackIndex }
1889
1980
  }
1890
1981
 
1982
+ export function canApplyGeneratedTitle(session, generationId, expectedTitle) {
1983
+ return session.titleGenerationId === generationId
1984
+ && session.titleSource === 'fallback'
1985
+ && session.title === expectedTitle
1986
+ }
1987
+
1988
+ function scheduleSessionTitleGeneration(session, userMessage) {
1989
+ if (session.titleSource !== 'fallback') return
1990
+ if (session.titleGenerationPromise && session.titleGenerationPromiseId === session.titleGenerationId) return
1991
+ const generationId = ++session.titleGenerationId
1992
+ const expectedTitle = session.title
1993
+ const promise = generateAiTitle([userMessage], session.model, session.thinkingLevel, session.getApiKey)
1994
+ .then(async (aiTitle) => {
1995
+ if (!aiTitle || aiTitle === 'New chat') return
1996
+ if (!canApplyGeneratedTitle(session, generationId, expectedTitle)) return
1997
+ session.title = aiTitle
1998
+ session.titleSource = 'ai'
1999
+ await persistSession(session)
2000
+ emitSessionEvent(session, { type: 'title_updated', title: aiTitle, titleSource: 'ai' })
2001
+ })
2002
+ .catch((err) => {
2003
+ logger.warn(`Title generation failed for session ${session.sessionId}:`, err.message || err, { sessionId: session.sessionId })
2004
+ })
2005
+ .finally(() => {
2006
+ if (session.titleGenerationPromise === promise) {
2007
+ session.titleGenerationPromise = null
2008
+ session.titleGenerationPromiseId = null
2009
+ }
2010
+ })
2011
+ session.titleGenerationPromise = promise
2012
+ session.titleGenerationPromiseId = generationId
2013
+ }
2014
+
1891
2015
  /**
1892
2016
  * Send a user message to the agent and start the agent loop.
1893
2017
  * Returns immediately; events are streamed via the event bus.
@@ -1940,24 +2064,14 @@ export async function runPrompt(sessionId, message, selectedCapabilities = [], p
1940
2064
  return compactSession(session, initialUserMessage, commandState.compact)
1941
2065
  }
1942
2066
 
1943
- // AI title generation on first user message (fire-and-forget, before agent runs)
1944
- if (!session.titleGenerated && session.title === 'New chat') {
1945
- // Set a simple fallback title immediately so the sidebar shows something
1946
- // meaningful even if AI title generation fails or is slow.
2067
+ // Set a meaningful fallback immediately. The AI title request starts only
2068
+ // after the first user message has been persisted by the message_end handler.
2069
+ if (session.titleSource === 'default' && session.title === 'New chat') {
1947
2070
  const simpleTitle = generateTitle([userMessage])
2071
+ session.titleSource = 'fallback'
1948
2072
  if (simpleTitle !== 'New chat') {
1949
2073
  session.title = simpleTitle
1950
2074
  }
1951
- session.titleGenerated = true
1952
- generateAiTitle([userMessage], session.model, session.thinkingLevel, session.getApiKey).then(async (aiTitle) => {
1953
- if (aiTitle && aiTitle !== 'New chat') {
1954
- session.title = aiTitle
1955
- await persistSession(session)
1956
- emitSessionEvent(session, { type: 'title_updated', title: aiTitle })
1957
- }
1958
- }).catch((err) => {
1959
- logger.warn(`Title generation failed for session ${sessionId}:`, err.message || err, { sessionId })
1960
- })
1961
2075
  }
1962
2076
 
1963
2077
  session.activeCommandName = commandState.commandName ?? null
@@ -2142,6 +2256,7 @@ export function getSessionState(sessionId) {
2142
2256
  model: session.model,
2143
2257
  thinkingLevel: session.thinkingLevel,
2144
2258
  title: session.title,
2259
+ titleSource: session.titleSource,
2145
2260
  createdAt: session.createdAt,
2146
2261
  lastModified: session.lastModified,
2147
2262
  stateVersion: session.stateVersion || 0,
@@ -2289,6 +2404,7 @@ export async function restoreAgent(sessionId) {
2289
2404
  thinkingLevel: sessionData.thinkingLevel || 'off',
2290
2405
  messages: sessionData.messages || [],
2291
2406
  title: sessionData.title || 'New chat',
2407
+ titleSource: sessionData.titleSource || (sessionData.title && sessionData.title !== 'New chat' ? 'ai' : 'default'),
2292
2408
  createdAt: sessionData.createdAt,
2293
2409
  lastModified: sessionData.lastModified,
2294
2410
  contextCompaction: sessionData.contextCompaction || null,
@@ -2387,6 +2503,28 @@ export async function refreshAllSessionTools() {
2387
2503
  return result
2388
2504
  }
2389
2505
 
2506
+ export async function updateSessionTitle(sessionId, title) {
2507
+ let session = agentSessions.get(sessionId)
2508
+ if (!session) session = await restoreAgent(sessionId)
2509
+ if (!session) {
2510
+ throw Object.assign(new Error('Session not found'), { statusCode: 404 })
2511
+ }
2512
+ const normalizedTitle = typeof title === 'string' ? title.trim() : ''
2513
+ if (!normalizedTitle) {
2514
+ throw Object.assign(new Error('Title must not be empty'), { statusCode: 400 })
2515
+ }
2516
+ if (normalizedTitle.length > 200) {
2517
+ throw Object.assign(new Error('Title is too long'), { statusCode: 400 })
2518
+ }
2519
+
2520
+ session.titleGenerationId += 1
2521
+ session.title = normalizedTitle
2522
+ session.titleSource = 'manual'
2523
+ await persistSession(session)
2524
+ emitSessionEvent(session, { type: 'title_updated', title: normalizedTitle, titleSource: 'manual' })
2525
+ return { sessionId, title: normalizedTitle, titleSource: 'manual' }
2526
+ }
2527
+
2390
2528
  export async function updateSessionAccessMode(sessionId, accessMode) {
2391
2529
  const session = agentSessions.get(sessionId)
2392
2530
  if (!session) {
@@ -15,6 +15,12 @@ const commandNamePattern = /^(?!.*--)[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/
15
15
  * `description` values here.
16
16
  */
17
17
  const builtinCommandCatalog = [
18
+ {
19
+ name: 'init',
20
+ description: 'Generate or update a concise AGENTS.md contributor guide for the current repository.',
21
+ argumentHint: '',
22
+ permissionNote: 'may edit files and run commands',
23
+ },
18
24
  {
19
25
  name: 'plan',
20
26
  description: 'Create a plan first; this turn cannot edit files or run commands.',
@@ -367,6 +373,8 @@ export function parseInternalCommandInvocation(message) {
367
373
  const text = textFromUserMessage(message).trim()
368
374
  if (/^\/(?:help|\?)(?:\s+.*)?$/i.test(text)) return { type: 'help' }
369
375
  if (/^\/commands(?:\s+.*)?$/i.test(text)) return { type: 'list' }
376
+ if (/^\/init\s*$/i.test(text)) return { type: 'init' }
377
+ if (/^\/init(?:\s+[\s\S]+)$/i.test(text)) return { type: 'invalid-init-args' }
370
378
  if (/^\/clear\s*$/i.test(text)) return { type: 'clear' }
371
379
  if (/^\/clear(?:\s+[\s\S]+)$/i.test(text)) return { type: 'invalid-clear-args' }
372
380
 
@@ -407,6 +415,15 @@ export async function handleInternalCommand(invocation, workspaceRoot, commandDi
407
415
  return { plan: true, args: invocation.args }
408
416
  }
409
417
 
418
+ if (invocation.type === 'init') {
419
+ if (!workspaceRoot) return 'Initialization requires an active project chat.'
420
+ return { init: true }
421
+ }
422
+
423
+ if (invocation.type === 'invalid-init-args') {
424
+ return 'Usage: /init'
425
+ }
426
+
410
427
  if (invocation.type === 'review') {
411
428
  if (!workspaceRoot) return 'Review requires an active project chat.'
412
429
  return { review: true, args: invocation.args || '' }