@shawnstack/quickforge 1.7.0 → 1.7.2

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 (37) hide show
  1. package/dist/assets/AgentProfilesPage-BFgyFa5e.js +1 -0
  2. package/dist/assets/ChatPanelHost-Cld9HcVz.js +288 -0
  3. package/dist/assets/{PluginsPage-B8bHMwfv.js → PluginsPage-DEMqwhOA.js} +1 -1
  4. package/dist/assets/ScheduledTasksPage-DTP_gedp.js +2 -0
  5. package/dist/assets/{SettingsWorkspacePage-BOP9CtoI.js → SettingsWorkspacePage-Dr9zT5Bs.js} +112 -112
  6. package/dist/assets/SharedConversationPage-op3DRwcw.js +1 -0
  7. package/dist/assets/TerminalDock-BL_UovwU.js +2 -0
  8. package/dist/assets/WorkspaceInspector-73dhAime.js +13 -0
  9. package/dist/assets/icons-BP8YOS-Z.js +1 -0
  10. package/dist/assets/index-Cu2bBHLv.css +3 -0
  11. package/dist/assets/index-yV1wtqTr.js +66 -0
  12. package/dist/assets/mcp-servers-dialog-Bp6kbIup.js +5 -0
  13. package/dist/assets/{monaco-C13M09wD.js → monaco-BTsVCDWS.js} +1 -1
  14. package/dist/assets/{react-vendor-2RKYr-A4.js → react-vendor-Dr5xvL-e.js} +1 -1
  15. package/dist/assets/{skills-dialog-MpoxntiV.js → skills-dialog-DiJAUfvW.js} +1 -1
  16. package/dist/index.html +6 -6
  17. package/package.json +1 -1
  18. package/server/acp/server.mjs +19 -7
  19. package/server/mcp/registry.mjs +54 -14
  20. package/server/plugins/loader.mjs +9 -1
  21. package/server/plugins/registry.mjs +32 -10
  22. package/server/routes/backup.mjs +79 -72
  23. package/server/routes/mcp.mjs +0 -5
  24. package/server/routes/scheduled-tasks.mjs +72 -32
  25. package/server/routes/workspace.mjs +171 -49
  26. package/server/utils/scheduled-tasks.mjs +23 -10
  27. package/server/utils/workspace.mjs +25 -3
  28. package/dist/assets/AgentProfilesPage-DQ8URegq.js +0 -1
  29. package/dist/assets/ChatPanelHost-vi1tDqlJ.js +0 -291
  30. package/dist/assets/ScheduledTasksPage-AaUz5el2.js +0 -2
  31. package/dist/assets/SharedConversationPage-9A4L9UcQ.js +0 -1
  32. package/dist/assets/TerminalDock-DQOXpaDe.js +0 -2
  33. package/dist/assets/WorkspaceInspector-DaM7TJHb.js +0 -13
  34. package/dist/assets/icons-ko_i0WpN.js +0 -1
  35. package/dist/assets/index-B2eauKpo.css +0 -3
  36. package/dist/assets/index-B8Awq5FV.js +0 -63
  37. package/dist/assets/mcp-servers-dialog-XE4K8PCO.js +0 -5
@@ -0,0 +1,5 @@
1
+ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{B as t,E as n,Pt as r,S as i,a,h as o,jt as s,tt as c,v as l}from"./icons-BP8YOS-Z.js";import{n as u}from"./react-vendor-Dr5xvL-e.js";import{V as d,b as f,ft as p,ht as m,mt as h,yt as g}from"./index-yV1wtqTr.js";var _=e(r(),1),v=u();function y(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 b=12;function x({server:e,toggling:r,reconnecting:i,onToggle:o,onEdit:s,onDelete:c,onReconnect:u}){let d=e.tools?.slice(0,b)??[],f=e.toolCount??e.tools?.length??0,p=Math.max(0,f-d.length),_=e.enabled&&e.status!==`connected`;return(0,v.jsxs)(`div`,{className:`rounded-lg border border-border p-3`,children:[(0,v.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,v.jsxs)(`div`,{className:`min-w-0`,children:[(0,v.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,v.jsx)(`div`,{className:`truncate text-sm font-medium text-foreground/90`,children:e.name}),(0,v.jsx)(`span`,{className:m(`rounded-full px-2 py-0.5 text-[11px]`,y(e.status)),children:e.status||`unknown`}),(0,v.jsx)(`span`,{className:`text-[11px] text-muted-foreground/60`,children:g(`mcpToolsCount`,{count:f})})]}),(0,v.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,v.jsx)(`div`,{className:`mt-1 text-xs text-destructive`,children:e.error}):null]}),(0,v.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1`,children:[(0,v.jsx)(`button`,{type:`button`,role:`switch`,"aria-checked":e.enabled,disabled:r,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:()=>o(e),title:e.enabled?g(`pauseTask`):g(`enable`),children:(0,v.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,v.jsx)(h,{type:`button`,variant:`ghost`,size:`icon`,className:`size-8 text-muted-foreground`,onClick:()=>u(e.name),disabled:i,"aria-label":g(`mcpReconnectServer`),title:g(`mcpReconnectServer`),children:i?(0,v.jsx)(t,{className:`size-4 animate-spin`}):(0,v.jsx)(l,{className:`size-4`})}):null,(0,v.jsx)(h,{type:`button`,variant:`ghost`,size:`icon`,className:`size-8 text-muted-foreground`,onClick:()=>s(e),"aria-label":g(`editTask`),title:g(`editTask`),children:(0,v.jsx)(n,{className:`size-4`})}),(0,v.jsx)(h,{type:`button`,variant:`ghost`,size:`icon`,className:`size-8 text-destructive`,onClick:()=>c(e.name),"aria-label":g(`delete`),title:g(`delete`),children:(0,v.jsx)(a,{className:`size-4`})})]})]}),d.length>0?(0,v.jsxs)(`div`,{className:`mt-2 flex flex-wrap gap-1.5`,children:[d.map(e=>(0,v.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,v.jsx)(`span`,{className:`rounded-md px-1.5 py-0.5 text-[11px] text-muted-foreground/55`,children:g(`mcpMoreTools`,{count:p})}):null]}):null]})}function S(){return{name:``,transport:`stdio`,command:``,args:[],url:``,cwd:``,env:{}}}function C(e){return{name:e.name,transport:e.transport,command:e.command,args:e.args||[],url:e.url||``,cwd:e.cwd||``,env:e.env||{}}}function w(e){return(e||[]).join(`
2
+ `)}function T(e){return Object.entries(e||{}).map(([e,t])=>`${e}=${t}`).join(`
3
+ `)}function E(e){return e.split(`
4
+ `).map(e=>e.trim()).filter(Boolean)}function D(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 O(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 k(e){return!!(e&&typeof e==`object`&&!Array.isArray(e))}function A(e){let t;try{t=JSON.parse(e)}catch{throw Error(g(`mcpInvalidJson`))}if(!k(t))throw Error(g(`mcpInvalidConfigJson`));let n=``,r=null;if(k(t.mcpServers)){let e=Object.entries(t.mcpServers);if(e.length===0)throw Error(g(`mcpEmptyConfigJson`));let[i,a]=e[0];n=i,k(a)&&(r=a)}else r=t;if(!r)throw Error(g(`mcpInvalidConfigJson`));let i=String(r.transport||r.type||`stdio`);if(![`stdio`,`http`,`sse`].includes(i))throw Error(g(`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:k(a)?a:{}}}var j=`mb-1 block text-xs text-muted-foreground/72`,M=`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`,N=`flex h-9 w-full rounded-md border border-input bg-transparent px-3 text-sm outline-none focus:border-ring`;function P({value:e,onChange:t,isEdit:n,disabled:r}){let i=e.transport===`stdio`,a=n=>t({...e,...n});return(0,v.jsxs)(`div`,{className:`space-y-3 p-3`,children:[(0,v.jsx)(`div`,{className:`text-xs text-muted-foreground/60`,children:g(n?`mcpEditServer`:`mcpAddServer`)}),(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`label`,{className:j,htmlFor:`mcp-server-name`,children:g(`mcpServerName`)}),(0,v.jsx)(f,{id:`mcp-server-name`,value:e.name,onChange:e=>a({name:e.target.value}),placeholder:g(`mcpNamePlaceholder`),disabled:n||r})]}),(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`label`,{className:j,htmlFor:`mcp-server-transport`,children:g(`mcpTransport`)}),(0,v.jsxs)(`select`,{id:`mcp-server-transport`,className:N,value:e.transport,onChange:e=>a({transport:e.target.value}),disabled:r,children:[(0,v.jsx)(`option`,{value:`stdio`,children:`stdio`}),(0,v.jsx)(`option`,{value:`http`,children:`http`}),(0,v.jsx)(`option`,{value:`sse`,children:`sse`})]})]}),i?(0,v.jsxs)(v.Fragment,{children:[(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`label`,{className:j,htmlFor:`mcp-server-command`,children:g(`mcpCommand`)}),(0,v.jsx)(f,{id:`mcp-server-command`,value:e.command,onChange:e=>a({command:e.target.value}),placeholder:g(`mcpCommandPlaceholder`),disabled:r})]}),(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`label`,{className:j,htmlFor:`mcp-server-args`,children:g(`mcpArgs`)}),(0,v.jsx)(`textarea`,{id:`mcp-server-args`,className:M,value:w(e.args),onChange:e=>a({args:E(e.target.value)}),spellCheck:!1,disabled:r})]}),(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`label`,{className:j,htmlFor:`mcp-server-cwd`,children:g(`mcpCwd`)}),(0,v.jsx)(f,{id:`mcp-server-cwd`,value:e.cwd,onChange:e=>a({cwd:e.target.value}),disabled:r})]}),(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`label`,{className:j,htmlFor:`mcp-server-env`,children:g(`mcpEnv`)}),(0,v.jsx)(`textarea`,{id:`mcp-server-env`,className:M,value:T(e.env),onChange:e=>a({env:D(e.target.value)}),spellCheck:!1,disabled:r})]})]}):(0,v.jsxs)(v.Fragment,{children:[(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`label`,{className:j,htmlFor:`mcp-server-url`,children:g(`mcpUrl`)}),(0,v.jsx)(f,{id:`mcp-server-url`,value:e.url,onChange:e=>a({url:e.target.value}),placeholder:g(`mcpUrlPlaceholder`),disabled:r})]}),(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`label`,{className:j,htmlFor:`mcp-server-headers`,children:g(`mcpHeaders`)}),(0,v.jsx)(`textarea`,{id:`mcp-server-headers`,className:M,value:T(e.env),onChange:e=>a({env:D(e.target.value)}),spellCheck:!1,disabled:r})]})]})]})}async function F(e){let t=await e.json().catch(()=>null);if(!e.ok)throw Error(t?.error||`HTTP ${e.status}`);return t}function I({active:e=!0,className:n}){let[r,a]=(0,_.useState)([]),[l,u]=(0,_.useState)(!1),[f,y]=(0,_.useState)(!1),[b,w]=(0,_.useState)(new Set),[T,E]=(0,_.useState)(null),[D,k]=(0,_.useState)(``),[j,M]=(0,_.useState)(!1),[N,I]=(0,_.useState)(null),[L,R]=(0,_.useState)(S),[z,B]=(0,_.useState)(`form`),[V,H]=(0,_.useState)(``),[U,W]=(0,_.useState)(``),G=(0,_.useCallback)(e=>{a(e?.servers??[])},[]),K=(0,_.useCallback)(async()=>{u(!0),k(``);try{G(await F(await fetch(`/api/mcp/servers`)))}catch(e){k(e instanceof Error?e.message:g(`mcpLoadFailed`))}finally{u(!1)}},[G]);if((0,_.useEffect)(()=>{if(!e)return;let t=window.setTimeout(()=>{K()},0);return()=>window.clearTimeout(t)},[e,K]),!e)return null;let q=e=>{e===`json`&&(H(O(L)),W(``)),B(e)},J=()=>{I(null),R(S()),B(`form`),M(!0),k(``)},Y=e=>{let t=C(e);I(e),R(t),H(O(t)),W(``),B(`form`),M(!0),k(``)},X=()=>{M(!1),I(null),H(``),W(``),k(``)},Z=e=>{R(e)},Q=e=>{H(e);try{let t=A(e);R(e=>({...t,name:t.name||e.name})),W(``)}catch(e){W(e instanceof Error?e.message:g(`mcpInvalidJson`))}},ee=async()=>{if(!f){if(U&&z===`json`){k(U);return}y(!0),k(``);try{G(await F(await fetch(`/api/mcp/servers`,{method:`PUT`,headers:{"content-type":`application/json`},body:JSON.stringify({server:{...L,enabled:N?.enabled??!0}})}))),X()}catch(e){k(e instanceof Error?e.message:g(`mcpSaveFailed`))}finally{y(!1)}}},te=async e=>{if(await d({description:g(`mcpDeleteConfirm`,{name:e}),confirmLabel:g(`confirmDelete`),cancelLabel:g(`cancel`),variant:`destructive`})){k(``);try{G(await F(await fetch(`/api/mcp/servers/${encodeURIComponent(e)}`,{method:`DELETE`})))}catch(e){k(e instanceof Error?e.message:g(`mcpDeleteFailed`))}}},ne=async e=>{if(!b.has(e.name)){w(t=>new Set(t).add(e.name)),k(``);try{G(await F(await fetch(`/api/mcp/servers/${encodeURIComponent(e.name)}/enabled`,{method:`PUT`,headers:{"content-type":`application/json`},body:JSON.stringify({enabled:!e.enabled})})))}catch(e){k(e instanceof Error?e.message:g(`mcpSaveFailed`))}finally{w(t=>{let n=new Set(t);return n.delete(e.name),n})}}},re=async e=>{if(!T){E(e),k(``);try{G(await F(await fetch(`/api/mcp/reconnect/${encodeURIComponent(e)}`,{method:`POST`})))}catch(e){k(e instanceof Error?e.message:g(`mcpReconnectFailed`))}finally{E(null)}}},$=!!N,ie=!!L.name.trim()&&!!(L.transport===`stdio`?L.command.trim():L.url.trim());return j?(0,v.jsxs)(`div`,{className:m(`flex min-h-0 flex-1 flex-col overflow-hidden bg-background`,n),children:[(0,v.jsx)(`div`,{className:`border-b border-border px-6 py-5`,children:(0,v.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,v.jsxs)(`button`,{type:`button`,className:`inline-flex items-center gap-1.5 text-sm text-muted-foreground hover:text-foreground`,onClick:X,children:[(0,v.jsx)(s,{className:`size-4`}),g(`mcpConfiguredServers`)]}),(0,v.jsx)(`span`,{className:`text-sm font-medium text-foreground/90`,children:g($?`mcpEditServer`:`mcpAddServer`)})]})}),D?(0,v.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:D}):null,(0,v.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto p-6`,children:(0,v.jsxs)(`div`,{className:`mx-auto max-w-5xl space-y-5`,children:[(0,v.jsxs)(`div`,{className:`flex border-b border-border`,children:[(0,v.jsxs)(`button`,{type:`button`,onClick:()=>q(`form`),className:m(`flex flex-1 items-center justify-center gap-1.5 px-3 py-2.5 text-xs font-medium transition-colors`,z===`form`?`border-b-2 border-primary text-foreground/90 -mb-px`:`text-muted-foreground/60 hover:text-foreground/85`),children:[(0,v.jsx)(o,{className:`size-3.5`}),g(`mcpTabServer`)]}),(0,v.jsxs)(`button`,{type:`button`,onClick:()=>q(`json`),className:m(`flex flex-1 items-center justify-center gap-1.5 px-3 py-2.5 text-xs font-medium transition-colors`,z===`json`?`border-b-2 border-primary text-foreground/90 -mb-px`:`text-muted-foreground/60 hover:text-foreground/85`),children:[(0,v.jsx)(c,{className:`size-3.5`}),g(`mcpTabJson`)]})]}),(0,v.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto`,children:z===`form`?(0,v.jsx)(P,{value:L,onChange:Z,isEdit:$,disabled:f}):(0,v.jsxs)(`div`,{className:`space-y-2`,children:[(0,v.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:V,onChange:e=>Q(e.target.value),spellCheck:!1}),U?(0,v.jsx)(`div`,{className:`rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive`,children:U}):null,(0,v.jsxs)(`div`,{className:`inline-flex items-center gap-1.5 text-[11px] font-medium text-foreground/90`,children:[g(`mcpTabJson`),(0,v.jsx)(p,{label:g(`mcpImportConfigDescription`)})]})]})}),(0,v.jsxs)(`div`,{className:`flex justify-end gap-2 border-t border-border pt-3`,children:[(0,v.jsx)(h,{type:`button`,variant:`outline`,size:`sm`,onClick:X,disabled:f,children:g(`cancel`)}),(0,v.jsxs)(h,{type:`button`,size:`sm`,onClick:()=>{ee()},disabled:f||!ie,children:[f?(0,v.jsx)(t,{className:`mr-1.5 size-3.5 animate-spin`}):null,g(`save`)]})]})]})})]}):(0,v.jsxs)(`div`,{className:m(`flex min-h-0 flex-1 flex-col overflow-hidden bg-background`,n),children:[(0,v.jsx)(`div`,{className:`border-b border-border px-6 py-5`,children:(0,v.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,v.jsx)(`h3`,{className:`text-sm font-medium text-foreground/90`,children:g(`mcpConfiguredServers`)}),(0,v.jsxs)(h,{type:`button`,variant:`ghost`,size:`sm`,onClick:J,children:[(0,v.jsx)(i,{className:`mr-1.5 size-3.5`}),g(`mcpAddServer`)]})]})}),D?(0,v.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:D}):null,(0,v.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto p-6`,children:(0,v.jsx)(`div`,{className:`mx-auto max-w-5xl space-y-5`,children:l&&r.length===0?(0,v.jsxs)(`div`,{className:`flex items-center justify-center gap-2 rounded-lg border border-border py-8 text-sm text-muted-foreground`,children:[(0,v.jsx)(t,{className:`size-4 animate-spin`}),g(`loading`)]}):r.length===0?(0,v.jsx)(`div`,{className:`rounded-lg border border-border bg-muted/15 p-4 text-sm text-muted-foreground/72`,children:g(`mcpNoServersDescription`)}):r.map(e=>(0,v.jsx)(x,{server:e,toggling:b.has(e.name),reconnecting:T===e.name,onToggle:e=>{ne(e)},onEdit:Y,onDelete:e=>{te(e)},onReconnect:e=>{re(e)}},e.name))})})]})}export{I as McpServersPanel};
@@ -1,4 +1,4 @@
1
- import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{Ot as t}from"./icons-ko_i0WpN.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{Pt as t}from"./icons-BP8YOS-Z.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{Ot as t}from"./icons-ko_i0WpN.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{Pt as t}from"./icons-BP8YOS-Z.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{Ct as n,L as r,Ot as i,Tt as a,g as o,n as s}from"./icons-ko_i0WpN.js";import{n as c}from"./react-vendor-2RKYr-A4.js";import{mt as l,st as u,ut as d}from"./index-B8Awq5FV.js";var f=t({SkillsDialog:()=>_,SkillsManagerPanel:()=>g}),p=e(i(),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:i,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&&!i)return;let t=!1;return(async()=>{E(!0),A(``);try{let e=j?`/api/skills?projectId=${encodeURIComponent(i.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,i,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&&i?(t.set(`scope`,`project`),t.set(`projectId`,i.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&&!i)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:i.id,selectedSkills:[...e]}:{selectedSkills:[...e]})}));g({scope:t,project:j?n.projects?.find(e=>e.id===i.id)??{...i,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:i.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)(r,{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)(r,{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};
1
+ import{i as e,n as t}from"./rolldown-runtime-DWdDZTNf.js";import{B as n,Ot as r,Pt as i,_ as a,jt as o,n as s}from"./icons-BP8YOS-Z.js";import{n as c}from"./react-vendor-Dr5xvL-e.js";import{ft as l,ht as u,yt as d}from"./index-yV1wtqTr.js";var f=t({SkillsDialog:()=>_,SkillsManagerPanel:()=>g}),p=e(i(),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:i,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&&!i)return;let t=!1;return(async()=>{E(!0),A(``);try{let e=j?`/api/skills?projectId=${encodeURIComponent(i.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,i,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&&i?(t.set(`scope`,`project`),t.set(`projectId`,i.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&&!i)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:i.id,selectedSkills:[...e]}:{selectedSkills:[...e]})}));g({scope:t,project:j?n.projects?.find(e=>e.id===i.id)??{...i,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:i.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)(a,{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)(o,{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};
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-B8Awq5FV.js"></script>
14
+ <script type="module" crossorigin src="/assets/index-yV1wtqTr.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-ko_i0WpN.js">
21
- <link rel="modulepreload" crossorigin href="/assets/react-vendor-2RKYr-A4.js">
20
+ <link rel="modulepreload" crossorigin href="/assets/icons-BP8YOS-Z.js">
21
+ <link rel="modulepreload" crossorigin href="/assets/react-vendor-Dr5xvL-e.js">
22
22
  <link rel="modulepreload" crossorigin href="/assets/logger-B65Akg8A.js">
23
- <link rel="modulepreload" crossorigin href="/assets/index-B8Awq5FV.js">
24
- <link rel="modulepreload" crossorigin href="/assets/skills-dialog-MpoxntiV.js">
25
- <link rel="stylesheet" crossorigin href="/assets/index-B2eauKpo.css">
23
+ <link rel="modulepreload" crossorigin href="/assets/index-yV1wtqTr.js">
24
+ <link rel="modulepreload" crossorigin href="/assets/skills-dialog-DiJAUfvW.js">
25
+ <link rel="stylesheet" crossorigin href="/assets/index-Cu2bBHLv.css">
26
26
  </head>
27
27
  <body>
28
28
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shawnstack/quickforge",
3
- "version": "1.7.0",
3
+ "version": "1.7.2",
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",
@@ -652,11 +652,12 @@ async function createQuickForgeSession(params = {}) {
652
652
  }
653
653
 
654
654
  function waitForPromptEnd(sessionId, conn, signal) {
655
- if (pendingPrompts.has(sessionId)) return Promise.reject(new Error('ACP prompt is already running for this session.'))
655
+ if (pendingPrompts.has(sessionId)) throw new Error('ACP prompt is already running for this session.')
656
656
  const eventBus = getSessionEventBus(sessionId)
657
- if (!eventBus) return Promise.reject(new Error('Session not found'))
657
+ if (!eventBus) throw new Error('Session not found')
658
658
 
659
- return new Promise((resolve, reject) => {
659
+ let failPrompt
660
+ const done = new Promise((resolve, reject) => {
660
661
  let settled = false
661
662
 
662
663
  const cleanup = () => {
@@ -678,6 +679,7 @@ function waitForPromptEnd(sessionId, conn, signal) {
678
679
  cleanup()
679
680
  reject(err)
680
681
  }
682
+ failPrompt = fail
681
683
 
682
684
  const sendUpdate = (update) => {
683
685
  conn.sessionUpdate({ sessionId, update }).catch((err) => {
@@ -712,7 +714,7 @@ function waitForPromptEnd(sessionId, conn, signal) {
712
714
  finish({ stopReason: 'cancelled' })
713
715
  }
714
716
 
715
- pendingPrompts.set(sessionId, { cancel: onAbort })
717
+ pendingPrompts.set(sessionId, { cancel: onAbort, fail })
716
718
 
717
719
  eventBus.on('agent_event', onEvent)
718
720
  if (signal) {
@@ -723,6 +725,7 @@ function waitForPromptEnd(sessionId, conn, signal) {
723
725
  signal.addEventListener('abort', onAbort, { once: true })
724
726
  }
725
727
  })
728
+ return { done, fail: (error) => failPrompt?.(error) }
726
729
  }
727
730
 
728
731
  async function listPersistedAcpSessions(params = {}) {
@@ -825,12 +828,17 @@ export async function createQuickForgeAcpAgent() {
825
828
  },
826
829
 
827
830
  async deleteSession(params = {}) {
831
+ pendingPrompts.get(params.sessionId)?.fail(new Error('ACP session deleted'))
828
832
  await destroyAgent(params.sessionId)
829
833
  acpSessions.delete(params.sessionId)
830
834
  return {}
831
835
  },
832
836
 
833
837
  async closeSession(params = {}) {
838
+ const pendingPrompt = pendingPrompts.get(params.sessionId)
839
+ if (pendingPrompt) {
840
+ pendingPrompt.cancel()
841
+ }
834
842
  try {
835
843
  await abortRun(params.sessionId)
836
844
  } catch {
@@ -853,9 +861,13 @@ export async function createQuickForgeAcpAgent() {
853
861
  if (!message) throw new Error('Prompt is empty or unsupported.')
854
862
  const state = getSessionState(params.sessionId)
855
863
  if (!state) throw new Error('Session not found')
856
- const done = waitForPromptEnd(params.sessionId, conn, signal)
857
- await runPrompt(params.sessionId, withAcpContext(params.sessionId, message))
858
- return done
864
+ const pendingPrompt = waitForPromptEnd(params.sessionId, conn, signal)
865
+ try {
866
+ await runPrompt(params.sessionId, withAcpContext(params.sessionId, message))
867
+ } catch (error) {
868
+ pendingPrompt.fail(error)
869
+ }
870
+ return pendingPrompt.done
859
871
  },
860
872
 
861
873
  async cancel(params = {}) {
@@ -41,14 +41,24 @@ function parseQuickForgeToolName(value) {
41
41
  }
42
42
  }
43
43
 
44
- function withTimeout(promise, timeoutMs, message) {
44
+ function withTimeout(promise, timeoutMs, message, onTimeout) {
45
45
  let timer
46
- return Promise.race([
47
- promise.finally(() => clearTimeout(timer)),
48
- new Promise((_, reject) => {
49
- timer = setTimeout(() => reject(new Error(message)), timeoutMs)
50
- }),
51
- ])
46
+ let timedOut = false
47
+ const guardedPromise = promise.catch((error) => {
48
+ if (timedOut) return new Promise(() => {})
49
+ throw error
50
+ })
51
+ const timeoutPromise = new Promise((_, reject) => {
52
+ timer = setTimeout(async () => {
53
+ timedOut = true
54
+ try {
55
+ await onTimeout?.()
56
+ } finally {
57
+ reject(new Error(message))
58
+ }
59
+ }, timeoutMs)
60
+ })
61
+ return Promise.race([guardedPromise, timeoutPromise]).finally(() => clearTimeout(timer))
52
62
  }
53
63
 
54
64
  function truncateText(value, max = MAX_TEXT_LENGTH) {
@@ -142,12 +152,27 @@ async function connectServer(config) {
142
152
  connection.error = error?.message || 'MCP transport error'
143
153
  }
144
154
 
145
- await withTimeout(client.connect(transport), CONNECT_TIMEOUT_MS, `MCP server ${config.name} connection timed out`)
146
- const listed = await withTimeout(client.listTools(), CONNECT_TIMEOUT_MS, `MCP server ${config.name} tool discovery timed out`)
147
- connection.tools = Array.isArray(listed?.tools) ? listed.tools : []
148
- connection.status = 'connected'
149
- connection.connectedAt = new Date().toISOString()
150
- return connection
155
+ try {
156
+ await withTimeout(
157
+ client.connect(transport),
158
+ CONNECT_TIMEOUT_MS,
159
+ `MCP server ${config.name} connection timed out`,
160
+ )
161
+ const listed = await withTimeout(
162
+ client.listTools(undefined, { timeout: CONNECT_TIMEOUT_MS }),
163
+ CONNECT_TIMEOUT_MS,
164
+ `MCP server ${config.name} tool discovery timed out`,
165
+ )
166
+ connection.tools = Array.isArray(listed?.tools) ? listed.tools : []
167
+ connection.status = 'connected'
168
+ connection.connectedAt = new Date().toISOString()
169
+ return connection
170
+ } catch (error) {
171
+ connection.status = 'error'
172
+ connection.error = error?.message || 'Failed to connect MCP server'
173
+ await closeConnection(connection)
174
+ throw error
175
+ }
151
176
  }
152
177
 
153
178
  async function closeConnection(connection) {
@@ -337,10 +362,25 @@ export async function callMcpTool(toolName, params = {}) {
337
362
  error.statusCode = 404
338
363
  throw error
339
364
  }
365
+ const controller = new AbortController()
340
366
  const result = await withTimeout(
341
- connection.client.callTool({ name: tool.name, arguments: params || {} }),
367
+ connection.client.callTool(
368
+ { name: tool.name, arguments: params || {} },
369
+ undefined,
370
+ { signal: controller.signal, timeout: CALL_TIMEOUT_MS },
371
+ ),
342
372
  CALL_TIMEOUT_MS,
343
373
  `MCP tool ${toolName} timed out`,
374
+ async () => {
375
+ controller.abort()
376
+ if (connections.get(parsed.serverName) === connection) connections.delete(parsed.serverName)
377
+ connection.status = 'error'
378
+ connection.error = `MCP tool ${toolName} timed out`
379
+ await Promise.race([
380
+ closeConnection(connection),
381
+ new Promise((resolve) => setTimeout(resolve, 1000)),
382
+ ])
383
+ },
344
384
  )
345
385
  return {
346
386
  isError: Boolean(result?.isError),
@@ -1,3 +1,5 @@
1
+ import { promises as fs } from 'node:fs'
2
+ import { createHash } from 'node:crypto'
1
3
  import { pathToFileURL } from 'node:url'
2
4
 
3
5
  function isPlainObject(value) {
@@ -19,7 +21,9 @@ function contentToText(result) {
19
21
 
20
22
  export async function loadPlugin(manifest, context = {}) {
21
23
  const mainPath = new URL(manifest.main, pathToFileURL(`${manifest.dir}/`))
22
- const moduleUrl = `${mainPath.href}?quickforgePluginReload=${Date.now()}`
24
+ const source = await fs.readFile(mainPath)
25
+ const reloadToken = createHash('sha256').update(source).digest('hex')
26
+ const moduleUrl = `${mainPath.href}?quickforgePluginReload=${reloadToken}`
23
27
  const module = await import(moduleUrl)
24
28
  const factory = module.createPlugin || module.default
25
29
  if (typeof factory !== 'function') {
@@ -41,6 +45,7 @@ export async function loadPlugin(manifest, context = {}) {
41
45
  }
42
46
 
43
47
  const tools = isPlainObject(plugin.tools) ? plugin.tools : {}
48
+ const dispose = typeof plugin.dispose === 'function' ? plugin.dispose.bind(plugin) : null
44
49
  return {
45
50
  async callTool(toolName, params = {}, toolContext = {}) {
46
51
  const handler = tools[toolName]
@@ -52,5 +57,8 @@ export async function loadPlugin(manifest, context = {}) {
52
57
  isError: Boolean(result?.isError),
53
58
  }
54
59
  },
60
+ async dispose() {
61
+ if (dispose) await dispose()
62
+ },
55
63
  }
56
64
  }
@@ -18,6 +18,7 @@ const globalPluginDir = path.join(dataDir, 'plugins')
18
18
  const legacyGlobalPluginDir = path.join(os.homedir(), '.agents', 'plugins')
19
19
  let cachedCatalog = null
20
20
  let cachedCatalogKey = null
21
+ let catalogDirty = false
21
22
  let refreshPromise = null
22
23
 
23
24
  function catalogKey(projectContext = null) {
@@ -96,7 +97,7 @@ async function discoverManifests(projectContext) {
96
97
  return { manifests, errors, roots }
97
98
  }
98
99
 
99
- async function loadEnabledPlugins(projectContext) {
100
+ async function loadEnabledPlugins(projectContext, previousCatalog = null) {
100
101
  const store = await readPluginStore()
101
102
  const { manifests, errors, roots } = await discoverManifests(projectContext)
102
103
  const plugins = []
@@ -126,8 +127,16 @@ async function loadEnabledPlugins(projectContext) {
126
127
  handlers.set(manifest.name, loaded)
127
128
  } catch (error) {
128
129
  logger.error(`Failed to load plugin ${manifest.name}:`, error)
129
- entry.status = 'error'
130
- entry.error = error?.message || 'Failed to load plugin'
130
+ const previousPlugin = previousCatalog?.plugins?.find((plugin) => plugin.name === manifest.name)
131
+ const previousHandler = previousCatalog?.handlers?.get(manifest.name)
132
+ if (previousPlugin?.enabled && previousPlugin.status === 'loaded' && previousHandler) {
133
+ handlers.set(manifest.name, previousHandler)
134
+ entry.status = 'loaded'
135
+ entry.error = error?.message || 'Failed to reload plugin; using previous instance'
136
+ } else {
137
+ entry.status = 'error'
138
+ entry.error = error?.message || 'Failed to load plugin'
139
+ }
131
140
  }
132
141
  }
133
142
 
@@ -138,12 +147,27 @@ async function loadEnabledPlugins(projectContext) {
138
147
  return { plugins, handlers, errors, roots }
139
148
  }
140
149
 
150
+ async function disposeHandlers(catalog, retainedHandlers = new Set()) {
151
+ if (!catalog?.handlers) return
152
+ await Promise.allSettled(Array.from(catalog.handlers.entries(), async ([name, handler]) => {
153
+ if (retainedHandlers.has(handler) || typeof handler?.dispose !== 'function') return
154
+ try {
155
+ await handler.dispose()
156
+ } catch (error) {
157
+ logger.warn(`Failed to dispose plugin ${name}:`, error)
158
+ }
159
+ }))
160
+ }
161
+
141
162
  export async function refreshPlugins(projectContext = null) {
142
163
  const key = catalogKey(projectContext)
143
164
  if (!refreshPromise) {
144
- refreshPromise = loadEnabledPlugins(projectContext).then((catalog) => {
165
+ const previousCatalog = cachedCatalogKey === key ? cachedCatalog : null
166
+ refreshPromise = loadEnabledPlugins(projectContext, previousCatalog).then(async (catalog) => {
145
167
  cachedCatalog = catalog
146
168
  cachedCatalogKey = key
169
+ catalogDirty = false
170
+ await disposeHandlers(previousCatalog, new Set(catalog.handlers.values()))
147
171
  return catalog
148
172
  }).finally(() => {
149
173
  refreshPromise = null
@@ -154,7 +178,7 @@ export async function refreshPlugins(projectContext = null) {
154
178
 
155
179
  async function getCatalog(projectContext = null) {
156
180
  const key = catalogKey(projectContext)
157
- if (!cachedCatalog || cachedCatalogKey !== key) return refreshPlugins(projectContext)
181
+ if (!cachedCatalog || cachedCatalogKey !== key || catalogDirty) return refreshPlugins(projectContext)
158
182
  return cachedCatalog
159
183
  }
160
184
 
@@ -183,7 +207,7 @@ export async function getEnabledPluginCommandSources(projectContext = null) {
183
207
  }
184
208
 
185
209
  export async function getPluginStatus(projectContext = null) {
186
- const catalog = await refreshPlugins(projectContext)
210
+ const catalog = await getCatalog(projectContext)
187
211
  return {
188
212
  searchPaths: catalog.roots,
189
213
  errors: catalog.errors,
@@ -221,8 +245,7 @@ export async function setPluginEnabled(name, enabled) {
221
245
  next.enabled[name] = enabled === true
222
246
  return next
223
247
  })
224
- cachedCatalog = null
225
- cachedCatalogKey = null
248
+ catalogDirty = true
226
249
  }
227
250
 
228
251
  export async function setPluginConfig(name, config) {
@@ -231,8 +254,7 @@ export async function setPluginConfig(name, config) {
231
254
  next.config[name] = isPlainObject(config) ? config : {}
232
255
  return next
233
256
  })
234
- cachedCatalog = null
235
- cachedCatalogKey = null
257
+ catalogDirty = true
236
258
  }
237
259
 
238
260
  export async function createPluginToolDefinitions(projectContext = null) {