@coralai/sps-cli 0.50.24 → 0.51.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +18 -1
  2. package/dist/commands/projectInit.d.ts +15 -0
  3. package/dist/commands/projectInit.d.ts.map +1 -1
  4. package/dist/commands/projectInit.js +191 -3
  5. package/dist/commands/projectInit.js.map +1 -1
  6. package/dist/commands/wikiCommand.d.ts +77 -0
  7. package/dist/commands/wikiCommand.d.ts.map +1 -0
  8. package/dist/commands/wikiCommand.js +489 -0
  9. package/dist/commands/wikiCommand.js.map +1 -0
  10. package/dist/console/routes/projects.d.ts.map +1 -1
  11. package/dist/console/routes/projects.js +1 -0
  12. package/dist/console/routes/projects.js.map +1 -1
  13. package/dist/console-assets/assets/index-DRhdpvew.css +10 -0
  14. package/dist/console-assets/assets/{index-QBai48VV.js → index-WUGCBcyb.js} +3 -3
  15. package/dist/console-assets/index.html +2 -2
  16. package/dist/core/taskPrompts.d.ts +12 -0
  17. package/dist/core/taskPrompts.d.ts.map +1 -1
  18. package/dist/core/taskPrompts.js +14 -0
  19. package/dist/core/taskPrompts.js.map +1 -1
  20. package/dist/core/wiki/frontmatter.d.ts +55 -0
  21. package/dist/core/wiki/frontmatter.d.ts.map +1 -0
  22. package/dist/core/wiki/frontmatter.js +109 -0
  23. package/dist/core/wiki/frontmatter.js.map +1 -0
  24. package/dist/core/wiki/hot.d.ts +27 -0
  25. package/dist/core/wiki/hot.d.ts.map +1 -0
  26. package/dist/core/wiki/hot.js +124 -0
  27. package/dist/core/wiki/hot.js.map +1 -0
  28. package/dist/core/wiki/index-builder.d.ts +37 -0
  29. package/dist/core/wiki/index-builder.d.ts.map +1 -0
  30. package/dist/core/wiki/index-builder.js +130 -0
  31. package/dist/core/wiki/index-builder.js.map +1 -0
  32. package/dist/core/wiki/linter.d.ts +76 -0
  33. package/dist/core/wiki/linter.d.ts.map +1 -0
  34. package/dist/core/wiki/linter.js +280 -0
  35. package/dist/core/wiki/linter.js.map +1 -0
  36. package/dist/core/wiki/log.d.ts +24 -0
  37. package/dist/core/wiki/log.d.ts.map +1 -0
  38. package/dist/core/wiki/log.js +107 -0
  39. package/dist/core/wiki/log.js.map +1 -0
  40. package/dist/core/wiki/manifest.d.ts +59 -0
  41. package/dist/core/wiki/manifest.d.ts.map +1 -0
  42. package/dist/core/wiki/manifest.js +180 -0
  43. package/dist/core/wiki/manifest.js.map +1 -0
  44. package/dist/core/wiki/page.d.ts +72 -0
  45. package/dist/core/wiki/page.d.ts.map +1 -0
  46. package/dist/core/wiki/page.js +221 -0
  47. package/dist/core/wiki/page.js.map +1 -0
  48. package/dist/core/wiki/reader.d.ts +102 -0
  49. package/dist/core/wiki/reader.d.ts.map +1 -0
  50. package/dist/core/wiki/reader.js +225 -0
  51. package/dist/core/wiki/reader.js.map +1 -0
  52. package/dist/core/wiki/scaffold.d.ts +42 -0
  53. package/dist/core/wiki/scaffold.d.ts.map +1 -0
  54. package/dist/core/wiki/scaffold.js +223 -0
  55. package/dist/core/wiki/scaffold.js.map +1 -0
  56. package/dist/core/wiki/searcher.d.ts +73 -0
  57. package/dist/core/wiki/searcher.d.ts.map +1 -0
  58. package/dist/core/wiki/searcher.js +216 -0
  59. package/dist/core/wiki/searcher.js.map +1 -0
  60. package/dist/core/wiki/sources.d.ts +84 -0
  61. package/dist/core/wiki/sources.d.ts.map +1 -0
  62. package/dist/core/wiki/sources.js +261 -0
  63. package/dist/core/wiki/sources.js.map +1 -0
  64. package/dist/core/wiki/types.d.ts +904 -0
  65. package/dist/core/wiki/types.d.ts.map +1 -0
  66. package/dist/core/wiki/types.js +109 -0
  67. package/dist/core/wiki/types.js.map +1 -0
  68. package/dist/engines/StageEngine.d.ts +17 -1
  69. package/dist/engines/StageEngine.d.ts.map +1 -1
  70. package/dist/engines/StageEngine.js +85 -0
  71. package/dist/engines/StageEngine.js.map +1 -1
  72. package/dist/main.js +78 -1
  73. package/dist/main.js.map +1 -1
  74. package/dist/services/ProjectService.d.ts +2 -0
  75. package/dist/services/ProjectService.d.ts.map +1 -1
  76. package/dist/services/ProjectService.js.map +1 -1
  77. package/dist/shared/wikiPaths.d.ts +38 -0
  78. package/dist/shared/wikiPaths.d.ts.map +1 -0
  79. package/dist/shared/wikiPaths.js +89 -0
  80. package/dist/shared/wikiPaths.js.map +1 -0
  81. package/package.json +1 -1
  82. package/skills/wiki-update/SKILL.md +300 -0
  83. package/dist/console-assets/assets/index-BgOHCIG1.css +0 -10
@@ -332,7 +332,7 @@ Please change the parent <Route path="${_}"> to <Route path="${_==="/"?"*":`${_}
332
332
  *
333
333
  * This source code is licensed under the ISC license.
334
334
  * See the LICENSE file in the root directory of this source tree.
335
- */const IA=[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]],zA=Me("zap",IA),BA=[{to:"/chat",label:"对话",icon:lA},{to:"/projects",label:"项目",icon:tA},{to:"/board",label:"看板",icon:JC},{to:"/workers",label:"Workers",icon:n1},{to:"/logs",label:"Logs",icon:qp},{to:"/skills",label:"Skills",icon:VC},{to:"/system",label:"系统",icon:JE}];function UA(){return m.jsxs(m.Fragment,{children:[m.jsxs("div",{className:"font-[family-name:var(--font-heading)] font-bold text-lg px-3 pt-2 pb-4 flex items-center gap-3 text-[var(--color-text)]",children:[m.jsx("span",{className:"w-5 h-5 rounded-md bg-[var(--color-accent-mint)] border-2 border-[var(--color-text)] shadow-[2px_2px_0_var(--color-text)]"}),"SPS Console"]}),m.jsx("nav",{className:"flex flex-col gap-1.5 mt-2","aria-label":"主导航",children:BA.map(e=>{const t=e.icon;return m.jsxs(KE,{to:e.to,className:({isActive:n})=>["flex items-center gap-3 px-3 py-2.5 rounded-xl font-semibold text-sm cursor-pointer transition-transform duration-150","border-2 border-transparent",n?"bg-[var(--color-accent-mint)] border-[var(--color-text)] shadow-[3px_3px_0_var(--color-text)] font-bold":"text-[var(--color-text)] hover:bg-[var(--color-bg-cream)] hover:border-[var(--color-text)] hover:shadow-[3px_3px_0_var(--color-text)] hover:-translate-x-px hover:-translate-y-px"].join(" "),children:[m.jsx(t,{size:18,strokeWidth:2.5}),e.label]},e.to)})})]})}class FA extends Error{constructor(t,n,a){super(n),this.status=t,this.detail=a,this.name="ApiError"}}async function Ht(e){const t=await fetch(e,{headers:{Accept:"application/json"}});if(!t.ok){let n;try{n=await t.json()}catch{n=await t.text()}throw new FA(t.status,`${t.status} ${t.statusText}`,n)}return await t.json()}function r1(){return Ht("/api/system/info")}function $A(){return Ht("/api/system/env")}function PA(){return Ht("/api/system/env/raw")}async function qA(e,t){const n=await fetch("/api/system/env",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:e,etag:t})});if(!n.ok){const a=await n.text(),s=new Error(`${n.status}: ${a}`);throw s.status=n.status,s}return n.json()}function HA(){return Ht("/api/system/latest-version")}async function KA(){const e=await fetch("/api/system/upgrade",{method:"POST"});if(!e.ok&&e.status!==409)throw new Error(`${e.status}: ${await e.text()}`);return e.json()}async function GA(e,t=!1){const n=t?"?fix=1":"",a=await fetch(`/api/system/doctor/${encodeURIComponent(e)}${n}`,{method:"POST"});if(!a.ok)throw new Error(`${a.status}: ${await a.text()}`);return a.json()}function _r(){return Ht("/api/projects")}function QA(e){return Ht(`/api/projects/${encodeURIComponent(e)}`)}async function YA(e){const t=await fetch("/api/projects",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!t.ok){const n=await t.text();throw new Error(`${t.status}: ${n}`)}return t.json()}function VA(e){return Ht(`/api/projects/${encodeURIComponent(e)}/conf`)}async function XA(e,t,n){const a=await fetch(`/api/projects/${encodeURIComponent(e)}/conf`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:t,etag:n})});if(!a.ok){const s=await a.text(),o=new Error(`${a.status}: ${s}`);throw o.status=a.status,o}return a.json()}async function ZA(e,t={}){const n=await fetch(`/api/projects/${encodeURIComponent(e)}`,{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!n.ok){const a=await n.text();throw new Error(`${n.status}: ${a}`)}return n.json()}function WA(e){return Ht(`/api/projects/${encodeURIComponent(e)}/pipelines`)}async function JA(e,t){const n=await fetch(`/api/projects/${encodeURIComponent(e)}/pipeline`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({pipeline:t})});if(!n.ok){const a=await n.text();throw new Error(`${n.status}: ${a}`)}return n.json()}function e2(e,t){return Ht(`/api/projects/${encodeURIComponent(e)}/pipelines/${encodeURIComponent(t)}`)}async function t2(e,t,n,a){const s=await fetch(`/api/projects/${encodeURIComponent(e)}/pipelines/${encodeURIComponent(t)}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:n,etag:a})});if(!s.ok){const o=await s.text(),c=new Error(`${s.status}: ${o}`);throw c.status=s.status,c}return s.json()}async function n2(e,t,n="blank"){const a=await fetch(`/api/projects/${encodeURIComponent(e)}/pipelines`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:t,template:n})});if(!a.ok){const s=await a.text();throw new Error(`${a.status}: ${s}`)}return a.json()}async function i2(e,t){const n=await fetch(`/api/projects/${encodeURIComponent(e)}/pipelines/${encodeURIComponent(t)}`,{method:"DELETE"});if(!n.ok){const a=await n.text();throw new Error(`${n.status}: ${a}`)}}function a2(){var f;const e=lt({queryKey:["system-info"],queryFn:r1,refetchInterval:3e4}),t=lt({queryKey:["projects"],queryFn:_r,refetchInterval:1e4}),n=s2(),a=!e.isError,s=((f=t.data)==null?void 0:f.data)??[],o=s.filter(d=>d.pipelineStatus==="running").length,c=s.reduce((d,h)=>d+h.workers.active,0);return m.jsxs("div",{className:"h-10 flex items-center gap-3 px-6 font-[family-name:var(--font-mono)] text-[11px] text-[var(--color-text-muted)]",children:[m.jsx("span",{className:"nb-status",style:{background:a?"var(--color-running-bg)":"var(--color-crashed-bg)",color:a?"var(--color-running)":"var(--color-crashed)",padding:"2px 8px 2px 7px"},children:a?"server":"offline"}),m.jsx(r2,{state:n}),m.jsx("span",{className:"text-[var(--color-text-subtle)]",children:"·"}),m.jsxs("span",{className:"flex items-center gap-1",title:"活跃 pipeline 数",children:[m.jsx(jf,{size:10,strokeWidth:2.5}),m.jsx("span",{className:"font-bold text-[var(--color-text)]",children:o})," pipeline"]}),m.jsx("span",{className:"text-[var(--color-text-subtle)]",children:"·"}),m.jsxs("span",{className:"flex items-center gap-1",title:"活跃 worker 数",children:[m.jsx(ZE,{size:10,strokeWidth:2.5}),m.jsx("span",{className:"font-bold text-[var(--color-text)]",children:c})," worker"]}),m.jsx("span",{className:"text-[var(--color-text-subtle)]",children:"·"}),m.jsxs("span",{children:["localhost:",window.location.port]}),e.data&&m.jsxs(m.Fragment,{children:[m.jsx("span",{className:"text-[var(--color-text-subtle)]",children:"·"}),m.jsxs("span",{children:["v",e.data.version]}),m.jsx("span",{className:"text-[var(--color-text-subtle)]",children:"·"}),m.jsxs("span",{children:["node ",e.data.nodeVersion]})]})]})}function r2({state:e}){return e==="open"?m.jsx("span",{className:"nb-status",style:{background:"var(--color-running-bg)",color:"var(--color-running)",padding:"2px 8px 2px 7px"},children:"SSE"}):e==="connecting"?m.jsx("span",{className:"nb-status",style:{background:"var(--color-stuck-bg)",color:"var(--color-stuck)",padding:"2px 8px 2px 7px"},children:"SSE·connect"}):m.jsxs("span",{className:"nb-status",style:{background:"var(--color-crashed-bg)",color:"var(--color-crashed)",padding:"2px 8px 2px 7px"},children:[m.jsx(rc,{size:9,strokeWidth:2.5}),"SSE·down"]})}function s2(){const[e,t]=M.useState("connecting");return M.useEffect(()=>{let n=null,a=null,s=!1;const o=()=>{s||(n=new EventSource("/stream/heartbeat"),n.addEventListener("server.heartbeat",()=>t("open")),n.addEventListener("open",()=>t("open")),n.addEventListener("error",()=>{(n==null?void 0:n.readyState)===EventSource.CLOSED?(t("closed"),a==null&&(a=setTimeout(()=>{a=null,n==null||n.close(),o()},1e4))):t("connecting")}))};return o(),()=>{s=!0,a!=null&&clearTimeout(a),n==null||n.close()}},[]),e}function l2(){return m.jsxs("div",{className:"grid grid-cols-[240px_1fr] grid-rows-[1fr_40px] min-h-screen",children:[m.jsx("aside",{className:"row-span-1 row-start-1 border-r-[3px] border-[var(--color-text)] bg-[var(--color-bg)] p-4 flex flex-col",children:m.jsx(UA,{})}),m.jsx("main",{className:"row-start-1 overflow-auto p-6 flex flex-col gap-4",children:m.jsx(RT,{})}),m.jsx("footer",{className:"col-span-2 row-start-2 border-t-[3px] border-[var(--color-text)] bg-[var(--color-bg)]",children:m.jsx(a2,{})})]})}function rp(e,t){try{const n=JSON.stringify({message:(e instanceof Error?e.message:String(e)).slice(0,1e3),stack:(e instanceof Error?e.stack??"":"").slice(0,4e3),url:typeof window<"u"?window.location.href:"",ua:typeof navigator<"u"?navigator.userAgent:"",ts:new Date().toISOString(),context:t==null?void 0:t.slice(0,200)});fetch("/api/system/client-errors",{method:"POST",headers:{"Content-Type":"application/json"},body:n,keepalive:!0}).catch(()=>{})}catch{}}function o2(){typeof window>"u"||(window.addEventListener("error",e=>{rp(e.error??e.message??"unknown error","window.error")}),window.addEventListener("unhandledrejection",e=>{const t=e.reason;rp(t instanceof Error?t:String(t),"unhandledrejection")}))}class c2 extends M.Component{constructor(){super(...arguments);uv(this,"state",{error:null})}static getDerivedStateFromError(n){return{error:n}}componentDidCatch(n,a){var s;rp(n,`ErrorBoundary: ${((s=a.componentStack)==null?void 0:s.slice(0,200))??""}`),console.error("[ErrorBoundary]",n,a)}render(){return this.state.error?m.jsx("div",{className:"p-6",children:m.jsxs("div",{className:"nb-card max-w-2xl bg-[var(--color-crashed-bg)]",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-2xl font-bold mb-2",children:"💥 UI 崩了"}),m.jsx("p",{className:"text-sm mb-3 text-[var(--color-text-muted)]",children:this.state.error.message}),m.jsxs("details",{className:"text-xs mb-4",children:[m.jsx("summary",{className:"cursor-pointer font-semibold",children:"stack"}),m.jsx("pre",{className:"mt-2 font-[family-name:var(--font-mono)] overflow-auto max-h-60 bg-[var(--color-bg)] border-2 border-[var(--color-text)] rounded-md p-3",children:this.state.error.stack??"(no stack)"})]}),m.jsx("button",{className:"nb-btn nb-btn-mint",type:"button",onClick:()=>{this.setState({error:null}),window.location.reload()},children:"刷新页面"})]})}):this.props.children}}function u2(){const e=wr(),{data:t,isLoading:n,isError:a,error:s,refetch:o}=lt({queryKey:["projects"],queryFn:_r});return m.jsxs("div",{className:"flex flex-col gap-6 max-w-6xl",children:[m.jsxs("header",{className:"flex items-center justify-between",children:[m.jsxs("div",{children:[m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-4xl font-bold tracking-tight",children:"项目 🎯"}),m.jsx("p",{className:"text-[var(--color-text-muted)] text-sm mt-1",children:t?`${t.data.length} 个本机项目`:n?"加载中…":"点击刷新重试"})]}),m.jsxs("div",{className:"flex items-center gap-3",children:[m.jsxs("button",{className:"nb-btn nb-btn-yellow",onClick:()=>o(),type:"button",children:[m.jsx(jf,{size:16,strokeWidth:2.5}),"刷新"]}),m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"button",onClick:()=>e("/projects/new"),"aria-label":"新建项目",children:[m.jsx(Xi,{size:16,strokeWidth:3}),"新建项目"]})]})]}),n&&m.jsx(h2,{}),a&&m.jsxs("div",{className:"nb-card bg-[var(--color-crashed-bg)]",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-xl font-bold mb-2",children:"加载失败"}),m.jsx("p",{className:"text-sm text-[var(--color-text)]",children:s instanceof Error?s.message:String(s)}),m.jsx("button",{className:"nb-btn mt-4",onClick:()=>o(),type:"button",children:"重试"})]}),t&&t.data.length===0&&m.jsx(m2,{}),t&&t.data.length>0&&m.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",children:t.data.map(c=>m.jsx(f2,{project:c},c.name))})]})}function f2({project:e}){const t=e.pipelineStatus==="running";return m.jsxs(ds,{to:`/projects/${encodeURIComponent(e.name)}`,className:"nb-card nb-card-interactive block no-underline text-[var(--color-text)]",children:[m.jsxs("div",{className:"flex items-center justify-between mb-3",children:[m.jsx("h3",{className:"font-[family-name:var(--font-heading)] font-bold text-xl truncate",children:e.name}),m.jsx(d2,{status:e.pipelineStatus})]}),e.repoDir&&m.jsx("p",{className:"text-xs font-[family-name:var(--font-mono)] text-[var(--color-text-muted)] truncate mb-3",children:e.repoDir}),m.jsxs("div",{className:"grid grid-cols-3 gap-2 text-sm mt-4 pt-3 border-t-[1.5px] border-dashed border-[var(--color-border-light)]",children:[m.jsx(fm,{label:"cards",value:e.cards.total,accent:"purple"}),m.jsx(fm,{label:"inprogress",value:e.cards.inprogress,accent:e.cards.inprogress>0?"yellow":"idle"}),m.jsx(fm,{label:"workers",value:`${e.workers.active}/${e.workers.total}`,accent:t?"mint":"idle"})]})]})}function fm({label:e,value:t,accent:n}){const a={purple:"var(--color-accent-purple)",yellow:"var(--color-accent-yellow)",mint:"var(--color-accent-mint)",idle:"var(--color-bg-cream)"};return m.jsxs("div",{className:"flex flex-col items-center justify-center py-2 rounded-lg border-2 border-[var(--color-text)]",style:{background:a[n]},children:[m.jsx("span",{className:"font-[family-name:var(--font-mono)] font-bold text-lg",children:t}),m.jsx("span",{className:"text-[10px] uppercase tracking-wider text-[var(--color-text-muted)] font-semibold",children:e})]})}function d2({status:e}){const t={running:{bg:"var(--color-running-bg)",label:"running"},idle:{bg:"var(--color-idle-bg)",label:"idle"},stopping:{bg:"var(--color-stuck-bg)",label:"stopping"},error:{bg:"var(--color-crashed-bg)",label:"error"}},{bg:n,label:a}=t[e],s=e==="running"?"var(--color-running)":e==="error"?"var(--color-crashed)":e==="stopping"?"var(--color-stuck)":"var(--color-idle)";return m.jsx("span",{className:"nb-status",style:{background:n,color:s},children:a})}function h2(){return m.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",children:[0,1,2].map(e=>m.jsxs("div",{className:"nb-card opacity-60 animate-pulse",children:[m.jsx("div",{className:"h-6 w-32 bg-[var(--color-border-light)] rounded-md mb-3"}),m.jsx("div",{className:"h-3 w-full bg-[var(--color-border-light)] rounded-md mb-2"}),m.jsx("div",{className:"h-3 w-2/3 bg-[var(--color-border-light)] rounded-md"})]},e))})}function m2(){return m.jsxs("div",{className:"nb-card bg-[var(--color-accent-yellow)] flex items-center gap-6 p-8",children:[m.jsx("div",{className:"w-20 h-20 rounded-2xl bg-[var(--color-accent-mint)] border-[3px] border-[var(--color-text)] shadow-[3px_3px_0_var(--color-text)] flex items-center justify-center",children:m.jsx(n1,{size:32,strokeWidth:2.5})}),m.jsxs("div",{className:"flex-1",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-2xl font-bold mb-2",children:"还没有项目 ✨"}),m.jsxs("p",{className:"text-sm text-[var(--color-text)] mb-4",children:["运行 ",m.jsx("code",{className:"bg-[var(--color-bg)] border-2 border-[var(--color-text)] px-2 py-0.5 rounded-md font-[family-name:var(--font-mono)]",children:"sps project init <name>"})," 创建第一个项目。"]}),m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"button",children:[m.jsx(Xi,{size:16,strokeWidth:3}),"新建项目"]})]})]})}function p2({title:e,body:t,confirm:n,onConfirm:a,onCancel:s,danger:o}){return M.useEffect(()=>{const c=f=>{f.key==="Escape"&&s()};return window.addEventListener("keydown",c),()=>window.removeEventListener("keydown",c)},[s]),m.jsx("div",{role:"dialog","aria-modal":"true","aria-labelledby":"confirm-title",className:"fixed inset-0 z-50 flex items-center justify-center p-6 bg-black/30",children:m.jsxs("div",{className:"nb-card max-w-md w-full",children:[m.jsx("h2",{id:"confirm-title",className:"font-[family-name:var(--font-heading)] text-xl font-bold mb-2",children:e}),m.jsx("p",{className:"text-sm text-[var(--color-text-muted)] mb-5",children:t}),m.jsxs("div",{className:"flex gap-3 justify-end",children:[m.jsx("button",{className:"nb-btn",onClick:s,type:"button",children:"取消"}),m.jsx("button",{className:o?"nb-btn nb-btn-danger":"nb-btn nb-btn-yellow",onClick:async()=>{await a()},type:"button",children:n})]})]})})}const s1=M.createContext(null);function g2({children:e}){const[t,n]=M.useState(null),a=M.useCallback(c=>new Promise(f=>{n({kind:"confirm",opts:c,resolve:d=>{n(null),f(d)}})}),[]),s=M.useCallback(c=>new Promise(f=>{n({kind:"alert",opts:c,resolve:()=>{n(null),f()}})}),[]),o=M.useCallback(c=>new Promise(f=>{n({kind:"prompt",opts:c,resolve:d=>{n(null),f(d)}})}),[]);return m.jsxs(s1.Provider,{value:{confirm:a,alert:s,prompt:o},children:[e,(t==null?void 0:t.kind)==="confirm"&&m.jsx(p2,{title:t.opts.title,body:t.opts.body,confirm:t.opts.confirm??"确定",danger:t.opts.danger,onConfirm:()=>t.resolve(!0),onCancel:()=>t.resolve(!1)}),(t==null?void 0:t.kind)==="alert"&&m.jsx(b2,{title:t.opts.title,body:t.opts.body,confirm:t.opts.confirm??"知道了",onClose:()=>t.resolve()}),(t==null?void 0:t.kind)==="prompt"&&m.jsx(y2,{title:t.opts.title,body:t.opts.body,placeholder:t.opts.placeholder,defaultValue:t.opts.defaultValue,confirm:t.opts.confirm??"确定",cancel:t.opts.cancel??"取消",onConfirm:c=>t.resolve(c),onCancel:()=>t.resolve(null)})]})}function si(){const e=M.useContext(s1);if(!e)throw new Error("useDialog must be used inside <DialogProvider>");return e}function b2({title:e,body:t,confirm:n,onClose:a}){return M.useEffect(()=>{const s=o=>{(o.key==="Escape"||o.key==="Enter")&&a()};return window.addEventListener("keydown",s),()=>window.removeEventListener("keydown",s)},[a]),m.jsx("div",{role:"dialog","aria-modal":"true",className:"fixed inset-0 z-50 flex items-center justify-center p-6 bg-black/30",children:m.jsxs("div",{className:"nb-card max-w-md w-full",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-xl font-bold mb-2",children:e}),m.jsx("p",{className:"text-sm text-[var(--color-text-muted)] mb-5 whitespace-pre-wrap break-words",children:t}),m.jsx("div",{className:"flex gap-3 justify-end",children:m.jsx("button",{className:"nb-btn nb-btn-primary",onClick:a,type:"button",autoFocus:!0,children:n})})]})})}function y2({title:e,body:t,placeholder:n,defaultValue:a,confirm:s,cancel:o,onConfirm:c,onCancel:f}){const[d,h]=M.useState(a??""),y=M.useRef(null);M.useEffect(()=>{var v,S;(v=y.current)==null||v.focus(),(S=y.current)==null||S.select();const x=w=>{w.key==="Escape"&&f()};return window.addEventListener("keydown",x),()=>window.removeEventListener("keydown",x)},[f]);const g=()=>{const x=d.trim();x&&c(x)};return m.jsx("div",{role:"dialog","aria-modal":"true",className:"fixed inset-0 z-50 flex items-center justify-center p-6 bg-black/30",children:m.jsxs("div",{className:"nb-card max-w-md w-full",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-xl font-bold mb-2",children:e}),t&&m.jsx("p",{className:"text-sm text-[var(--color-text-muted)] mb-3 whitespace-pre-wrap break-words",children:t}),m.jsx("input",{ref:y,type:"text",className:"nb-input w-full mb-5",placeholder:n,value:d,onChange:x=>h(x.target.value),onKeyDown:x=>{x.key==="Enter"&&!x.nativeEvent.isComposing&&(x.preventDefault(),g())}}),m.jsxs("div",{className:"flex gap-3 justify-end",children:[m.jsx("button",{className:"nb-btn",onClick:f,type:"button",children:o}),m.jsx("button",{className:"nb-btn nb-btn-primary",onClick:g,type:"button",disabled:!d.trim(),children:s})]})]})})}function x2(){const e=wr(),t=qn(),{alert:n}=si(),[a,s]=M.useState({name:"",projectDir:"",enableGit:!0,mergeBranch:"main",maxWorkers:"1",ackTimeoutMin:"5"}),o=Pn({mutationFn:d=>YA(d),onSuccess:d=>{t.invalidateQueries({queryKey:["projects"]}),e(`/projects/${encodeURIComponent(d.name)}`)},onError:d=>{n({title:"创建失败",body:d instanceof Error?d.message:String(d)})}}),c=/^[a-zA-Z0-9_-]+$/.test(a.name),f=c&&a.projectDir.trim()!==""&&!o.isPending;return m.jsxs("div",{className:"flex flex-col gap-5 max-w-2xl",children:[m.jsxs("header",{className:"flex items-center gap-3",children:[m.jsxs("button",{type:"button",onClick:()=>e("/projects"),className:"nb-btn",style:{padding:"6px 12px"},"aria-label":"返回项目列表",children:[m.jsx(VE,{size:14,strokeWidth:3}),"返回"]}),m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-3xl font-bold",children:"新建项目"})]}),m.jsx("div",{className:"nb-card",children:m.jsxs("form",{onSubmit:d=>{d.preventDefault(),f&&o.mutate(a)},className:"flex flex-col gap-5",children:[m.jsxs(rr,{label:"项目名",hint:"只能用字母、数字、下划线、连字符。例如 acme-web",children:[m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"例如: acme-web",value:a.name,onChange:d=>s({...a,name:d.target.value}),autoFocus:!0,required:!0}),a.name&&!c&&m.jsx("p",{className:"text-xs text-[var(--color-crashed)] mt-1",children:"名称只能包含 a-z A-Z 0-9 _ -"})]}),m.jsx(rr,{label:"项目目录",hint:"本机绝对路径(代码或文档都可)。和是否启用 git 无关。",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"/home/coral/code/acme",value:a.projectDir,onChange:d=>s({...a,projectDir:d.target.value}),required:!0})}),m.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[m.jsx(rr,{label:"最大 Worker 数",children:m.jsx("input",{type:"number",min:"1",max:"8",className:"nb-input w-full font-[family-name:var(--font-mono)]",value:a.maxWorkers,onChange:d=>s({...a,maxWorkers:d.target.value})})}),m.jsx(rr,{label:"ACK 超时(分钟)",hint:"Worker 启动后多久没 ACK 视为失败",children:m.jsx("input",{type:"number",min:"1",max:"30",className:"nb-input w-full font-[family-name:var(--font-mono)]",value:a.ackTimeoutMin??"5",onChange:d=>s({...a,ackTimeoutMin:d.target.value})})})]}),m.jsxs("div",{className:"pt-3 border-t-2 border-[var(--color-text)] border-dashed",children:[m.jsxs("label",{className:"flex items-center gap-3 mb-3 cursor-pointer select-none",children:[m.jsx("input",{type:"checkbox",checked:a.enableGit??!0,onChange:d=>s({...a,enableGit:d.target.checked}),className:"w-4 h-4 cursor-pointer"}),m.jsx("span",{className:"text-sm font-bold",children:"启用 Git(Worker 自动 commit + push)"})]}),m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] mb-3",children:"关闭后 Worker 只做任务、不做版本控制;适合文档/数据处理等非代码项目。"}),a.enableGit!==!1&&m.jsxs("div",{className:"flex flex-col gap-4 bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-lg p-4",children:[m.jsx(rr,{label:"合并分支",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",value:a.mergeBranch??"main",onChange:d=>s({...a,mergeBranch:d.target.value})})}),m.jsx(rr,{label:"Git 远程项目路径",hint:"如 user/repo,空则跳过远程 API(只本地 commit/push)",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"user/repo",value:a.gitlabProject??"",onChange:d=>s({...a,gitlabProject:d.target.value})})}),a.gitlabProject&&m.jsx(rr,{label:"GitLab 项目 ID",hint:"数字;GitHub 用户留空",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"42",value:a.gitlabProjectId??"",onChange:d=>s({...a,gitlabProjectId:d.target.value})})})]})]}),m.jsxs("div",{className:"pt-3 border-t-2 border-[var(--color-text)] border-dashed",children:[m.jsx("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold uppercase tracking-wider mb-3 text-[var(--color-text-muted)]",children:"通知"}),m.jsx(rr,{label:"Matrix 房间 ID",hint:"空则使用全局配置;不填 = 不通知",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"!abc:matrix.example.com",value:a.matrixRoomId??"",onChange:d=>s({...a,matrixRoomId:d.target.value})})})]}),m.jsxs("div",{className:"flex gap-3 justify-end pt-3",children:[m.jsx("button",{type:"button",className:"nb-btn",onClick:()=>e("/projects"),disabled:o.isPending,children:"取消"}),m.jsx("button",{type:"submit",className:"nb-btn nb-btn-primary",disabled:!f,"aria-label":"创建项目",children:o.isPending?m.jsxs(m.Fragment,{children:[m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}),"创建中…"]}):m.jsxs(m.Fragment,{children:[m.jsx(Xi,{size:14,strokeWidth:3}),"创建"]})})]})]})})]})}function rr({label:e,hint:t,children:n}){return m.jsxs("label",{className:"flex flex-col gap-1.5",children:[m.jsx("span",{className:"text-sm font-bold",children:e}),n,t&&m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:t})]})}const Gp=Symbol.for("yaml.alias"),sp=Symbol.for("yaml.document"),vr=Symbol.for("yaml.map"),l1=Symbol.for("yaml.pair"),Vi=Symbol.for("yaml.scalar"),zl=Symbol.for("yaml.seq"),Si=Symbol.for("yaml.node.type"),kr=e=>!!e&&typeof e=="object"&&e[Si]===Gp,hs=e=>!!e&&typeof e=="object"&&e[Si]===sp,Bl=e=>!!e&&typeof e=="object"&&e[Si]===vr,At=e=>!!e&&typeof e=="object"&&e[Si]===l1,vt=e=>!!e&&typeof e=="object"&&e[Si]===Vi,Ul=e=>!!e&&typeof e=="object"&&e[Si]===zl;function Mt(e){if(e&&typeof e=="object")switch(e[Si]){case vr:case zl:return!0}return!1}function jt(e){if(e&&typeof e=="object")switch(e[Si]){case Gp:case vr:case Vi:case zl:return!0}return!1}const o1=e=>(vt(e)||Mt(e))&&!!e.anchor,$n=Symbol("break visit"),c1=Symbol("skip children"),Yi=Symbol("remove node");function ms(e,t){const n=u1(t);hs(e)?cl(null,e.contents,n,Object.freeze([e]))===Yi&&(e.contents=null):cl(null,e,n,Object.freeze([]))}ms.BREAK=$n;ms.SKIP=c1;ms.REMOVE=Yi;function cl(e,t,n,a){const s=f1(e,t,n,a);if(jt(s)||At(s))return d1(e,a,s),cl(e,s,n,a);if(typeof s!="symbol"){if(Mt(t)){a=Object.freeze(a.concat(t));for(let o=0;o<t.items.length;++o){const c=cl(o,t.items[o],n,a);if(typeof c=="number")o=c-1;else{if(c===$n)return $n;c===Yi&&(t.items.splice(o,1),o-=1)}}}else if(At(t)){a=Object.freeze(a.concat(t));const o=cl("key",t.key,n,a);if(o===$n)return $n;o===Yi&&(t.key=null);const c=cl("value",t.value,n,a);if(c===$n)return $n;c===Yi&&(t.value=null)}}return s}async function Lf(e,t){const n=u1(t);hs(e)?await ul(null,e.contents,n,Object.freeze([e]))===Yi&&(e.contents=null):await ul(null,e,n,Object.freeze([]))}Lf.BREAK=$n;Lf.SKIP=c1;Lf.REMOVE=Yi;async function ul(e,t,n,a){const s=await f1(e,t,n,a);if(jt(s)||At(s))return d1(e,a,s),ul(e,s,n,a);if(typeof s!="symbol"){if(Mt(t)){a=Object.freeze(a.concat(t));for(let o=0;o<t.items.length;++o){const c=await ul(o,t.items[o],n,a);if(typeof c=="number")o=c-1;else{if(c===$n)return $n;c===Yi&&(t.items.splice(o,1),o-=1)}}}else if(At(t)){a=Object.freeze(a.concat(t));const o=await ul("key",t.key,n,a);if(o===$n)return $n;o===Yi&&(t.key=null);const c=await ul("value",t.value,n,a);if(c===$n)return $n;c===Yi&&(t.value=null)}}return s}function u1(e){return typeof e=="object"&&(e.Collection||e.Node||e.Value)?Object.assign({Alias:e.Node,Map:e.Node,Scalar:e.Node,Seq:e.Node},e.Value&&{Map:e.Value,Scalar:e.Value,Seq:e.Value},e.Collection&&{Map:e.Collection,Seq:e.Collection},e):e}function f1(e,t,n,a){var s,o,c,f,d;if(typeof n=="function")return n(e,t,a);if(Bl(t))return(s=n.Map)==null?void 0:s.call(n,e,t,a);if(Ul(t))return(o=n.Seq)==null?void 0:o.call(n,e,t,a);if(At(t))return(c=n.Pair)==null?void 0:c.call(n,e,t,a);if(vt(t))return(f=n.Scalar)==null?void 0:f.call(n,e,t,a);if(kr(t))return(d=n.Alias)==null?void 0:d.call(n,e,t,a)}function d1(e,t,n){const a=t[t.length-1];if(Mt(a))a.items[e]=n;else if(At(a))e==="key"?a.key=n:a.value=n;else if(hs(a))a.contents=n;else{const s=kr(a)?"alias":"scalar";throw new Error(`Cannot replace node with ${s} parent`)}}const v2={"!":"%21",",":"%2C","[":"%5B","]":"%5D","{":"%7B","}":"%7D"},E2=e=>e.replace(/[!,[\]{}]/g,t=>v2[t]);class Nn{constructor(t,n){this.docStart=null,this.docEnd=!1,this.yaml=Object.assign({},Nn.defaultYaml,t),this.tags=Object.assign({},Nn.defaultTags,n)}clone(){const t=new Nn(this.yaml,this.tags);return t.docStart=this.docStart,t}atDocument(){const t=new Nn(this.yaml,this.tags);switch(this.yaml.version){case"1.1":this.atNextDocument=!0;break;case"1.2":this.atNextDocument=!1,this.yaml={explicit:Nn.defaultYaml.explicit,version:"1.2"},this.tags=Object.assign({},Nn.defaultTags);break}return t}add(t,n){this.atNextDocument&&(this.yaml={explicit:Nn.defaultYaml.explicit,version:"1.1"},this.tags=Object.assign({},Nn.defaultTags),this.atNextDocument=!1);const a=t.trim().split(/[ \t]+/),s=a.shift();switch(s){case"%TAG":{if(a.length!==2&&(n(0,"%TAG directive should contain exactly two parts"),a.length<2))return!1;const[o,c]=a;return this.tags[o]=c,!0}case"%YAML":{if(this.yaml.explicit=!0,a.length!==1)return n(0,"%YAML directive should contain exactly one part"),!1;const[o]=a;if(o==="1.1"||o==="1.2")return this.yaml.version=o,!0;{const c=/^\d+\.\d+$/.test(o);return n(6,`Unsupported YAML version ${o}`,c),!1}}default:return n(0,`Unknown directive ${s}`,!0),!1}}tagName(t,n){if(t==="!")return"!";if(t[0]!=="!")return n(`Not a valid tag: ${t}`),null;if(t[1]==="<"){const c=t.slice(2,-1);return c==="!"||c==="!!"?(n(`Verbatim tags aren't resolved, so ${t} is invalid.`),null):(t[t.length-1]!==">"&&n("Verbatim tags must end with a >"),c)}const[,a,s]=t.match(/^(.*!)([^!]*)$/s);s||n(`The ${t} tag has no suffix`);const o=this.tags[a];if(o)try{return o+decodeURIComponent(s)}catch(c){return n(String(c)),null}return a==="!"?t:(n(`Could not resolve tag: ${t}`),null)}tagString(t){for(const[n,a]of Object.entries(this.tags))if(t.startsWith(a))return n+E2(t.substring(a.length));return t[0]==="!"?t:`!<${t}>`}toString(t){const n=this.yaml.explicit?[`%YAML ${this.yaml.version||"1.2"}`]:[],a=Object.entries(this.tags);let s;if(t&&a.length>0&&jt(t.contents)){const o={};ms(t.contents,(c,f)=>{jt(f)&&f.tag&&(o[f.tag]=!0)}),s=Object.keys(o)}else s=[];for(const[o,c]of a)o==="!!"&&c==="tag:yaml.org,2002:"||(!t||s.some(f=>f.startsWith(c)))&&n.push(`%TAG ${o} ${c}`);return n.join(`
335
+ */const IA=[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]],zA=Me("zap",IA),BA=[{to:"/chat",label:"对话",icon:lA},{to:"/projects",label:"项目",icon:tA},{to:"/board",label:"看板",icon:JC},{to:"/workers",label:"Workers",icon:n1},{to:"/logs",label:"Logs",icon:qp},{to:"/skills",label:"Skills",icon:VC},{to:"/system",label:"系统",icon:JE}];function UA(){return m.jsxs(m.Fragment,{children:[m.jsxs("div",{className:"font-[family-name:var(--font-heading)] font-bold text-lg px-3 pt-2 pb-4 flex items-center gap-3 text-[var(--color-text)]",children:[m.jsx("span",{className:"w-5 h-5 rounded-md bg-[var(--color-accent-mint)] border-2 border-[var(--color-text)] shadow-[2px_2px_0_var(--color-text)]"}),"SPS Console"]}),m.jsx("nav",{className:"flex flex-col gap-1.5 mt-2","aria-label":"主导航",children:BA.map(e=>{const t=e.icon;return m.jsxs(KE,{to:e.to,className:({isActive:n})=>["flex items-center gap-3 px-3 py-2.5 rounded-xl font-semibold text-sm cursor-pointer transition-transform duration-150","border-2 border-transparent",n?"bg-[var(--color-accent-mint)] border-[var(--color-text)] shadow-[3px_3px_0_var(--color-text)] font-bold":"text-[var(--color-text)] hover:bg-[var(--color-bg-cream)] hover:border-[var(--color-text)] hover:shadow-[3px_3px_0_var(--color-text)] hover:-translate-x-px hover:-translate-y-px"].join(" "),children:[m.jsx(t,{size:18,strokeWidth:2.5}),e.label]},e.to)})})]})}class FA extends Error{constructor(t,n,a){super(n),this.status=t,this.detail=a,this.name="ApiError"}}async function Ht(e){const t=await fetch(e,{headers:{Accept:"application/json"}});if(!t.ok){let n;try{n=await t.json()}catch{n=await t.text()}throw new FA(t.status,`${t.status} ${t.statusText}`,n)}return await t.json()}function r1(){return Ht("/api/system/info")}function $A(){return Ht("/api/system/env")}function PA(){return Ht("/api/system/env/raw")}async function qA(e,t){const n=await fetch("/api/system/env",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:e,etag:t})});if(!n.ok){const a=await n.text(),s=new Error(`${n.status}: ${a}`);throw s.status=n.status,s}return n.json()}function HA(){return Ht("/api/system/latest-version")}async function KA(){const e=await fetch("/api/system/upgrade",{method:"POST"});if(!e.ok&&e.status!==409)throw new Error(`${e.status}: ${await e.text()}`);return e.json()}async function GA(e,t=!1){const n=t?"?fix=1":"",a=await fetch(`/api/system/doctor/${encodeURIComponent(e)}${n}`,{method:"POST"});if(!a.ok)throw new Error(`${a.status}: ${await a.text()}`);return a.json()}function _r(){return Ht("/api/projects")}function QA(e){return Ht(`/api/projects/${encodeURIComponent(e)}`)}async function YA(e){const t=await fetch("/api/projects",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!t.ok){const n=await t.text();throw new Error(`${t.status}: ${n}`)}return t.json()}function VA(e){return Ht(`/api/projects/${encodeURIComponent(e)}/conf`)}async function XA(e,t,n){const a=await fetch(`/api/projects/${encodeURIComponent(e)}/conf`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:t,etag:n})});if(!a.ok){const s=await a.text(),o=new Error(`${a.status}: ${s}`);throw o.status=a.status,o}return a.json()}async function ZA(e,t={}){const n=await fetch(`/api/projects/${encodeURIComponent(e)}`,{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!n.ok){const a=await n.text();throw new Error(`${n.status}: ${a}`)}return n.json()}function WA(e){return Ht(`/api/projects/${encodeURIComponent(e)}/pipelines`)}async function JA(e,t){const n=await fetch(`/api/projects/${encodeURIComponent(e)}/pipeline`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({pipeline:t})});if(!n.ok){const a=await n.text();throw new Error(`${n.status}: ${a}`)}return n.json()}function e2(e,t){return Ht(`/api/projects/${encodeURIComponent(e)}/pipelines/${encodeURIComponent(t)}`)}async function t2(e,t,n,a){const s=await fetch(`/api/projects/${encodeURIComponent(e)}/pipelines/${encodeURIComponent(t)}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:n,etag:a})});if(!s.ok){const o=await s.text(),c=new Error(`${s.status}: ${o}`);throw c.status=s.status,c}return s.json()}async function n2(e,t,n="blank"){const a=await fetch(`/api/projects/${encodeURIComponent(e)}/pipelines`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:t,template:n})});if(!a.ok){const s=await a.text();throw new Error(`${a.status}: ${s}`)}return a.json()}async function i2(e,t){const n=await fetch(`/api/projects/${encodeURIComponent(e)}/pipelines/${encodeURIComponent(t)}`,{method:"DELETE"});if(!n.ok){const a=await n.text();throw new Error(`${n.status}: ${a}`)}}function a2(){var f;const e=lt({queryKey:["system-info"],queryFn:r1,refetchInterval:3e4}),t=lt({queryKey:["projects"],queryFn:_r,refetchInterval:1e4}),n=s2(),a=!e.isError,s=((f=t.data)==null?void 0:f.data)??[],o=s.filter(d=>d.pipelineStatus==="running").length,c=s.reduce((d,h)=>d+h.workers.active,0);return m.jsxs("div",{className:"h-10 flex items-center gap-3 px-6 font-[family-name:var(--font-mono)] text-[11px] text-[var(--color-text-muted)]",children:[m.jsx("span",{className:"nb-status",style:{background:a?"var(--color-running-bg)":"var(--color-crashed-bg)",color:a?"var(--color-running)":"var(--color-crashed)",padding:"2px 8px 2px 7px"},children:a?"server":"offline"}),m.jsx(r2,{state:n}),m.jsx("span",{className:"text-[var(--color-text-subtle)]",children:"·"}),m.jsxs("span",{className:"flex items-center gap-1",title:"活跃 pipeline 数",children:[m.jsx(jf,{size:10,strokeWidth:2.5}),m.jsx("span",{className:"font-bold text-[var(--color-text)]",children:o})," pipeline"]}),m.jsx("span",{className:"text-[var(--color-text-subtle)]",children:"·"}),m.jsxs("span",{className:"flex items-center gap-1",title:"活跃 worker 数",children:[m.jsx(ZE,{size:10,strokeWidth:2.5}),m.jsx("span",{className:"font-bold text-[var(--color-text)]",children:c})," worker"]}),m.jsx("span",{className:"text-[var(--color-text-subtle)]",children:"·"}),m.jsxs("span",{children:["localhost:",window.location.port]}),e.data&&m.jsxs(m.Fragment,{children:[m.jsx("span",{className:"text-[var(--color-text-subtle)]",children:"·"}),m.jsxs("span",{children:["v",e.data.version]}),m.jsx("span",{className:"text-[var(--color-text-subtle)]",children:"·"}),m.jsxs("span",{children:["node ",e.data.nodeVersion]})]})]})}function r2({state:e}){return e==="open"?m.jsx("span",{className:"nb-status",style:{background:"var(--color-running-bg)",color:"var(--color-running)",padding:"2px 8px 2px 7px"},children:"SSE"}):e==="connecting"?m.jsx("span",{className:"nb-status",style:{background:"var(--color-stuck-bg)",color:"var(--color-stuck)",padding:"2px 8px 2px 7px"},children:"SSE·connect"}):m.jsxs("span",{className:"nb-status",style:{background:"var(--color-crashed-bg)",color:"var(--color-crashed)",padding:"2px 8px 2px 7px"},children:[m.jsx(rc,{size:9,strokeWidth:2.5}),"SSE·down"]})}function s2(){const[e,t]=M.useState("connecting");return M.useEffect(()=>{let n=null,a=null,s=!1;const o=()=>{s||(n=new EventSource("/stream/heartbeat"),n.addEventListener("server.heartbeat",()=>t("open")),n.addEventListener("open",()=>t("open")),n.addEventListener("error",()=>{(n==null?void 0:n.readyState)===EventSource.CLOSED?(t("closed"),a==null&&(a=setTimeout(()=>{a=null,n==null||n.close(),o()},1e4))):t("connecting")}))};return o(),()=>{s=!0,a!=null&&clearTimeout(a),n==null||n.close()}},[]),e}function l2(){return m.jsxs("div",{className:"grid grid-cols-[240px_1fr] grid-rows-[1fr_40px] h-screen",children:[m.jsx("aside",{className:"row-span-1 row-start-1 border-r-[3px] border-[var(--color-text)] bg-[var(--color-bg)] p-4 flex flex-col",children:m.jsx(UA,{})}),m.jsx("main",{className:"row-start-1 overflow-auto p-6 flex flex-col gap-4",children:m.jsx(RT,{})}),m.jsx("footer",{className:"col-span-2 row-start-2 border-t-[3px] border-[var(--color-text)] bg-[var(--color-bg)]",children:m.jsx(a2,{})})]})}function rp(e,t){try{const n=JSON.stringify({message:(e instanceof Error?e.message:String(e)).slice(0,1e3),stack:(e instanceof Error?e.stack??"":"").slice(0,4e3),url:typeof window<"u"?window.location.href:"",ua:typeof navigator<"u"?navigator.userAgent:"",ts:new Date().toISOString(),context:t==null?void 0:t.slice(0,200)});fetch("/api/system/client-errors",{method:"POST",headers:{"Content-Type":"application/json"},body:n,keepalive:!0}).catch(()=>{})}catch{}}function o2(){typeof window>"u"||(window.addEventListener("error",e=>{rp(e.error??e.message??"unknown error","window.error")}),window.addEventListener("unhandledrejection",e=>{const t=e.reason;rp(t instanceof Error?t:String(t),"unhandledrejection")}))}class c2 extends M.Component{constructor(){super(...arguments);uv(this,"state",{error:null})}static getDerivedStateFromError(n){return{error:n}}componentDidCatch(n,a){var s;rp(n,`ErrorBoundary: ${((s=a.componentStack)==null?void 0:s.slice(0,200))??""}`),console.error("[ErrorBoundary]",n,a)}render(){return this.state.error?m.jsx("div",{className:"p-6",children:m.jsxs("div",{className:"nb-card max-w-2xl bg-[var(--color-crashed-bg)]",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-2xl font-bold mb-2",children:"💥 UI 崩了"}),m.jsx("p",{className:"text-sm mb-3 text-[var(--color-text-muted)]",children:this.state.error.message}),m.jsxs("details",{className:"text-xs mb-4",children:[m.jsx("summary",{className:"cursor-pointer font-semibold",children:"stack"}),m.jsx("pre",{className:"mt-2 font-[family-name:var(--font-mono)] overflow-auto max-h-60 bg-[var(--color-bg)] border-2 border-[var(--color-text)] rounded-md p-3",children:this.state.error.stack??"(no stack)"})]}),m.jsx("button",{className:"nb-btn nb-btn-mint",type:"button",onClick:()=>{this.setState({error:null}),window.location.reload()},children:"刷新页面"})]})}):this.props.children}}function u2(){const e=wr(),{data:t,isLoading:n,isError:a,error:s,refetch:o}=lt({queryKey:["projects"],queryFn:_r});return m.jsxs("div",{className:"flex flex-col gap-6 max-w-6xl",children:[m.jsxs("header",{className:"flex items-center justify-between",children:[m.jsxs("div",{children:[m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-4xl font-bold tracking-tight",children:"项目 🎯"}),m.jsx("p",{className:"text-[var(--color-text-muted)] text-sm mt-1",children:t?`${t.data.length} 个本机项目`:n?"加载中…":"点击刷新重试"})]}),m.jsxs("div",{className:"flex items-center gap-3",children:[m.jsxs("button",{className:"nb-btn nb-btn-yellow",onClick:()=>o(),type:"button",children:[m.jsx(jf,{size:16,strokeWidth:2.5}),"刷新"]}),m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"button",onClick:()=>e("/projects/new"),"aria-label":"新建项目",children:[m.jsx(Xi,{size:16,strokeWidth:3}),"新建项目"]})]})]}),n&&m.jsx(h2,{}),a&&m.jsxs("div",{className:"nb-card bg-[var(--color-crashed-bg)]",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-xl font-bold mb-2",children:"加载失败"}),m.jsx("p",{className:"text-sm text-[var(--color-text)]",children:s instanceof Error?s.message:String(s)}),m.jsx("button",{className:"nb-btn mt-4",onClick:()=>o(),type:"button",children:"重试"})]}),t&&t.data.length===0&&m.jsx(m2,{}),t&&t.data.length>0&&m.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",children:t.data.map(c=>m.jsx(f2,{project:c},c.name))})]})}function f2({project:e}){const t=e.pipelineStatus==="running";return m.jsxs(ds,{to:`/projects/${encodeURIComponent(e.name)}`,className:"nb-card nb-card-interactive block no-underline text-[var(--color-text)]",children:[m.jsxs("div",{className:"flex items-center justify-between mb-3",children:[m.jsx("h3",{className:"font-[family-name:var(--font-heading)] font-bold text-xl truncate",children:e.name}),m.jsx(d2,{status:e.pipelineStatus})]}),e.repoDir&&m.jsx("p",{className:"text-xs font-[family-name:var(--font-mono)] text-[var(--color-text-muted)] truncate mb-3",children:e.repoDir}),m.jsxs("div",{className:"grid grid-cols-3 gap-2 text-sm mt-4 pt-3 border-t-[1.5px] border-dashed border-[var(--color-border-light)]",children:[m.jsx(fm,{label:"cards",value:e.cards.total,accent:"purple"}),m.jsx(fm,{label:"inprogress",value:e.cards.inprogress,accent:e.cards.inprogress>0?"yellow":"idle"}),m.jsx(fm,{label:"workers",value:`${e.workers.active}/${e.workers.total}`,accent:t?"mint":"idle"})]})]})}function fm({label:e,value:t,accent:n}){const a={purple:"var(--color-accent-purple)",yellow:"var(--color-accent-yellow)",mint:"var(--color-accent-mint)",idle:"var(--color-bg-cream)"};return m.jsxs("div",{className:"flex flex-col items-center justify-center py-2 rounded-lg border-2 border-[var(--color-text)]",style:{background:a[n]},children:[m.jsx("span",{className:"font-[family-name:var(--font-mono)] font-bold text-lg",children:t}),m.jsx("span",{className:"text-[10px] uppercase tracking-wider text-[var(--color-text-muted)] font-semibold",children:e})]})}function d2({status:e}){const t={running:{bg:"var(--color-running-bg)",label:"running"},idle:{bg:"var(--color-idle-bg)",label:"idle"},stopping:{bg:"var(--color-stuck-bg)",label:"stopping"},error:{bg:"var(--color-crashed-bg)",label:"error"}},{bg:n,label:a}=t[e],s=e==="running"?"var(--color-running)":e==="error"?"var(--color-crashed)":e==="stopping"?"var(--color-stuck)":"var(--color-idle)";return m.jsx("span",{className:"nb-status",style:{background:n,color:s},children:a})}function h2(){return m.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",children:[0,1,2].map(e=>m.jsxs("div",{className:"nb-card opacity-60 animate-pulse",children:[m.jsx("div",{className:"h-6 w-32 bg-[var(--color-border-light)] rounded-md mb-3"}),m.jsx("div",{className:"h-3 w-full bg-[var(--color-border-light)] rounded-md mb-2"}),m.jsx("div",{className:"h-3 w-2/3 bg-[var(--color-border-light)] rounded-md"})]},e))})}function m2(){return m.jsxs("div",{className:"nb-card bg-[var(--color-accent-yellow)] flex items-center gap-6 p-8",children:[m.jsx("div",{className:"w-20 h-20 rounded-2xl bg-[var(--color-accent-mint)] border-[3px] border-[var(--color-text)] shadow-[3px_3px_0_var(--color-text)] flex items-center justify-center",children:m.jsx(n1,{size:32,strokeWidth:2.5})}),m.jsxs("div",{className:"flex-1",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-2xl font-bold mb-2",children:"还没有项目 ✨"}),m.jsxs("p",{className:"text-sm text-[var(--color-text)] mb-4",children:["运行 ",m.jsx("code",{className:"bg-[var(--color-bg)] border-2 border-[var(--color-text)] px-2 py-0.5 rounded-md font-[family-name:var(--font-mono)]",children:"sps project init <name>"})," 创建第一个项目。"]}),m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"button",children:[m.jsx(Xi,{size:16,strokeWidth:3}),"新建项目"]})]})]})}function p2({title:e,body:t,confirm:n,onConfirm:a,onCancel:s,danger:o}){return M.useEffect(()=>{const c=f=>{f.key==="Escape"&&s()};return window.addEventListener("keydown",c),()=>window.removeEventListener("keydown",c)},[s]),m.jsx("div",{role:"dialog","aria-modal":"true","aria-labelledby":"confirm-title",className:"fixed inset-0 z-50 flex items-center justify-center p-6 bg-black/30",children:m.jsxs("div",{className:"nb-card max-w-md w-full",children:[m.jsx("h2",{id:"confirm-title",className:"font-[family-name:var(--font-heading)] text-xl font-bold mb-2",children:e}),m.jsx("p",{className:"text-sm text-[var(--color-text-muted)] mb-5",children:t}),m.jsxs("div",{className:"flex gap-3 justify-end",children:[m.jsx("button",{className:"nb-btn",onClick:s,type:"button",children:"取消"}),m.jsx("button",{className:o?"nb-btn nb-btn-danger":"nb-btn nb-btn-yellow",onClick:async()=>{await a()},type:"button",children:n})]})]})})}const s1=M.createContext(null);function g2({children:e}){const[t,n]=M.useState(null),a=M.useCallback(c=>new Promise(f=>{n({kind:"confirm",opts:c,resolve:d=>{n(null),f(d)}})}),[]),s=M.useCallback(c=>new Promise(f=>{n({kind:"alert",opts:c,resolve:()=>{n(null),f()}})}),[]),o=M.useCallback(c=>new Promise(f=>{n({kind:"prompt",opts:c,resolve:d=>{n(null),f(d)}})}),[]);return m.jsxs(s1.Provider,{value:{confirm:a,alert:s,prompt:o},children:[e,(t==null?void 0:t.kind)==="confirm"&&m.jsx(p2,{title:t.opts.title,body:t.opts.body,confirm:t.opts.confirm??"确定",danger:t.opts.danger,onConfirm:()=>t.resolve(!0),onCancel:()=>t.resolve(!1)}),(t==null?void 0:t.kind)==="alert"&&m.jsx(b2,{title:t.opts.title,body:t.opts.body,confirm:t.opts.confirm??"知道了",onClose:()=>t.resolve()}),(t==null?void 0:t.kind)==="prompt"&&m.jsx(y2,{title:t.opts.title,body:t.opts.body,placeholder:t.opts.placeholder,defaultValue:t.opts.defaultValue,confirm:t.opts.confirm??"确定",cancel:t.opts.cancel??"取消",onConfirm:c=>t.resolve(c),onCancel:()=>t.resolve(null)})]})}function si(){const e=M.useContext(s1);if(!e)throw new Error("useDialog must be used inside <DialogProvider>");return e}function b2({title:e,body:t,confirm:n,onClose:a}){return M.useEffect(()=>{const s=o=>{(o.key==="Escape"||o.key==="Enter")&&a()};return window.addEventListener("keydown",s),()=>window.removeEventListener("keydown",s)},[a]),m.jsx("div",{role:"dialog","aria-modal":"true",className:"fixed inset-0 z-50 flex items-center justify-center p-6 bg-black/30",children:m.jsxs("div",{className:"nb-card max-w-md w-full",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-xl font-bold mb-2",children:e}),m.jsx("p",{className:"text-sm text-[var(--color-text-muted)] mb-5 whitespace-pre-wrap break-words",children:t}),m.jsx("div",{className:"flex gap-3 justify-end",children:m.jsx("button",{className:"nb-btn nb-btn-primary",onClick:a,type:"button",autoFocus:!0,children:n})})]})})}function y2({title:e,body:t,placeholder:n,defaultValue:a,confirm:s,cancel:o,onConfirm:c,onCancel:f}){const[d,h]=M.useState(a??""),y=M.useRef(null);M.useEffect(()=>{var v,S;(v=y.current)==null||v.focus(),(S=y.current)==null||S.select();const x=w=>{w.key==="Escape"&&f()};return window.addEventListener("keydown",x),()=>window.removeEventListener("keydown",x)},[f]);const g=()=>{const x=d.trim();x&&c(x)};return m.jsx("div",{role:"dialog","aria-modal":"true",className:"fixed inset-0 z-50 flex items-center justify-center p-6 bg-black/30",children:m.jsxs("div",{className:"nb-card max-w-md w-full",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-xl font-bold mb-2",children:e}),t&&m.jsx("p",{className:"text-sm text-[var(--color-text-muted)] mb-3 whitespace-pre-wrap break-words",children:t}),m.jsx("input",{ref:y,type:"text",className:"nb-input w-full mb-5",placeholder:n,value:d,onChange:x=>h(x.target.value),onKeyDown:x=>{x.key==="Enter"&&!x.nativeEvent.isComposing&&(x.preventDefault(),g())}}),m.jsxs("div",{className:"flex gap-3 justify-end",children:[m.jsx("button",{className:"nb-btn",onClick:f,type:"button",children:o}),m.jsx("button",{className:"nb-btn nb-btn-primary",onClick:g,type:"button",disabled:!d.trim(),children:s})]})]})})}function x2(){const e=wr(),t=qn(),{alert:n}=si(),[a,s]=M.useState({name:"",projectDir:"",enableGit:!0,mergeBranch:"main",maxWorkers:"1",ackTimeoutMin:"5"}),o=Pn({mutationFn:d=>YA(d),onSuccess:d=>{t.invalidateQueries({queryKey:["projects"]}),e(`/projects/${encodeURIComponent(d.name)}`)},onError:d=>{n({title:"创建失败",body:d instanceof Error?d.message:String(d)})}}),c=/^[a-zA-Z0-9_-]+$/.test(a.name),f=c&&a.projectDir.trim()!==""&&!o.isPending;return m.jsxs("div",{className:"flex flex-col gap-5 max-w-2xl",children:[m.jsxs("header",{className:"flex items-center gap-3",children:[m.jsxs("button",{type:"button",onClick:()=>e("/projects"),className:"nb-btn",style:{padding:"6px 12px"},"aria-label":"返回项目列表",children:[m.jsx(VE,{size:14,strokeWidth:3}),"返回"]}),m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-3xl font-bold",children:"新建项目"})]}),m.jsx("div",{className:"nb-card",children:m.jsxs("form",{onSubmit:d=>{d.preventDefault(),f&&o.mutate(a)},className:"flex flex-col gap-5",children:[m.jsxs(rr,{label:"项目名",hint:"只能用字母、数字、下划线、连字符。例如 acme-web",children:[m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"例如: acme-web",value:a.name,onChange:d=>s({...a,name:d.target.value}),autoFocus:!0,required:!0}),a.name&&!c&&m.jsx("p",{className:"text-xs text-[var(--color-crashed)] mt-1",children:"名称只能包含 a-z A-Z 0-9 _ -"})]}),m.jsx(rr,{label:"项目目录",hint:"本机绝对路径(代码或文档都可)。和是否启用 git 无关。",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"/home/coral/code/acme",value:a.projectDir,onChange:d=>s({...a,projectDir:d.target.value}),required:!0})}),m.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[m.jsx(rr,{label:"最大 Worker 数",children:m.jsx("input",{type:"number",min:"1",max:"8",className:"nb-input w-full font-[family-name:var(--font-mono)]",value:a.maxWorkers,onChange:d=>s({...a,maxWorkers:d.target.value})})}),m.jsx(rr,{label:"ACK 超时(分钟)",hint:"Worker 启动后多久没 ACK 视为失败",children:m.jsx("input",{type:"number",min:"1",max:"30",className:"nb-input w-full font-[family-name:var(--font-mono)]",value:a.ackTimeoutMin??"5",onChange:d=>s({...a,ackTimeoutMin:d.target.value})})})]}),m.jsxs("div",{className:"pt-3 border-t-2 border-[var(--color-text)] border-dashed",children:[m.jsxs("label",{className:"flex items-center gap-3 mb-3 cursor-pointer select-none",children:[m.jsx("input",{type:"checkbox",checked:a.enableGit??!0,onChange:d=>s({...a,enableGit:d.target.checked}),className:"w-4 h-4 cursor-pointer"}),m.jsx("span",{className:"text-sm font-bold",children:"启用 Git(Worker 自动 commit + push)"})]}),m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] mb-3",children:"关闭后 Worker 只做任务、不做版本控制;适合文档/数据处理等非代码项目。"}),a.enableGit!==!1&&m.jsxs("div",{className:"flex flex-col gap-4 bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-lg p-4",children:[m.jsx(rr,{label:"合并分支",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",value:a.mergeBranch??"main",onChange:d=>s({...a,mergeBranch:d.target.value})})}),m.jsx(rr,{label:"Git 远程项目路径",hint:"如 user/repo,空则跳过远程 API(只本地 commit/push)",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"user/repo",value:a.gitlabProject??"",onChange:d=>s({...a,gitlabProject:d.target.value})})}),a.gitlabProject&&m.jsx(rr,{label:"GitLab 项目 ID",hint:"数字;GitHub 用户留空",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"42",value:a.gitlabProjectId??"",onChange:d=>s({...a,gitlabProjectId:d.target.value})})})]})]}),m.jsxs("div",{className:"pt-3 border-t-2 border-[var(--color-text)] border-dashed",children:[m.jsxs("label",{className:"flex items-center gap-3 mb-3 cursor-pointer select-none",children:[m.jsx("input",{type:"checkbox",checked:a.enableWiki===!0,onChange:d=>s({...a,enableWiki:d.target.checked}),className:"w-4 h-4 cursor-pointer"}),m.jsx("span",{className:"text-sm font-bold",children:"启用 Wiki 知识库(per-project,doc-28)"})]}),m.jsxs("p",{className:"text-xs text-[var(--color-text-muted)]",children:["开启后自动 scaffold ",m.jsx("code",{className:"font-mono",children:"wiki/"})," 目录,并向 Worker prompt 注入 5 层检索上下文与 wiki-update 提示。可后续 ",m.jsx("code",{className:"font-mono",children:"sps wiki init"})," 补办。"]})]}),m.jsxs("div",{className:"pt-3 border-t-2 border-[var(--color-text)] border-dashed",children:[m.jsx("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold uppercase tracking-wider mb-3 text-[var(--color-text-muted)]",children:"通知"}),m.jsx(rr,{label:"Matrix 房间 ID",hint:"空则使用全局配置;不填 = 不通知",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"!abc:matrix.example.com",value:a.matrixRoomId??"",onChange:d=>s({...a,matrixRoomId:d.target.value})})})]}),m.jsxs("div",{className:"flex gap-3 justify-end pt-3",children:[m.jsx("button",{type:"button",className:"nb-btn",onClick:()=>e("/projects"),disabled:o.isPending,children:"取消"}),m.jsx("button",{type:"submit",className:"nb-btn nb-btn-primary",disabled:!f,"aria-label":"创建项目",children:o.isPending?m.jsxs(m.Fragment,{children:[m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}),"创建中…"]}):m.jsxs(m.Fragment,{children:[m.jsx(Xi,{size:14,strokeWidth:3}),"创建"]})})]})]})})]})}function rr({label:e,hint:t,children:n}){return m.jsxs("label",{className:"flex flex-col gap-1.5",children:[m.jsx("span",{className:"text-sm font-bold",children:e}),n,t&&m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:t})]})}const Gp=Symbol.for("yaml.alias"),sp=Symbol.for("yaml.document"),vr=Symbol.for("yaml.map"),l1=Symbol.for("yaml.pair"),Vi=Symbol.for("yaml.scalar"),zl=Symbol.for("yaml.seq"),Si=Symbol.for("yaml.node.type"),kr=e=>!!e&&typeof e=="object"&&e[Si]===Gp,hs=e=>!!e&&typeof e=="object"&&e[Si]===sp,Bl=e=>!!e&&typeof e=="object"&&e[Si]===vr,At=e=>!!e&&typeof e=="object"&&e[Si]===l1,vt=e=>!!e&&typeof e=="object"&&e[Si]===Vi,Ul=e=>!!e&&typeof e=="object"&&e[Si]===zl;function Mt(e){if(e&&typeof e=="object")switch(e[Si]){case vr:case zl:return!0}return!1}function jt(e){if(e&&typeof e=="object")switch(e[Si]){case Gp:case vr:case Vi:case zl:return!0}return!1}const o1=e=>(vt(e)||Mt(e))&&!!e.anchor,$n=Symbol("break visit"),c1=Symbol("skip children"),Yi=Symbol("remove node");function ms(e,t){const n=u1(t);hs(e)?cl(null,e.contents,n,Object.freeze([e]))===Yi&&(e.contents=null):cl(null,e,n,Object.freeze([]))}ms.BREAK=$n;ms.SKIP=c1;ms.REMOVE=Yi;function cl(e,t,n,a){const s=f1(e,t,n,a);if(jt(s)||At(s))return d1(e,a,s),cl(e,s,n,a);if(typeof s!="symbol"){if(Mt(t)){a=Object.freeze(a.concat(t));for(let o=0;o<t.items.length;++o){const c=cl(o,t.items[o],n,a);if(typeof c=="number")o=c-1;else{if(c===$n)return $n;c===Yi&&(t.items.splice(o,1),o-=1)}}}else if(At(t)){a=Object.freeze(a.concat(t));const o=cl("key",t.key,n,a);if(o===$n)return $n;o===Yi&&(t.key=null);const c=cl("value",t.value,n,a);if(c===$n)return $n;c===Yi&&(t.value=null)}}return s}async function Lf(e,t){const n=u1(t);hs(e)?await ul(null,e.contents,n,Object.freeze([e]))===Yi&&(e.contents=null):await ul(null,e,n,Object.freeze([]))}Lf.BREAK=$n;Lf.SKIP=c1;Lf.REMOVE=Yi;async function ul(e,t,n,a){const s=await f1(e,t,n,a);if(jt(s)||At(s))return d1(e,a,s),ul(e,s,n,a);if(typeof s!="symbol"){if(Mt(t)){a=Object.freeze(a.concat(t));for(let o=0;o<t.items.length;++o){const c=await ul(o,t.items[o],n,a);if(typeof c=="number")o=c-1;else{if(c===$n)return $n;c===Yi&&(t.items.splice(o,1),o-=1)}}}else if(At(t)){a=Object.freeze(a.concat(t));const o=await ul("key",t.key,n,a);if(o===$n)return $n;o===Yi&&(t.key=null);const c=await ul("value",t.value,n,a);if(c===$n)return $n;c===Yi&&(t.value=null)}}return s}function u1(e){return typeof e=="object"&&(e.Collection||e.Node||e.Value)?Object.assign({Alias:e.Node,Map:e.Node,Scalar:e.Node,Seq:e.Node},e.Value&&{Map:e.Value,Scalar:e.Value,Seq:e.Value},e.Collection&&{Map:e.Collection,Seq:e.Collection},e):e}function f1(e,t,n,a){var s,o,c,f,d;if(typeof n=="function")return n(e,t,a);if(Bl(t))return(s=n.Map)==null?void 0:s.call(n,e,t,a);if(Ul(t))return(o=n.Seq)==null?void 0:o.call(n,e,t,a);if(At(t))return(c=n.Pair)==null?void 0:c.call(n,e,t,a);if(vt(t))return(f=n.Scalar)==null?void 0:f.call(n,e,t,a);if(kr(t))return(d=n.Alias)==null?void 0:d.call(n,e,t,a)}function d1(e,t,n){const a=t[t.length-1];if(Mt(a))a.items[e]=n;else if(At(a))e==="key"?a.key=n:a.value=n;else if(hs(a))a.contents=n;else{const s=kr(a)?"alias":"scalar";throw new Error(`Cannot replace node with ${s} parent`)}}const v2={"!":"%21",",":"%2C","[":"%5B","]":"%5D","{":"%7B","}":"%7D"},E2=e=>e.replace(/[!,[\]{}]/g,t=>v2[t]);class Nn{constructor(t,n){this.docStart=null,this.docEnd=!1,this.yaml=Object.assign({},Nn.defaultYaml,t),this.tags=Object.assign({},Nn.defaultTags,n)}clone(){const t=new Nn(this.yaml,this.tags);return t.docStart=this.docStart,t}atDocument(){const t=new Nn(this.yaml,this.tags);switch(this.yaml.version){case"1.1":this.atNextDocument=!0;break;case"1.2":this.atNextDocument=!1,this.yaml={explicit:Nn.defaultYaml.explicit,version:"1.2"},this.tags=Object.assign({},Nn.defaultTags);break}return t}add(t,n){this.atNextDocument&&(this.yaml={explicit:Nn.defaultYaml.explicit,version:"1.1"},this.tags=Object.assign({},Nn.defaultTags),this.atNextDocument=!1);const a=t.trim().split(/[ \t]+/),s=a.shift();switch(s){case"%TAG":{if(a.length!==2&&(n(0,"%TAG directive should contain exactly two parts"),a.length<2))return!1;const[o,c]=a;return this.tags[o]=c,!0}case"%YAML":{if(this.yaml.explicit=!0,a.length!==1)return n(0,"%YAML directive should contain exactly one part"),!1;const[o]=a;if(o==="1.1"||o==="1.2")return this.yaml.version=o,!0;{const c=/^\d+\.\d+$/.test(o);return n(6,`Unsupported YAML version ${o}`,c),!1}}default:return n(0,`Unknown directive ${s}`,!0),!1}}tagName(t,n){if(t==="!")return"!";if(t[0]!=="!")return n(`Not a valid tag: ${t}`),null;if(t[1]==="<"){const c=t.slice(2,-1);return c==="!"||c==="!!"?(n(`Verbatim tags aren't resolved, so ${t} is invalid.`),null):(t[t.length-1]!==">"&&n("Verbatim tags must end with a >"),c)}const[,a,s]=t.match(/^(.*!)([^!]*)$/s);s||n(`The ${t} tag has no suffix`);const o=this.tags[a];if(o)try{return o+decodeURIComponent(s)}catch(c){return n(String(c)),null}return a==="!"?t:(n(`Could not resolve tag: ${t}`),null)}tagString(t){for(const[n,a]of Object.entries(this.tags))if(t.startsWith(a))return n+E2(t.substring(a.length));return t[0]==="!"?t:`!<${t}>`}toString(t){const n=this.yaml.explicit?[`%YAML ${this.yaml.version||"1.2"}`]:[],a=Object.entries(this.tags);let s;if(t&&a.length>0&&jt(t.contents)){const o={};ms(t.contents,(c,f)=>{jt(f)&&f.tag&&(o[f.tag]=!0)}),s=Object.keys(o)}else s=[];for(const[o,c]of a)o==="!!"&&c==="tag:yaml.org,2002:"||(!t||s.some(f=>f.startsWith(c)))&&n.push(`%TAG ${o} ${c}`);return n.join(`
336
336
  `)}}Nn.defaultYaml={explicit:!1,version:"1.2"};Nn.defaultTags={"!!":"tag:yaml.org,2002:"};function h1(e){if(/[\x00-\x19\s,[\]{}]/.test(e)){const n=`Anchor must not contain whitespace or control characters: ${JSON.stringify(e)}`;throw new Error(n)}return!0}function m1(e){const t=new Set;return ms(e,{Value(n,a){a.anchor&&t.add(a.anchor)}}),t}function p1(e,t){for(let n=1;;++n){const a=`${e}${n}`;if(!t.has(a))return a}}function S2(e,t){const n=[],a=new Map;let s=null;return{onAnchor:o=>{n.push(o),s??(s=m1(e));const c=p1(t,s);return s.add(c),c},setAnchors:()=>{for(const o of n){const c=a.get(o);if(typeof c=="object"&&c.anchor&&(vt(c.node)||Mt(c.node)))c.node.anchor=c.anchor;else{const f=new Error("Failed to resolve repeated object (this should not happen)");throw f.source=o,f}}},sourceObjects:a}}function fl(e,t,n,a){if(a&&typeof a=="object")if(Array.isArray(a))for(let s=0,o=a.length;s<o;++s){const c=a[s],f=fl(e,a,String(s),c);f===void 0?delete a[s]:f!==c&&(a[s]=f)}else if(a instanceof Map)for(const s of Array.from(a.keys())){const o=a.get(s),c=fl(e,a,s,o);c===void 0?a.delete(s):c!==o&&a.set(s,c)}else if(a instanceof Set)for(const s of Array.from(a)){const o=fl(e,a,s,s);o===void 0?a.delete(s):o!==s&&(a.delete(s),a.add(o))}else for(const[s,o]of Object.entries(a)){const c=fl(e,a,s,o);c===void 0?delete a[s]:c!==o&&(a[s]=c)}return e.call(t,n,a)}function vi(e,t,n){if(Array.isArray(e))return e.map((a,s)=>vi(a,String(s),n));if(e&&typeof e.toJSON=="function"){if(!n||!o1(e))return e.toJSON(t,n);const a={aliasCount:0,count:1,res:void 0};n.anchors.set(e,a),n.onCreate=o=>{a.res=o,delete n.onCreate};const s=e.toJSON(t,n);return n.onCreate&&n.onCreate(s),s}return typeof e=="bigint"&&!(n!=null&&n.keep)?Number(e):e}class Qp{constructor(t){Object.defineProperty(this,Si,{value:t})}clone(){const t=Object.create(Object.getPrototypeOf(this),Object.getOwnPropertyDescriptors(this));return this.range&&(t.range=this.range.slice()),t}toJS(t,{mapAsMap:n,maxAliasCount:a,onAnchor:s,reviver:o}={}){if(!hs(t))throw new TypeError("A document argument is required");const c={anchors:new Map,doc:t,keep:!0,mapAsMap:n===!0,mapKeyWarned:!1,maxAliasCount:typeof a=="number"?a:100},f=vi(this,"",c);if(typeof s=="function")for(const{count:d,res:h}of c.anchors.values())s(h,d);return typeof o=="function"?fl(o,{"":f},"",f):f}}class If extends Qp{constructor(t){super(Gp),this.source=t,Object.defineProperty(this,"tag",{set(){throw new Error("Alias nodes cannot have tags")}})}resolve(t,n){let a;n!=null&&n.aliasResolveCache?a=n.aliasResolveCache:(a=[],ms(t,{Node:(o,c)=>{(kr(c)||o1(c))&&a.push(c)}}),n&&(n.aliasResolveCache=a));let s;for(const o of a){if(o===this)break;o.anchor===this.source&&(s=o)}return s}toJSON(t,n){if(!n)return{source:this.source};const{anchors:a,doc:s,maxAliasCount:o}=n,c=this.resolve(s,n);if(!c){const d=`Unresolved alias (the anchor must be set before the alias): ${this.source}`;throw new ReferenceError(d)}let f=a.get(c);if(f||(vi(c,null,n),f=a.get(c)),(f==null?void 0:f.res)===void 0){const d="This should not happen: Alias anchor was not resolved?";throw new ReferenceError(d)}if(o>=0&&(f.count+=1,f.aliasCount===0&&(f.aliasCount=uf(s,c,a)),f.count*f.aliasCount>o)){const d="Excessive alias count indicates a resource exhaustion attack";throw new ReferenceError(d)}return f.res}toString(t,n,a){const s=`*${this.source}`;if(t){if(h1(this.source),t.options.verifyAliasOrder&&!t.anchors.has(this.source)){const o=`Unresolved alias (the anchor must be set before the alias): ${this.source}`;throw new Error(o)}if(t.implicitKey)return`${s} `}return s}}function uf(e,t,n){if(kr(t)){const a=t.resolve(e),s=n&&a&&n.get(a);return s?s.count*s.aliasCount:0}else if(Mt(t)){let a=0;for(const s of t.items){const o=uf(e,s,n);o>a&&(a=o)}return a}else if(At(t)){const a=uf(e,t.key,n),s=uf(e,t.value,n);return Math.max(a,s)}return 1}const g1=e=>!e||typeof e!="function"&&typeof e!="object";class ze extends Qp{constructor(t){super(Vi),this.value=t}toJSON(t,n){return n!=null&&n.keep?this.value:vi(this.value,t,n)}toString(){return String(this.value)}}ze.BLOCK_FOLDED="BLOCK_FOLDED";ze.BLOCK_LITERAL="BLOCK_LITERAL";ze.PLAIN="PLAIN";ze.QUOTE_DOUBLE="QUOTE_DOUBLE";ze.QUOTE_SINGLE="QUOTE_SINGLE";const w2="tag:yaml.org,2002:";function _2(e,t,n){if(t){const a=n.filter(o=>o.tag===t),s=a.find(o=>!o.format)??a[0];if(!s)throw new Error(`Tag ${t} not found`);return s}return n.find(a=>{var s;return((s=a.identify)==null?void 0:s.call(a,e))&&!a.format})}function sc(e,t,n){var g,x,v;if(hs(e)&&(e=e.contents),jt(e))return e;if(At(e)){const S=(x=(g=n.schema[vr]).createNode)==null?void 0:x.call(g,n.schema,null,n);return S.items.push(e),S}(e instanceof String||e instanceof Number||e instanceof Boolean||typeof BigInt<"u"&&e instanceof BigInt)&&(e=e.valueOf());const{aliasDuplicateObjects:a,onAnchor:s,onTagObj:o,schema:c,sourceObjects:f}=n;let d;if(a&&e&&typeof e=="object"){if(d=f.get(e),d)return d.anchor??(d.anchor=s(e)),new If(d.anchor);d={anchor:null,node:null},f.set(e,d)}t!=null&&t.startsWith("!!")&&(t=w2+t.slice(2));let h=_2(e,t,c.tags);if(!h){if(e&&typeof e.toJSON=="function"&&(e=e.toJSON()),!e||typeof e!="object"){const S=new ze(e);return d&&(d.node=S),S}h=e instanceof Map?c[vr]:Symbol.iterator in Object(e)?c[zl]:c[vr]}o&&(o(h),delete n.onTagObj);const y=h!=null&&h.createNode?h.createNode(n.schema,e,n):typeof((v=h==null?void 0:h.nodeClass)==null?void 0:v.from)=="function"?h.nodeClass.from(n.schema,e,n):new ze(e);return t?y.tag=t:h.default||(y.tag=h.tag),d&&(d.node=y),y}function vf(e,t,n){let a=n;for(let s=t.length-1;s>=0;--s){const o=t[s];if(typeof o=="number"&&Number.isInteger(o)&&o>=0){const c=[];c[o]=a,a=c}else a=new Map([[o,a]])}return sc(a,void 0,{aliasDuplicateObjects:!1,keepUndefined:!1,onAnchor:()=>{throw new Error("This should not happen, please report a bug.")},schema:e,sourceObjects:new Map})}const Zo=e=>e==null||typeof e=="object"&&!!e[Symbol.iterator]().next().done;class b1 extends Qp{constructor(t,n){super(t),Object.defineProperty(this,"schema",{value:n,configurable:!0,enumerable:!1,writable:!0})}clone(t){const n=Object.create(Object.getPrototypeOf(this),Object.getOwnPropertyDescriptors(this));return t&&(n.schema=t),n.items=n.items.map(a=>jt(a)||At(a)?a.clone(t):a),this.range&&(n.range=this.range.slice()),n}addIn(t,n){if(Zo(t))this.add(n);else{const[a,...s]=t,o=this.get(a,!0);if(Mt(o))o.addIn(s,n);else if(o===void 0&&this.schema)this.set(a,vf(this.schema,s,n));else throw new Error(`Expected YAML collection at ${a}. Remaining path: ${s}`)}}deleteIn(t){const[n,...a]=t;if(a.length===0)return this.delete(n);const s=this.get(n,!0);if(Mt(s))return s.deleteIn(a);throw new Error(`Expected YAML collection at ${n}. Remaining path: ${a}`)}getIn(t,n){const[a,...s]=t,o=this.get(a,!0);return s.length===0?!n&&vt(o)?o.value:o:Mt(o)?o.getIn(s,n):void 0}hasAllNullValues(t){return this.items.every(n=>{if(!At(n))return!1;const a=n.value;return a==null||t&&vt(a)&&a.value==null&&!a.commentBefore&&!a.comment&&!a.tag})}hasIn(t){const[n,...a]=t;if(a.length===0)return this.has(n);const s=this.get(n,!0);return Mt(s)?s.hasIn(a):!1}setIn(t,n){const[a,...s]=t;if(s.length===0)this.set(a,n);else{const o=this.get(a,!0);if(Mt(o))o.setIn(s,n);else if(o===void 0&&this.schema)this.set(a,vf(this.schema,s,n));else throw new Error(`Expected YAML collection at ${a}. Remaining path: ${s}`)}}}const k2=e=>e.replace(/^(?!$)(?: $)?/gm,"#");function ka(e,t){return/^\n+$/.test(e)?e.substring(1):t?e.replace(/^(?! *$)/gm,t):e}const Zr=(e,t,n)=>e.endsWith(`
337
337
  `)?ka(n,t):n.includes(`
338
338
  `)?`
@@ -472,9 +472,9 @@ ${n.comment}`:n.comment}this.doc.range[2]=n.offset;break}default:this.errors.pus
472
472
  `)+1;for(;n!==0;)this.onNewLine(this.offset+n),n=this.source.indexOf(`
473
473
  `,n)+1}return{type:t,offset:this.offset,indent:this.indent,source:this.source}}startBlockValue(t){switch(this.type){case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":return this.flowScalar(this.type);case"block-scalar-header":return{type:"block-scalar",offset:this.offset,indent:this.indent,props:[this.sourceToken],source:""};case"flow-map-start":case"flow-seq-start":return{type:"flow-collection",offset:this.offset,indent:this.indent,start:this.sourceToken,items:[],end:[]};case"seq-item-ind":return{type:"block-seq",offset:this.offset,indent:this.indent,items:[{start:[this.sourceToken]}]};case"explicit-key-ind":{this.onKeyLine=!0;const n=Vu(t),a=il(n);return a.push(this.sourceToken),{type:"block-map",offset:this.offset,indent:this.indent,items:[{start:a,explicitKey:!0}]}}case"map-value-ind":{this.onKeyLine=!0;const n=Vu(t),a=il(n);return{type:"block-map",offset:this.offset,indent:this.indent,items:[{start:a,key:null,sep:[this.sourceToken]}]}}}return null}atIndentedComment(t,n){return this.type!=="comment"||this.indent<=n?!1:t.every(a=>a.type==="newline"||a.type==="space")}*documentEnd(t){this.type!=="doc-mode"&&(t.end?t.end.push(this.sourceToken):t.end=[this.sourceToken],this.type==="newline"&&(yield*this.pop()))}*lineEnd(t){switch(this.type){case"comma":case"doc-start":case"doc-end":case"flow-seq-end":case"flow-map-end":case"map-value-ind":yield*this.pop(),yield*this.step();break;case"newline":this.onKeyLine=!1;case"space":case"comment":default:t.end?t.end.push(this.sourceToken):t.end=[this.sourceToken],this.type==="newline"&&(yield*this.pop())}}}function tS(e){const t=e.prettyErrors!==!1;return{lineCounter:e.lineCounter||t&&new J1||null,prettyErrors:t}}function kO(e,t={}){const{lineCounter:n,prettyErrors:a}=tS(t),s=new sg(n==null?void 0:n.addNewLine),o=new rg(t),c=Array.from(o.compose(s.parse(e)));if(a&&n)for(const f of c)f.errors.forEach(Sf(e,n)),f.warnings.forEach(Sf(e,n));return c.length>0?c:Object.assign([],{empty:!0},o.streamInfo())}function nS(e,t={}){const{lineCounter:n,prettyErrors:a}=tS(t),s=new sg(n==null?void 0:n.addNewLine),o=new rg(t);let c=null;for(const f of o.compose(s.parse(e),!0,e.length))if(!c)c=f;else if(c.options.logLevel!=="silent"){c.errors.push(new Jr(f.range.slice(0,2),"MULTIPLE_DOCS","Source contains multiple documents; please use YAML.parseAllDocuments()"));break}return a&&n&&(c.errors.forEach(Sf(e,n)),c.warnings.forEach(Sf(e,n))),c}function NO(e,t,n){let a;typeof t=="function"?a=t:n===void 0&&t&&typeof t=="object"&&(n=t);const s=nS(e,n);if(!s)return null;if(s.warnings.forEach(o=>v1(s.options.logLevel,o)),s.errors.length>0){if(s.options.logLevel!=="silent")throw s.errors[0];s.errors=[]}return s.toJS(Object.assign({reviver:a},n))}function TO(e,t,n){let a=null;if(typeof t=="function"||Array.isArray(t)?a=t:n===void 0&&t&&(n=t),typeof n=="string"&&(n=n.length),typeof n=="number"){const s=Math.round(n);n=s<1?void 0:s>8?{indent:8}:{indent:s}}if(e===void 0){const{keepUndefined:s}=n??t??{};if(!s)return}return hs(e)&&!a?e.toString(n):new Pl(e,a,n).toString(n)}const Wv=Object.freeze(Object.defineProperty({__proto__:null,Alias:If,CST:SO,Composer:rg,Document:Pl,Lexer:W1,LineCounter:J1,Pair:gn,Parser:sg,Scalar:ze,Schema:U1,YAMLError:ig,YAMLMap:ii,YAMLParseError:Jr,YAMLSeq:Sr,YAMLWarning:$1,isAlias:kr,isCollection:Mt,isDocument:hs,isMap:Bl,isNode:jt,isPair:At,isScalar:vt,isSeq:Ul,parse:NO,parseAllDocuments:kO,parseDocument:nS,stringify:TO,visit:ms,visitAsync:Lf},Symbol.toStringTag,{value:"Module"}));function CO({projectName:e,file:t,onClose:n,onSaved:a}){const s=qn(),{alert:o}=si(),{data:c,isLoading:f,isError:d,error:h,refetch:y}=lt({queryKey:["pipeline-file",e,t],queryFn:()=>e2(e,t)}),[g,x]=M.useState("structured"),[v,S]=M.useState(null),[w,k]=M.useState(null);M.useEffect(()=>{c&&v===null&&(S(c.content),k(c.etag),c.parseError&&x("yaml"))},[c,v]),M.useEffect(()=>{const j=q=>{q.key==="Escape"&&n()};return window.addEventListener("keydown",j),()=>window.removeEventListener("keydown",j)},[n]);const _=Pn({mutationFn:()=>{if(v===null||w===null)throw new Error("no draft");return t2(e,t,v,w)},onSuccess:j=>{k(j.etag),s.invalidateQueries({queryKey:["pipeline-file",e,t]}),s.invalidateQueries({queryKey:["project-pipelines",e]}),a()},onError:j=>{const q=j.status;o({title:q===409?"文件已被其他地方修改":q===422?"YAML 语法错":"保存失败",body:j instanceof Error?j.message:String(j)})}}),A=v!==null&&c&&v!==c.content,{parsed:T,parseError:D}=M.useMemo(()=>{if(v===null)return{parsed:null,parseError:null};try{return{parsed:Wv.parse(v)??{},parseError:null}}catch(j){return{parsed:null,parseError:j instanceof Error?j.message:String(j)}}},[v]),$=j=>{try{const q=Wv.stringify(j,{lineWidth:0});S(q)}catch(q){o({title:"YAML 序列化失败",body:q instanceof Error?q.message:String(q)})}};return m.jsx("div",{role:"dialog","aria-modal":"true",className:"fixed inset-0 z-40 flex items-start justify-center p-6 bg-black/30 overflow-auto",children:m.jsxs("div",{className:"nb-card mt-8 w-full max-w-4xl flex flex-col",style:{maxHeight:"calc(100vh - 64px)"},children:[m.jsxs("header",{className:"flex items-start justify-between gap-3 mb-3 flex-shrink-0",children:[m.jsxs("div",{children:[m.jsxs("h2",{className:"font-[family-name:var(--font-heading)] text-2xl font-bold flex items-center gap-2",children:[m.jsx(Fv,{size:20,strokeWidth:2.5}),m.jsx("code",{className:"font-[family-name:var(--font-mono)] text-lg",children:t}),(c==null?void 0:c.isActive)&&m.jsx("span",{className:"nb-status",style:{background:"var(--color-running-bg)",color:"var(--color-running)",padding:"2px 8px"},children:"active"})]}),m.jsxs("p",{className:"text-xs text-[var(--color-text-muted)] font-[family-name:var(--font-mono)] mt-1",children:[e,"/pipelines/",t,w&&` · etag ${w}`]})]}),m.jsx("button",{className:"nb-btn nb-btn-mint p-2",onClick:n,type:"button","aria-label":"关闭",children:m.jsx(Er,{size:14,strokeWidth:3})})]}),f&&m.jsx("p",{className:"text-[var(--color-text-muted)]",children:"加载中…"}),d&&m.jsxs("p",{className:"text-[var(--color-crashed)]",children:["加载失败: ",h instanceof Error?h.message:String(h)]}),c&&v!==null&&m.jsxs(m.Fragment,{children:[m.jsxs("div",{className:"flex items-center gap-3 mb-3 flex-shrink-0 flex-wrap",children:[m.jsxs("div",{className:"flex gap-1 p-1 bg-[var(--color-bg)] border-[2px] border-[var(--color-text)] rounded-full shadow-[2px_2px_0_var(--color-text)]",children:[m.jsxs("button",{type:"button",onClick:()=>x("structured"),"aria-pressed":g==="structured",disabled:!!D,className:["px-3 py-1 rounded-full text-xs font-bold flex items-center gap-1.5",g==="structured"?"bg-[var(--color-primary)] text-[var(--color-text)] shadow-[1px_1px_0_var(--color-text)]":"text-[var(--color-text-muted)]",D?"opacity-50 cursor-not-allowed":""].join(" "),title:D??void 0,children:[m.jsx(qp,{size:11,strokeWidth:2.5}),"结构化"]}),m.jsxs("button",{type:"button",onClick:()=>x("yaml"),"aria-pressed":g==="yaml",className:["px-3 py-1 rounded-full text-xs font-bold flex items-center gap-1.5",g==="yaml"?"bg-[var(--color-primary)] text-[var(--color-text)] shadow-[1px_1px_0_var(--color-text)]":"text-[var(--color-text-muted)]"].join(" "),children:[m.jsx(Fv,{size:11,strokeWidth:2.5}),"原始 YAML"]})]}),D&&m.jsxs("div",{className:"flex items-center gap-1 text-xs text-[var(--color-crashed)] font-bold",children:[m.jsx(rc,{size:12,strokeWidth:2.5}),"YAML parse: ",D]}),(c==null?void 0:c.isActive)&&m.jsx("span",{className:"text-xs text-[var(--color-stuck)] font-bold ml-auto",children:"⚠ 这是当前激活的 pipeline,保存后下一轮 tick 生效"})]}),m.jsxs("div",{className:"flex-1 overflow-auto",children:[g==="structured"&&T&&m.jsx(AO,{parsed:T,onChange:$}),g==="yaml"&&m.jsx("textarea",{className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",style:{minHeight:400,resize:"vertical"},value:v,onChange:j=>S(j.target.value),spellCheck:!1,"aria-label":"pipeline YAML 编辑器"})]}),m.jsxs("div",{className:"flex items-center justify-between mt-3 pt-3 border-t-2 border-dashed border-[var(--color-text)] flex-shrink-0",children:[m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:A?m.jsx("span",{className:"text-[var(--color-stuck)] font-bold",children:"● 未保存"}):_.isSuccess?m.jsxs("span",{className:"text-[var(--color-running)] font-bold flex items-center gap-1",children:[m.jsx(Pp,{size:12,strokeWidth:2.5})," 已保存"]}):"无变化"}),m.jsxs("div",{className:"flex gap-2",children:[m.jsx("button",{className:"nb-btn",style:{padding:"6px 14px"},onClick:()=>{S(null),y()},disabled:_.isPending,type:"button",children:"重新加载"}),m.jsxs("button",{className:"nb-btn nb-btn-primary",style:{padding:"6px 14px"},onClick:()=>_.mutate(),disabled:!A||_.isPending,type:"button","aria-label":"保存 pipeline",children:[_.isPending?m.jsx(Wt,{size:13,strokeWidth:3,className:"animate-spin"}):m.jsx(Df,{size:13,strokeWidth:3}),"保存"]})]})]})]})]})})}function AO({parsed:e,onChange:t}){const n=e.stages??[],a=d=>{t({...e,stages:d})},s=()=>{a([...n,{name:`stage-${n.length+1}`,on_complete:"move_card Done"}])},o=d=>{a(n.filter((h,y)=>y!==d))},c=(d,h)=>{const y=[...n],g=d+h;g<0||g>=y.length||([y[d],y[g]]=[y[g],y[d]],a(y))},f=(d,h)=>{a(n.map((y,g)=>g===d?{...y,...h}:y))};return m.jsxs("div",{className:"flex flex-col gap-4",children:[m.jsxs("div",{className:"flex items-center gap-3 p-3 bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-lg",children:[m.jsxs("label",{className:"flex items-center gap-2 text-sm",children:[m.jsx("span",{className:"font-bold",children:"mode:"}),m.jsxs("select",{className:"nb-input",style:{padding:"4px 10px",fontSize:12},value:e.mode??"project",onChange:d=>t({...e,mode:d.target.value}),children:[m.jsx("option",{value:"project",children:"project"}),m.jsx("option",{value:"steps",children:"steps"})]})]}),m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:"project = 事件驱动流水线(默认) · steps = 顺序脚本"})]}),m.jsxs("div",{children:[m.jsxs("div",{className:"flex items-center justify-between mb-2",children:[m.jsxs("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold uppercase tracking-wider",children:["Stages (",n.length,")"]}),m.jsxs("button",{type:"button",className:"nb-btn nb-btn-mint",style:{padding:"4px 12px",fontSize:12},onClick:s,"aria-label":"添加 stage",children:[m.jsx(Xi,{size:11,strokeWidth:3})," 添加 stage"]})]}),n.length===0?m.jsx("p",{className:"text-sm text-[var(--color-text-muted)] italic p-4 border-2 border-dashed border-[var(--color-text)] rounded-lg text-center",children:'还没 stage。点"添加 stage"开始。'}):m.jsx("div",{className:"flex flex-col gap-3",children:n.map((d,h)=>m.jsx(OO,{stage:d,index:h,total:n.length,onChange:y=>f(h,y),onRemove:()=>o(h),onMoveUp:()=>c(h,-1),onMoveDown:()=>c(h,1)},h))})]})]})}function OO({stage:e,index:t,total:n,onChange:a,onRemove:s,onMoveUp:o,onMoveDown:c}){const f=e.on_fail??{};return m.jsxs("div",{className:"nb-card bg-[var(--color-bg-cream)] p-4",children:[m.jsxs("div",{className:"flex items-center justify-between mb-3",children:[m.jsxs("h4",{className:"font-[family-name:var(--font-heading)] font-bold text-sm",children:["Stage #",t+1,e.name&&m.jsx("code",{className:"ml-2 text-xs font-[family-name:var(--font-mono)] bg-[var(--color-bg)] border-2 border-[var(--color-text)] px-2 py-0.5 rounded",children:e.name})]}),m.jsxs("div",{className:"flex gap-1",children:[m.jsx("button",{type:"button",className:"nb-btn",style:{padding:"3px 8px"},onClick:o,disabled:t===0,"aria-label":"上移",children:m.jsx(kC,{size:12,strokeWidth:3})}),m.jsx("button",{type:"button",className:"nb-btn",style:{padding:"3px 8px"},onClick:c,disabled:t===n-1,"aria-label":"下移",children:m.jsx(yc,{size:12,strokeWidth:3})}),m.jsx("button",{type:"button",className:"nb-btn nb-btn-danger",style:{padding:"3px 8px"},onClick:s,"aria-label":"删除 stage",children:m.jsx(Il,{size:12,strokeWidth:3})})]})]}),m.jsxs("div",{className:"grid grid-cols-2 gap-3 text-sm",children:[m.jsx(sr,{label:"name",hint:"stage 唯一名",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",value:e.name??"",onChange:d=>a({name:d.target.value}),placeholder:"develop"})}),m.jsx(sr,{label:"profile",hint:"skill 画像,可空",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",value:e.profile??"",onChange:d=>a({profile:d.target.value||void 0}),placeholder:"fullstack"})}),m.jsx(sr,{label:"card_state",hint:"本 stage 期间卡片状态",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",value:e.card_state??"",onChange:d=>a({card_state:d.target.value||void 0}),placeholder:"Inprogress"})}),m.jsx(sr,{label:"timeout",hint:"可选,如 30m 2h",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",value:e.timeout??"",onChange:d=>a({timeout:d.target.value||void 0}),placeholder:"2h"})}),m.jsx(sr,{label:"trigger",hint:"触发条件,可空走默认",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",value:e.trigger??"",onChange:d=>a({trigger:d.target.value||void 0}),placeholder:"card_enters 'Todo'"})}),m.jsx(sr,{label:"on_complete",hint:"成功后动作",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",value:e.on_complete??"",onChange:d=>a({on_complete:d.target.value}),placeholder:"move_card Done"})})]}),m.jsxs("div",{className:"mt-4 pt-3 border-t-2 border-dashed border-[var(--color-text)]",children:[m.jsx("h5",{className:"text-xs font-bold uppercase tracking-wider mb-2 text-[var(--color-text-muted)]",children:"on_fail"}),m.jsxs("div",{className:"grid grid-cols-2 gap-3 text-sm",children:[m.jsx(sr,{label:"action",hint:"失败时动作,如 label NEEDS-FIX",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",value:f.action??"",onChange:d=>a({on_fail:{...f,action:d.target.value||void 0}}),placeholder:"label NEEDS-FIX"})}),m.jsx(sr,{label:"comment",hint:"写进卡片的注释",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",value:f.comment??"",onChange:d=>a({on_fail:{...f,comment:d.target.value||void 0}}),placeholder:"Worker failed. Check logs."})})]}),m.jsxs("label",{className:"flex items-center gap-2 mt-3 text-sm cursor-pointer",children:[m.jsx("input",{type:"checkbox",checked:f.halt??!0,onChange:d=>a({on_fail:{...f,halt:d.target.checked}})}),m.jsx("span",{className:"font-bold",children:"halt"}),m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:"(失败后停流水线;去掉则继续下一张卡)"})]})]})]})}function sr({label:e,hint:t,children:n}){return m.jsxs("label",{className:"flex flex-col gap-1",children:[m.jsx("span",{className:"text-xs font-bold font-[family-name:var(--font-mono)]",children:e}),n,t&&m.jsx("span",{className:"text-[10px] text-[var(--color-text-muted)]",children:t})]})}function RO({onCancel:e,onCreate:t,hasActive:n,hasSample:a,isPending:s}){const[o,c]=M.useState(""),[f,d]=M.useState("blank");M.useEffect(()=>{const v=S=>{S.key==="Escape"&&e()};return window.addEventListener("keydown",v),()=>window.removeEventListener("keydown",v)},[e]);const h=o.trim(),y=h.endsWith(".yaml")?h:h?`${h}.yaml`:"",g=y&&/^[a-zA-Z0-9_.-]+\.yaml$/.test(y),x=()=>{!g||s||t(y,f)};return m.jsx("div",{role:"dialog","aria-modal":"true",className:"fixed inset-0 z-50 flex items-center justify-center p-6 bg-black/30",children:m.jsxs("div",{className:"nb-card max-w-md w-full",children:[m.jsxs("header",{className:"flex items-start justify-between mb-4",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-xl font-bold",children:"新建 pipeline"}),m.jsx("button",{className:"nb-btn nb-btn-mint p-2",onClick:e,type:"button","aria-label":"关闭",children:m.jsx(Er,{size:14,strokeWidth:3})})]}),m.jsxs("form",{onSubmit:v=>{v.preventDefault(),x()},className:"flex flex-col gap-4",children:[m.jsxs("label",{className:"flex flex-col gap-1.5",children:[m.jsx("span",{className:"text-sm font-bold",children:"文件名"}),m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"例如 ci",value:o,onChange:v=>c(v.target.value),autoFocus:!0}),m.jsxs("span",{className:"text-xs text-[var(--color-text-muted)]",children:["实际会保存为 ",m.jsx("code",{className:"font-[family-name:var(--font-mono)]",children:y||"xxx.yaml"}),"。 只允许 a-z A-Z 0-9 _ -;已有同名文件会 409 报错。"]})]}),m.jsxs("fieldset",{className:"flex flex-col gap-2",children:[m.jsx("legend",{className:"text-sm font-bold mb-1",children:"初始内容"}),m.jsx(xm,{value:"blank",current:f,label:"空白模板",desc:"最简 1 stage (develop → Done)",onSelect:d}),m.jsx(xm,{value:"sample",current:f,label:"教学模板",desc:"从 sample.yaml.example 复制(带注释,讲解所有字段)",onSelect:d,disabled:!a,disabledReason:"sample.yaml.example 不存在"}),m.jsx(xm,{value:"active",current:f,label:"复制当前活动的",desc:"从 project.yaml 复制(基于目前的配置改)",onSelect:d,disabled:!n,disabledReason:"project.yaml 不存在"})]}),m.jsxs("div",{className:"flex gap-3 justify-end pt-2",children:[m.jsx("button",{className:"nb-btn",onClick:e,type:"button",disabled:s,children:"取消"}),m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"submit",disabled:!g||s,"aria-label":"创建 pipeline",children:[s?m.jsx(Wt,{size:13,strokeWidth:3,className:"animate-spin"}):m.jsx(Xi,{size:13,strokeWidth:3}),"创建"]})]})]})]})})}function xm({value:e,current:t,label:n,desc:a,onSelect:s,disabled:o,disabledReason:c}){const f=t===e;return m.jsxs("label",{className:["flex items-start gap-2 p-2 rounded-lg border-2 cursor-pointer",o?"border-[var(--color-border-light)] opacity-50 cursor-not-allowed":f?"bg-[var(--color-accent-mint)] border-[var(--color-text)] shadow-[2px_2px_0_var(--color-text)]":"border-[var(--color-border-light)] hover:bg-[var(--color-bg-cream)] hover:border-[var(--color-text)]"].join(" "),children:[m.jsx("input",{type:"radio",name:"pipeline-template",value:e,checked:f,disabled:o,onChange:()=>s(e),className:"mt-1 flex-shrink-0"}),m.jsxs("div",{className:"flex-1",children:[m.jsx("div",{className:"text-sm font-bold",children:n}),m.jsx("div",{className:"text-xs text-[var(--color-text-muted)]",children:o?c:a})]})]})}function MO(){var o;const{name:e=""}=UE(),t=wr(),[n,a]=M.useState("overview"),s=lt({queryKey:["project",e],queryFn:()=>QA(e),enabled:!!e});return m.jsxs("div",{className:"flex flex-col gap-5 max-w-4xl",children:[m.jsxs("header",{className:"flex items-center gap-3",children:[m.jsxs("button",{type:"button",onClick:()=>t("/projects"),className:"nb-btn",style:{padding:"6px 12px"},"aria-label":"返回项目列表",children:[m.jsx(VE,{size:14,strokeWidth:3}),"返回"]}),m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-3xl font-bold flex-1",children:e}),m.jsx(ds,{to:`/board?project=${encodeURIComponent(e)}`,className:"nb-btn nb-btn-mint",children:"看板"})]}),m.jsxs("nav",{className:"flex gap-2 flex-wrap",children:[m.jsx(Xu,{current:n,value:"overview",onSelect:a,icon:$C,children:"概览"}),m.jsx(Xu,{current:n,value:"config",onSelect:a,icon:JE,children:"配置"}),m.jsx(Xu,{current:n,value:"pipelines",onSelect:a,icon:i1,children:"Pipelines"}),m.jsx(Xu,{current:n,value:"danger",onSelect:a,icon:Il,children:"危险操作"})]}),n==="overview"&&m.jsx(jO,{name:e,data:s.data,loading:s.isLoading}),n==="config"&&m.jsx(DO,{name:e}),n==="pipelines"&&m.jsx(LO,{name:e}),n==="danger"&&m.jsx(IO,{name:e,repoDir:((o=s.data)==null?void 0:o.repoDir)??null})]})}function Xu({current:e,value:t,onSelect:n,icon:a,children:s}){const o=e===t;return m.jsxs("button",{type:"button",onClick:()=>n(t),"aria-current":o?"page":void 0,className:["nb-btn",o?"nb-btn-primary":""].join(" "),style:{padding:"6px 14px",fontSize:13},children:[m.jsx(a,{size:13,strokeWidth:2.5}),s]})}function jO({name:e,data:t,loading:n}){return n?m.jsx("div",{className:"nb-card",children:m.jsx("p",{className:"text-[var(--color-text-muted)]",children:"加载中…"})}):t?m.jsx("div",{className:"nb-card",children:m.jsxs("dl",{className:"grid grid-cols-[160px_1fr] gap-y-3 text-sm",children:[m.jsx("dt",{className:"font-bold",children:"仓库路径"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:t.repoDir??"—"}),m.jsx("dt",{className:"font-bold",children:"PM 后端"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:t.pmBackend}),m.jsx("dt",{className:"font-bold",children:"Agent"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:t.agentProvider}),m.jsx("dt",{className:"font-bold",children:"卡片"}),m.jsxs("dd",{className:"font-[family-name:var(--font-mono)]",children:[t.cards.total," 张 · ",t.cards.inprogress," 进行中 · ",t.cards.done," 完成"]}),m.jsx("dt",{className:"font-bold",children:"Worker"}),m.jsxs("dd",{className:"font-[family-name:var(--font-mono)]",children:[t.workers.total," 个(",t.workers.active," 活跃)"]}),m.jsx("dt",{className:"font-bold",children:"Pipeline"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:t.pipelineStatus}),m.jsx("dt",{className:"font-bold",children:"最近活动"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:t.lastActivityAt?new Date(t.lastActivityAt).toLocaleString():"—"})]})}):m.jsx("div",{className:"nb-card bg-[var(--color-crashed-bg)]",children:m.jsxs("p",{children:["项目 ",e," 不存在或无法读取。"]})})}function DO({name:e}){const t=qn(),{alert:n}=si(),{data:a,isLoading:s,isError:o,error:c,refetch:f}=lt({queryKey:["project-conf",e],queryFn:()=>VA(e)}),[d,h]=M.useState(null),[y,g]=M.useState(null);M.useEffect(()=>{a&&d===null&&(h(a.content),g(a.etag))},[a,d]);const x=d!==null&&a!==void 0&&d!==a.content,v=Pn({mutationFn:()=>{if(d===null||y===null)throw new Error("no draft");return XA(e,d,y)},onSuccess:S=>{g(S.etag),t.invalidateQueries({queryKey:["project-conf",e]}),t.invalidateQueries({queryKey:["project",e]})},onError:S=>{const w=S.status;n({title:w===409?"配置已被其他地方修改":"保存失败",body:w===409?'conf 文件在你编辑期间被改过。点"重新加载"后再编辑。':S instanceof Error?S.message:String(S)})}});return s?m.jsx("div",{className:"nb-card",children:m.jsx("p",{className:"text-[var(--color-text-muted)]",children:"加载中…"})}):o?m.jsx("div",{className:"nb-card bg-[var(--color-crashed-bg)]",children:m.jsxs("p",{children:["加载失败: ",c instanceof Error?c.message:String(c)]})}):m.jsxs("div",{className:"nb-card",children:[m.jsxs("div",{className:"flex items-center justify-between mb-3",children:[m.jsxs("div",{children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-lg font-bold",children:m.jsxs("code",{className:"font-[family-name:var(--font-mono)] text-sm bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] px-2 py-0.5 rounded",children:["~/.coral/projects/",e,"/conf"]})}),y&&m.jsxs("p",{className:"text-xs text-[var(--color-text-muted)] font-[family-name:var(--font-mono)] mt-1",children:["etag: ",y]})]}),m.jsxs("div",{className:"flex gap-2",children:[m.jsxs("button",{type:"button",className:"nb-btn",style:{padding:"6px 12px"},onClick:()=>{h(null),f()},disabled:v.isPending,"aria-label":"重新加载",children:[m.jsx(Cl,{size:13,strokeWidth:2.5}),"重新加载"]}),m.jsxs("button",{type:"button",className:"nb-btn nb-btn-primary",style:{padding:"6px 12px"},onClick:()=>v.mutate(),disabled:!x||v.isPending,"aria-label":"保存配置",children:[v.isPending?m.jsx(Wt,{size:13,strokeWidth:3,className:"animate-spin"}):v.isSuccess&&!x?m.jsx(EC,{size:13,strokeWidth:3}):m.jsx(Df,{size:13,strokeWidth:3}),"保存"]})]})]}),m.jsx("textarea",{className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",style:{minHeight:480,resize:"vertical"},value:d??"",onChange:S=>h(S.target.value),spellCheck:!1,"aria-label":"conf 文件编辑器"}),x&&m.jsx("p",{className:"text-xs text-[var(--color-stuck)] mt-2 font-bold",children:"● 未保存的修改"})]})}function LO({name:e}){const t=qn(),{confirm:n,alert:a}=si(),{data:s,isLoading:o}=lt({queryKey:["project-pipelines",e],queryFn:()=>WA(e)}),[c,f]=M.useState(null),[d,h]=M.useState(!1),y=Pn({mutationFn:S=>JA(e,S),onSuccess:()=>t.invalidateQueries({queryKey:["project-pipelines",e]}),onError:S=>{a({title:"切换失败",body:S instanceof Error?S.message:String(S)})}}),g=Pn({mutationFn:S=>i2(e,S),onSuccess:()=>t.invalidateQueries({queryKey:["project-pipelines",e]}),onError:S=>{a({title:"删除失败",body:S instanceof Error?S.message:String(S)})}}),x=Pn({mutationFn:S=>n2(e,S.name,S.template),onSuccess:S=>{t.invalidateQueries({queryKey:["project-pipelines",e]}),h(!1),f(S.name)},onError:S=>{a({title:"创建失败",body:S instanceof Error?S.message:String(S)})}});if(o)return m.jsx("div",{className:"nb-card",children:m.jsx("p",{className:"text-[var(--color-text-muted)]",children:"加载中…"})});const v=[];s!=null&&s.active&&v.push({name:s.active,isActive:!0});for(const S of(s==null?void 0:s.available)??[])v.push({name:S.name,isActive:!1});return m.jsxs(m.Fragment,{children:[m.jsxs("div",{className:"nb-card",children:[m.jsxs("div",{className:"flex items-center justify-between mb-3",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-lg font-bold",children:"Pipelines"}),m.jsxs("button",{type:"button",className:"nb-btn nb-btn-mint",style:{padding:"6px 12px",fontSize:12},onClick:()=>h(!0),disabled:x.isPending,"aria-label":"新建 pipeline",children:[m.jsx(Xi,{size:12,strokeWidth:3}),"新建 pipeline"]})]}),v.length===0?m.jsx("p",{className:"text-sm text-[var(--color-text-muted)] italic p-4 border-2 border-dashed border-[var(--color-text)] rounded-lg text-center",children:'还没有 pipeline 文件。点"新建 pipeline"开始。'}):m.jsx("ul",{className:"flex flex-col gap-2",children:v.map(S=>m.jsxs("li",{className:"flex items-center gap-3 p-3 bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-lg",children:[m.jsx(i1,{size:16,strokeWidth:2.5}),m.jsx("span",{className:"font-[family-name:var(--font-mono)] font-bold flex-1",children:S.name}),S.isActive&&m.jsx("span",{className:"nb-status",style:{background:"var(--color-running-bg)",color:"var(--color-running)"},children:"active"}),m.jsxs("div",{className:"flex gap-1",children:[m.jsxs("button",{type:"button",className:"nb-btn",style:{padding:"4px 10px",fontSize:11},onClick:()=>f(S.name),"aria-label":`编辑 ${S.name}`,children:[m.jsx(Hp,{size:11,strokeWidth:2.5}),"编辑"]}),!S.isActive&&m.jsxs(m.Fragment,{children:[m.jsx("button",{type:"button",className:"nb-btn nb-btn-primary",style:{padding:"4px 10px",fontSize:11},onClick:async()=>{await n({title:`切换到 ${S.name}`,body:`当前 project.yaml 会被 ${S.name} 的内容覆盖。继续?`,confirm:"切换"})&&y.mutate(S.name)},disabled:y.isPending,"aria-label":`切换到 ${S.name}`,children:"切换"}),m.jsx("button",{type:"button",className:"nb-btn nb-btn-danger",style:{padding:"4px 10px",fontSize:11},onClick:async()=>{await n({title:`删除 ${S.name}`,body:"这个 pipeline 文件会被永久删除。",confirm:"删除",danger:!0})&&g.mutate(S.name)},disabled:g.isPending,"aria-label":`删除 ${S.name}`,children:m.jsx(Il,{size:11,strokeWidth:2.5})})]})]})]},S.name))})]}),c&&m.jsx(CO,{projectName:e,file:c,onClose:()=>f(null),onSaved:()=>{t.invalidateQueries({queryKey:["project-pipelines",e]})}}),d&&m.jsx(RO,{hasActive:!!(s!=null&&s.active),hasSample:!0,isPending:x.isPending,onCancel:()=>h(!1),onCreate:(S,w)=>x.mutate({name:S,template:w})})]})}function IO({name:e,repoDir:t}){const n=wr(),a=qn(),{alert:s}=si(),[o,c]=M.useState(""),[f,d]=M.useState(!0),h=Pn({mutationFn:()=>ZA(e,{includeClaudeDir:f}),onSuccess:y=>{a.invalidateQueries({queryKey:["projects"]});const g=y.claudeRemoved.filter(x=>x.ok).map(x=>x.path);s({title:"已删除",body:g.length>0?`项目已删除。同时清理了:
474
474
  ${g.join(`
475
- `)}`:"项目已删除。"}).then(()=>n("/projects"))},onError:y=>{s({title:"删除失败",body:y instanceof Error?y.message:String(y)})}});return m.jsxs("div",{className:"nb-card bg-[var(--color-crashed-bg)]",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-lg font-bold mb-2 text-[var(--color-crashed)]",children:"删除项目"}),m.jsxs("p",{className:"text-sm mb-4",children:["这会清理 ",m.jsxs("code",{className:"font-[family-name:var(--font-mono)] bg-[var(--color-bg)] border-2 border-[var(--color-text)] px-1.5 py-0.5 rounded",children:["~/.coral/projects/",e,"/"]}),"(包括所有卡片、runtime、logs)。"]}),t&&m.jsxs("label",{className:"flex items-start gap-2 mb-4 p-3 bg-[var(--color-bg)] border-2 border-[var(--color-text)] rounded-lg cursor-pointer",children:[m.jsx("input",{type:"checkbox",checked:f,onChange:y=>d(y.target.checked),className:"mt-0.5"}),m.jsxs("div",{className:"flex-1",children:[m.jsx("div",{className:"text-sm font-bold",children:"同时清理 repo 的 .claude/"}),m.jsxs("div",{className:"text-xs text-[var(--color-text-muted)] font-[family-name:var(--font-mono)]",children:[t,"/.claude/"]}),m.jsx("div",{className:"text-xs text-[var(--color-text-muted)] mt-1",children:"repo 本身不动,只清这个目录。"})]})]}),m.jsx("div",{className:"mb-4",children:m.jsxs("label",{className:"flex flex-col gap-1.5",children:[m.jsxs("span",{className:"text-sm font-bold",children:["输入项目名 ",m.jsx("code",{className:"font-[family-name:var(--font-mono)] text-xs",children:e})," 确认:"]}),m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",value:o,onChange:y=>c(y.target.value),placeholder:e})]})}),m.jsxs("button",{type:"button",className:"nb-btn nb-btn-danger",disabled:o!==e||h.isPending,onClick:()=>h.mutate(),"aria-label":"永久删除项目",children:[h.isPending?m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(Il,{size:14,strokeWidth:3}),"永久删除"]})]})}function lg(e){const t=e?`?project=${encodeURIComponent(e)}`:"";return Ht(`/api/skills${t}`)}function zO(e){return Ht(`/api/skills/${encodeURIComponent(e)}`)}function BO(e,t){return Ht(`/api/skills/${encodeURIComponent(e)}/references/${encodeURIComponent(t)}`)}async function Yf(e,t){const n=await fetch(e,{method:"POST",headers:t?{"Content-Type":"application/json"}:void 0,body:t?JSON.stringify(t):void 0});if(!n.ok)throw new Error(`${n.status}: ${await n.text()}`);return n.json().catch(()=>({}))}function UO(e,t){return Yf(`/api/skills/${encodeURIComponent(e)}/link`,{project:t})}function FO(e,t){return fetch(`/api/skills/${encodeURIComponent(e)}/link?project=${encodeURIComponent(t)}`,{method:"DELETE"}).then(n=>{if(!n.ok)throw new Error(`${n.status}`);return n.json()})}function $O(e,t){return Yf(`/api/skills/${encodeURIComponent(e)}/freeze`,{project:t})}function PO(e,t){return Yf(`/api/skills/${encodeURIComponent(e)}/unfreeze`,{project:t})}function qO(){return Yf("/api/skills/sync")}function HO({project:e,isPending:t,onCancel:n,onCreate:a}){var A;const[s,o]=M.useState(""),[c,f]=M.useState(""),[d,h]=M.useState(new Set),[y,g]=M.useState(!0),x=lt({queryKey:["skills-all",e],queryFn:()=>lg(e)});M.useEffect(()=>{const T=D=>{D.key==="Escape"&&n()};return window.addEventListener("keydown",T),()=>window.removeEventListener("keydown",T)},[n]);const S=s.trim().length>0&&s.trim().length<=200&&!t,w=T=>{const D=new Set(d);D.has(T)?D.delete(T):D.add(T),h(D)},k=()=>{S&&a({title:s.trim(),description:c.trim(),skills:[...d],labels:y?["AI-PIPELINE"]:[]})},_=((A=x.data)==null?void 0:A.data)??[];return m.jsx("div",{role:"dialog","aria-modal":"true",className:"fixed inset-0 z-40 flex items-start justify-center p-6 bg-black/30 overflow-auto",children:m.jsxs("div",{className:"nb-card mt-8 w-full max-w-xl flex flex-col",style:{maxHeight:"calc(100vh - 64px)"},children:[m.jsxs("header",{className:"flex items-center justify-between mb-4 flex-shrink-0",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-2xl font-bold",children:"新建卡片"}),m.jsx("button",{className:"nb-btn nb-btn-mint p-2",onClick:n,type:"button","aria-label":"关闭",children:m.jsx(Er,{size:14,strokeWidth:3})})]}),m.jsxs("form",{onSubmit:T=>{T.preventDefault(),k()},className:"flex flex-col gap-4 overflow-auto",children:[m.jsxs("label",{className:"flex flex-col gap-1.5",children:[m.jsx("span",{className:"text-sm font-bold",children:"标题 *"}),m.jsx("input",{type:"text",className:"nb-input w-full",placeholder:"例如:接入 GitHub OAuth 登录",value:s,onChange:T=>o(T.target.value),maxLength:200,autoFocus:!0,required:!0}),m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:"写简短明了的目标(<200 字符)"})]}),m.jsxs("label",{className:"flex flex-col gap-1.5",children:[m.jsx("span",{className:"text-sm font-bold",children:"描述"}),m.jsx("textarea",{className:"nb-input w-full",style:{minHeight:120,resize:"vertical"},placeholder:"用户故事、需求、验收标准、参考资料… Claude 启动时会读这里的内容",value:c,onChange:T=>f(T.target.value)}),m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:"支持 markdown。空的话就只有 title,Claude 只能靠 title 推断要做啥。"})]}),m.jsxs("div",{className:"flex flex-col gap-2",children:[m.jsx("span",{className:"text-sm font-bold",children:"Skills"}),m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:"勾选哪些 skill 会被加载(走 frontmatter `skills:`)。不选也行,Worker 默认加载项目级 skills。"}),x.isLoading&&m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"加载 skill 列表…"}),x.isError&&m.jsxs("p",{className:"text-xs text-[var(--color-crashed)]",children:["skill 列表加载失败,不影响创建:",x.error instanceof Error?x.error.message:String(x.error)]}),_.length>0&&m.jsx("div",{className:"flex flex-wrap gap-2",children:_.map(T=>{const D=d.has(T.name);return m.jsx("button",{type:"button",onClick:()=>w(T.name),className:["px-2.5 py-1 text-xs font-[family-name:var(--font-mono)] rounded-full border-2 transition-all",D?"bg-[var(--color-accent-mint)] border-[var(--color-text)] shadow-[2px_2px_0_var(--color-text)] font-bold":"bg-[var(--color-bg)] border-[var(--color-border-light)] hover:border-[var(--color-text)]"].join(" "),"aria-pressed":D,children:T.name},T.name)})}),d.size>0&&m.jsxs("p",{className:"text-xs text-[var(--color-text-muted)]",children:["已选 ",d.size," 个:",[...d].join(", ")]})]}),m.jsxs("div",{className:"flex flex-col gap-2",children:[m.jsx("span",{className:"text-sm font-bold",children:"流水线"}),m.jsxs("label",{className:"flex items-center gap-3 cursor-pointer select-none p-3 border-[2px] border-[var(--color-text)] rounded-lg bg-[var(--color-bg-cream)]",children:[m.jsx("input",{type:"checkbox",className:"w-4 h-4 accent-[var(--color-cta)] cursor-pointer",checked:y,onChange:T=>g(T.target.checked)}),m.jsxs("div",{className:"flex-1",children:[m.jsx("div",{className:"text-sm font-bold",children:"加入流水线(`AI-PIPELINE` 标签)"}),m.jsx("div",{className:"text-xs text-[var(--color-text-muted)] mt-0.5",children:"打开后 pipeline 会识别这张卡并派 worker 跑。关闭则只是一个普通 todo,需要人工改标签才会被流水线拾起。"})]})]})]})]}),m.jsxs("div",{className:"flex gap-2 justify-end mt-4 pt-3 border-t-2 border-dashed border-[var(--color-text)] flex-shrink-0",children:[m.jsx("button",{className:"nb-btn",style:{padding:"6px 14px"},onClick:n,disabled:t,type:"button",children:"取消"}),m.jsxs("button",{className:"nb-btn nb-btn-primary",style:{padding:"6px 14px"},onClick:k,disabled:!S,type:"button","aria-label":"创建卡片",children:[t?m.jsx(Wt,{size:13,strokeWidth:3,className:"animate-spin"}):m.jsx(Xi,{size:13,strokeWidth:3}),"创建"]})]})]})})}function KO(e){return Ht(`/api/projects/${encodeURIComponent(e)}/cards`)}function GO(e,t){return Ht(`/api/projects/${encodeURIComponent(e)}/cards/${t}`)}async function ql(e,t){const n=await fetch(e,{method:"POST",headers:t?{"Content-Type":"application/json"}:void 0,body:t?JSON.stringify(t):void 0});if(!n.ok){const a=await n.text();throw new Error(`${n.status} ${n.statusText}: ${a}`)}return n.json().catch(()=>({}))}function QO(e,t){return ql(`/api/projects/${encodeURIComponent(e)}/cards/${t}/reset`)}async function YO(e,t){const n=await fetch(`/api/projects/${encodeURIComponent(e)}/cards/${t}`,{method:"DELETE"});if(!n.ok){const a=await n.text();throw new Error(`${n.status}: ${a}`)}}function VO(e,t){return ql(`/api/projects/${encodeURIComponent(e)}/cards/${t}/launch`)}function XO(e,t){const n=typeof t=="string"?{title:t}:t;return ql(`/api/projects/${encodeURIComponent(e)}/cards`,n)}async function ZO(e,t,n){const a=await fetch(`/api/projects/${encodeURIComponent(e)}/cards/${t}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:n})});if(!a.ok){const s=await a.text();throw new Error(`${a.status}: ${s}`)}}async function WO(e,t,n){const a=await fetch(`/api/projects/${encodeURIComponent(e)}/cards/${t}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});if(!a.ok){const s=await a.text();throw new Error(`${a.status}: ${s}`)}return a.json()}function JO(e){return ql(`/api/projects/${encodeURIComponent(e)}/pipeline/start`)}function eR(e){return ql(`/api/projects/${encodeURIComponent(e)}/pipeline/stop`)}function tR(e,t){return ql(`/api/projects/${encodeURIComponent(e)}/pipeline/reset`,t??{})}function nR(e){const t=qn();M.useEffect(()=>{if(!e)return;const n=`/stream/projects/${encodeURIComponent(e)}`,a=new EventSource(n),s=f=>{try{const d=JSON.parse(f.data);t.invalidateQueries({queryKey:["cards",d.project]}),t.invalidateQueries({queryKey:["card",d.project,d.seq]}),t.invalidateQueries({queryKey:["projects"]})}catch{}},o=f=>{try{const d=JSON.parse(f.data);t.invalidateQueries({queryKey:["workers",d.project]}),t.invalidateQueries({queryKey:["projects"]})}catch{}},c=f=>{try{const d=JSON.parse(f.data);t.invalidateQueries({queryKey:["pipeline-status",d.project]}),t.invalidateQueries({queryKey:["projects"]})}catch{}};return a.addEventListener("card.created",s),a.addEventListener("card.updated",s),a.addEventListener("card.moved",s),a.addEventListener("card.deleted",s),a.addEventListener("worker.updated",o),a.addEventListener("worker.added",o),a.addEventListener("worker.deleted",o),a.addEventListener("pipeline.status",c),a.addEventListener("pipeline.started",c),a.addEventListener("pipeline.stopped",c),()=>a.close()},[e,t])}const iR=new Set(["python","typescript","golang","rust","kotlin","swift","java"]),aR=new Set(["frontend","backend","mobile","database","devops"]),rR=new Set(["backend-architect","frontend-developer","code-reviewer","database-optimizer","devops-automator","security-engineer","qa-tester","security","qa","architect","db-opt"]),sR=new Set(["coding-standards","tdd-workflow","git-workflow","architecture-decision-records","debugging-workflow"]);function lR(e){return iR.has(e)?"lang":aR.has(e)?"end":rR.has(e)?"persona":sR.has(e)?"workflow":"other"}const oR={lang:"var(--color-accent-purple)",end:"var(--color-secondary)",persona:"var(--color-primary)",workflow:"var(--color-accent-mint)",other:"var(--color-bg)"};function iS({name:e}){const t=oR[lR(e)];return m.jsx("span",{className:"nb-badge",style:{background:t},children:e})}function aS({label:e,kind:t="default"}){const n=t==="warn"?"var(--color-accent-pink)":t==="accent"?"var(--color-accent-yellow)":"var(--color-bg-cream)";return m.jsx("span",{className:"nb-badge",style:{background:n},children:e})}function cR({card:e,onClick:t,done:n,draggable:a}){const s=e.labels.some(o=>o.startsWith("STARTED-"))&&!n;return m.jsxs("article",{onClick:t,onKeyDown:o=>{(o.key==="Enter"||o.key===" ")&&(o.preventDefault(),t())},draggable:a,onDragStart:o=>{o.dataTransfer.setData("application/x-sps-card-seq",String(e.seq)),o.dataTransfer.effectAllowed="move"},tabIndex:0,role:"button","aria-label":`Card #${e.seq}: ${e.title}`,className:["bg-[var(--color-bg)] border-[3px] border-[var(--color-text)] rounded-xl p-3","shadow-[3px_3px_0_var(--color-text)] cursor-pointer","transition-[transform,box-shadow] duration-[180ms] ease-out","hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-[5px_5px_0_var(--color-text)]","focus:outline-none focus-visible:ring-[3px] focus-visible:ring-offset-2 focus-visible:ring-[var(--color-text)]",n?"opacity-60":"",a?"active:cursor-grabbing":""].join(" "),children:[m.jsxs("div",{className:"flex items-center justify-between gap-2 mb-2",children:[m.jsxs("span",{className:"font-[family-name:var(--font-mono)] font-bold text-[11px] px-2 py-0.5 bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-full",children:["#",e.seq]}),s&&m.jsx("span",{className:"nb-status",style:{background:"var(--color-running-bg)",color:"var(--color-running)"},children:"running"})]}),m.jsx("p",{className:`font-bold text-sm leading-5 mb-2 line-clamp-2 ${n?"line-through decoration-2":""}`,children:e.title}),(e.skills.length>0||e.labels.length>0)&&m.jsxs("div",{className:"flex flex-wrap gap-1 mb-2",children:[e.skills.slice(0,3).map(o=>m.jsx(iS,{name:o},o)),e.labels.filter(o=>o==="NEEDS-FIX").map(o=>m.jsx(aS,{label:o,kind:"warn"},o))]}),e.checklist&&e.checklist.total>0&&m.jsx(uR,{stats:e.checklist}),m.jsxs("div",{className:"pt-2 border-t-[1.5px] border-dashed border-[var(--color-border-light)] flex items-center gap-2 text-[11px] font-[family-name:var(--font-mono)] text-[var(--color-text-subtle)]",children:[m.jsx("span",{children:fR(e.updatedAt??e.createdAt)}),e.branch&&m.jsxs("span",{className:"truncate",children:["· ",e.branch]})]})]})}function uR({stats:e}){return m.jsxs("div",{className:"mb-2",children:[m.jsxs("div",{className:"flex items-center justify-between text-[11px] font-[family-name:var(--font-mono)] mb-1",children:[m.jsxs("span",{className:"font-bold",children:["检查清单 ",e.done,"/",e.total]}),m.jsxs("span",{className:"text-[var(--color-text-subtle)]",children:[e.percent,"%"]})]}),m.jsx("div",{className:"w-full h-1.5 bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-full overflow-hidden mb-1.5",children:m.jsx("div",{className:"h-full bg-[var(--color-cta)] transition-[width] duration-200",style:{width:`${e.percent}%`}})}),m.jsxs("ul",{className:"text-[11px] space-y-0.5",children:[e.items.slice(0,3).map((t,n)=>m.jsxs("li",{className:`flex items-start gap-1 ${t.done?"opacity-60 line-through":""}`,children:[m.jsx("span",{className:"flex-shrink-0 mt-0.5",children:t.done?"✓":"○"}),m.jsx("span",{className:"line-clamp-1",children:t.text})]},n)),e.items.length>3&&m.jsxs("li",{className:"text-[var(--color-text-subtle)] italic pl-3",children:["… 还有 ",e.items.length-3," 条"]})]})]})}function fR(e){if(!e)return"—";const t=new Date(e),n=Date.now()-t.getTime();return n<6e4?"刚才":n<36e5?`${Math.floor(n/6e4)}m ago`:n<864e5?`${Math.floor(n/36e5)}h ago`:t.toLocaleDateString()}function dR({label:e,bg:t,cards:n,onCardClick:a,onDropCard:s}){const[o,c]=M.useState(!1);return m.jsxs("div",{className:["flex flex-col gap-2 p-3 rounded-2xl border-[3px] min-h-[340px]","transition-all",o?"border-[var(--color-cta)] shadow-[4px_4px_0_var(--color-cta)]":"border-[var(--color-text)]"].join(" "),style:{background:t},onDragOver:f=>{!s||!f.dataTransfer.types.includes("application/x-sps-card-seq")||(f.preventDefault(),f.dataTransfer.dropEffect="move",o||c(!0))},onDragLeave:()=>c(!1),onDrop:f=>{if(c(!1),!s)return;const d=f.dataTransfer.getData("application/x-sps-card-seq"),h=Number.parseInt(d,10);Number.isFinite(h)&&(f.preventDefault(),s(h))},children:[m.jsxs("div",{className:"flex items-center justify-between px-1 pb-2 border-b-2 border-[var(--color-text)]",children:[m.jsx("span",{className:"font-[family-name:var(--font-heading)] font-bold text-sm uppercase tracking-wider",children:e}),m.jsx("span",{className:"font-[family-name:var(--font-mono)] font-bold text-xs px-2 py-0.5 bg-[var(--color-bg)] border-2 border-[var(--color-text)] rounded-full",children:n.length})]}),m.jsxs("div",{className:"flex flex-col gap-2",children:[n.length===0&&m.jsx("div",{className:"text-xs text-[var(--color-text-muted)] text-center py-6 italic",children:"— 空 —"}),n.map(f=>m.jsx(cR,{card:f,onClick:()=>a(f),done:e==="Done",draggable:!!s},f.seq))]})]})}function dp(e,t){if(!e)return"";const n=e.split(`
475
+ `)}`:"项目已删除。"}).then(()=>n("/projects"))},onError:y=>{s({title:"删除失败",body:y instanceof Error?y.message:String(y)})}});return m.jsxs("div",{className:"nb-card bg-[var(--color-crashed-bg)]",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-lg font-bold mb-2 text-[var(--color-crashed)]",children:"删除项目"}),m.jsxs("p",{className:"text-sm mb-4",children:["这会清理 ",m.jsxs("code",{className:"font-[family-name:var(--font-mono)] bg-[var(--color-bg)] border-2 border-[var(--color-text)] px-1.5 py-0.5 rounded",children:["~/.coral/projects/",e,"/"]}),"(包括所有卡片、runtime、logs)。"]}),t&&m.jsxs("label",{className:"flex items-start gap-2 mb-4 p-3 bg-[var(--color-bg)] border-2 border-[var(--color-text)] rounded-lg cursor-pointer",children:[m.jsx("input",{type:"checkbox",checked:f,onChange:y=>d(y.target.checked),className:"mt-0.5"}),m.jsxs("div",{className:"flex-1",children:[m.jsx("div",{className:"text-sm font-bold",children:"同时清理 repo 的 .claude/"}),m.jsxs("div",{className:"text-xs text-[var(--color-text-muted)] font-[family-name:var(--font-mono)]",children:[t,"/.claude/"]}),m.jsx("div",{className:"text-xs text-[var(--color-text-muted)] mt-1",children:"repo 本身不动,只清这个目录。"})]})]}),m.jsx("div",{className:"mb-4",children:m.jsxs("label",{className:"flex flex-col gap-1.5",children:[m.jsxs("span",{className:"text-sm font-bold",children:["输入项目名 ",m.jsx("code",{className:"font-[family-name:var(--font-mono)] text-xs",children:e})," 确认:"]}),m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",value:o,onChange:y=>c(y.target.value),placeholder:e})]})}),m.jsxs("button",{type:"button",className:"nb-btn nb-btn-danger",disabled:o!==e||h.isPending,onClick:()=>h.mutate(),"aria-label":"永久删除项目",children:[h.isPending?m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(Il,{size:14,strokeWidth:3}),"永久删除"]})]})}function lg(e){const t=e?`?project=${encodeURIComponent(e)}`:"";return Ht(`/api/skills${t}`)}function zO(e){return Ht(`/api/skills/${encodeURIComponent(e)}`)}function BO(e,t){return Ht(`/api/skills/${encodeURIComponent(e)}/references/${encodeURIComponent(t)}`)}async function Yf(e,t){const n=await fetch(e,{method:"POST",headers:t?{"Content-Type":"application/json"}:void 0,body:t?JSON.stringify(t):void 0});if(!n.ok)throw new Error(`${n.status}: ${await n.text()}`);return n.json().catch(()=>({}))}function UO(e,t){return Yf(`/api/skills/${encodeURIComponent(e)}/link`,{project:t})}function FO(e,t){return fetch(`/api/skills/${encodeURIComponent(e)}/link?project=${encodeURIComponent(t)}`,{method:"DELETE"}).then(n=>{if(!n.ok)throw new Error(`${n.status}`);return n.json()})}function $O(e,t){return Yf(`/api/skills/${encodeURIComponent(e)}/freeze`,{project:t})}function PO(e,t){return Yf(`/api/skills/${encodeURIComponent(e)}/unfreeze`,{project:t})}function qO(){return Yf("/api/skills/sync")}function HO({project:e,isPending:t,onCancel:n,onCreate:a}){var A;const[s,o]=M.useState(""),[c,f]=M.useState(""),[d,h]=M.useState(new Set),[y,g]=M.useState(!0),x=lt({queryKey:["skills-all",e],queryFn:()=>lg(e)});M.useEffect(()=>{const T=D=>{D.key==="Escape"&&n()};return window.addEventListener("keydown",T),()=>window.removeEventListener("keydown",T)},[n]);const S=s.trim().length>0&&s.trim().length<=200&&!t,w=T=>{const D=new Set(d);D.has(T)?D.delete(T):D.add(T),h(D)},k=()=>{S&&a({title:s.trim(),description:c.trim(),skills:[...d],labels:y?["AI-PIPELINE"]:[]})},_=((A=x.data)==null?void 0:A.data)??[];return m.jsx("div",{role:"dialog","aria-modal":"true",className:"fixed inset-0 z-40 flex items-start justify-center p-6 bg-black/30 overflow-auto",children:m.jsxs("div",{className:"nb-card mt-8 w-full max-w-xl flex flex-col",style:{maxHeight:"calc(100vh - 64px)"},children:[m.jsxs("header",{className:"flex items-center justify-between mb-4 flex-shrink-0",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-2xl font-bold",children:"新建卡片"}),m.jsx("button",{className:"nb-btn nb-btn-mint p-2",onClick:n,type:"button","aria-label":"关闭",children:m.jsx(Er,{size:14,strokeWidth:3})})]}),m.jsxs("form",{onSubmit:T=>{T.preventDefault(),k()},className:"flex flex-col gap-4 overflow-auto",children:[m.jsxs("label",{className:"flex flex-col gap-1.5",children:[m.jsx("span",{className:"text-sm font-bold",children:"标题 *"}),m.jsx("input",{type:"text",className:"nb-input w-full",placeholder:"例如:接入 GitHub OAuth 登录",value:s,onChange:T=>o(T.target.value),maxLength:200,autoFocus:!0,required:!0}),m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:"写简短明了的目标(<200 字符)"})]}),m.jsxs("label",{className:"flex flex-col gap-1.5",children:[m.jsx("span",{className:"text-sm font-bold",children:"描述"}),m.jsx("textarea",{className:"nb-input w-full",style:{minHeight:120,resize:"vertical"},placeholder:"用户故事、需求、验收标准、参考资料… Claude 启动时会读这里的内容",value:c,onChange:T=>f(T.target.value)}),m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:"支持 markdown。空的话就只有 title,Claude 只能靠 title 推断要做啥。"})]}),m.jsxs("div",{className:"flex flex-col gap-2",children:[m.jsx("span",{className:"text-sm font-bold",children:"Skills"}),m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:"勾选哪些 skill 会被加载(走 frontmatter `skills:`)。不选也行,Worker 默认加载项目级 skills。"}),x.isLoading&&m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"加载 skill 列表…"}),x.isError&&m.jsxs("p",{className:"text-xs text-[var(--color-crashed)]",children:["skill 列表加载失败,不影响创建:",x.error instanceof Error?x.error.message:String(x.error)]}),_.length>0&&m.jsx("div",{className:"flex flex-wrap gap-2",children:_.map(T=>{const D=d.has(T.name);return m.jsx("button",{type:"button",onClick:()=>w(T.name),className:["px-2.5 py-1 text-xs font-[family-name:var(--font-mono)] rounded-full border-2 transition-all",D?"bg-[var(--color-accent-mint)] border-[var(--color-text)] shadow-[2px_2px_0_var(--color-text)] font-bold":"bg-[var(--color-bg)] border-[var(--color-border-light)] hover:border-[var(--color-text)]"].join(" "),"aria-pressed":D,children:T.name},T.name)})}),d.size>0&&m.jsxs("p",{className:"text-xs text-[var(--color-text-muted)]",children:["已选 ",d.size," 个:",[...d].join(", ")]})]}),m.jsxs("div",{className:"flex flex-col gap-2",children:[m.jsx("span",{className:"text-sm font-bold",children:"流水线"}),m.jsxs("label",{className:"flex items-center gap-3 cursor-pointer select-none p-3 border-[2px] border-[var(--color-text)] rounded-lg bg-[var(--color-bg-cream)]",children:[m.jsx("input",{type:"checkbox",className:"w-4 h-4 accent-[var(--color-cta)] cursor-pointer",checked:y,onChange:T=>g(T.target.checked)}),m.jsxs("div",{className:"flex-1",children:[m.jsx("div",{className:"text-sm font-bold",children:"加入流水线(`AI-PIPELINE` 标签)"}),m.jsx("div",{className:"text-xs text-[var(--color-text-muted)] mt-0.5",children:"打开后 pipeline 会识别这张卡并派 worker 跑。关闭则只是一个普通 todo,需要人工改标签才会被流水线拾起。"})]})]})]})]}),m.jsxs("div",{className:"flex gap-2 justify-end mt-4 pt-3 border-t-2 border-dashed border-[var(--color-text)] flex-shrink-0",children:[m.jsx("button",{className:"nb-btn",style:{padding:"6px 14px"},onClick:n,disabled:t,type:"button",children:"取消"}),m.jsxs("button",{className:"nb-btn nb-btn-primary",style:{padding:"6px 14px"},onClick:k,disabled:!S,type:"button","aria-label":"创建卡片",children:[t?m.jsx(Wt,{size:13,strokeWidth:3,className:"animate-spin"}):m.jsx(Xi,{size:13,strokeWidth:3}),"创建"]})]})]})})}function KO(e){return Ht(`/api/projects/${encodeURIComponent(e)}/cards`)}function GO(e,t){return Ht(`/api/projects/${encodeURIComponent(e)}/cards/${t}`)}async function ql(e,t){const n=await fetch(e,{method:"POST",headers:t?{"Content-Type":"application/json"}:void 0,body:t?JSON.stringify(t):void 0});if(!n.ok){const a=await n.text();throw new Error(`${n.status} ${n.statusText}: ${a}`)}return n.json().catch(()=>({}))}function QO(e,t){return ql(`/api/projects/${encodeURIComponent(e)}/cards/${t}/reset`)}async function YO(e,t){const n=await fetch(`/api/projects/${encodeURIComponent(e)}/cards/${t}`,{method:"DELETE"});if(!n.ok){const a=await n.text();throw new Error(`${n.status}: ${a}`)}}function VO(e,t){return ql(`/api/projects/${encodeURIComponent(e)}/cards/${t}/launch`)}function XO(e,t){const n=typeof t=="string"?{title:t}:t;return ql(`/api/projects/${encodeURIComponent(e)}/cards`,n)}async function ZO(e,t,n){const a=await fetch(`/api/projects/${encodeURIComponent(e)}/cards/${t}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:n})});if(!a.ok){const s=await a.text();throw new Error(`${a.status}: ${s}`)}}async function WO(e,t,n){const a=await fetch(`/api/projects/${encodeURIComponent(e)}/cards/${t}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});if(!a.ok){const s=await a.text();throw new Error(`${a.status}: ${s}`)}return a.json()}function JO(e){return ql(`/api/projects/${encodeURIComponent(e)}/pipeline/start`)}function eR(e){return ql(`/api/projects/${encodeURIComponent(e)}/pipeline/stop`)}function tR(e,t){return ql(`/api/projects/${encodeURIComponent(e)}/pipeline/reset`,t??{})}function nR(e){const t=qn();M.useEffect(()=>{if(!e)return;const n=`/stream/projects/${encodeURIComponent(e)}`,a=new EventSource(n),s=f=>{try{const d=JSON.parse(f.data);t.invalidateQueries({queryKey:["cards",d.project]}),t.invalidateQueries({queryKey:["card",d.project,d.seq]}),t.invalidateQueries({queryKey:["projects"]})}catch{}},o=f=>{try{const d=JSON.parse(f.data);t.invalidateQueries({queryKey:["workers",d.project]}),t.invalidateQueries({queryKey:["projects"]})}catch{}},c=f=>{try{const d=JSON.parse(f.data);t.invalidateQueries({queryKey:["pipeline-status",d.project]}),t.invalidateQueries({queryKey:["projects"]})}catch{}};return a.addEventListener("card.created",s),a.addEventListener("card.updated",s),a.addEventListener("card.moved",s),a.addEventListener("card.deleted",s),a.addEventListener("worker.updated",o),a.addEventListener("worker.added",o),a.addEventListener("worker.deleted",o),a.addEventListener("pipeline.status",c),a.addEventListener("pipeline.started",c),a.addEventListener("pipeline.stopped",c),()=>a.close()},[e,t])}const iR=new Set(["python","typescript","golang","rust","kotlin","swift","java"]),aR=new Set(["frontend","backend","mobile","database","devops"]),rR=new Set(["backend-architect","frontend-developer","code-reviewer","database-optimizer","devops-automator","security-engineer","qa-tester","security","qa","architect","db-opt"]),sR=new Set(["coding-standards","tdd-workflow","git-workflow","architecture-decision-records","debugging-workflow"]);function lR(e){return iR.has(e)?"lang":aR.has(e)?"end":rR.has(e)?"persona":sR.has(e)?"workflow":"other"}const oR={lang:"var(--color-accent-purple)",end:"var(--color-secondary)",persona:"var(--color-primary)",workflow:"var(--color-accent-mint)",other:"var(--color-bg)"};function iS({name:e}){const t=oR[lR(e)];return m.jsx("span",{className:"nb-badge",style:{background:t},children:e})}function aS({label:e,kind:t="default"}){const n=t==="warn"?"var(--color-accent-pink)":t==="accent"?"var(--color-accent-yellow)":"var(--color-bg-cream)";return m.jsx("span",{className:"nb-badge",style:{background:n},children:e})}function cR({card:e,onClick:t,done:n,draggable:a}){const s=e.labels.some(o=>o.startsWith("STARTED-"))&&!n;return m.jsxs("article",{onClick:t,onKeyDown:o=>{(o.key==="Enter"||o.key===" ")&&(o.preventDefault(),t())},draggable:a,onDragStart:o=>{o.dataTransfer.setData("application/x-sps-card-seq",String(e.seq)),o.dataTransfer.effectAllowed="move"},tabIndex:0,role:"button","aria-label":`Card #${e.seq}: ${e.title}`,className:["bg-[var(--color-bg)] border-[3px] border-[var(--color-text)] rounded-xl p-3","shadow-[3px_3px_0_var(--color-text)] cursor-pointer","transition-[transform,box-shadow] duration-[180ms] ease-out","hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-[5px_5px_0_var(--color-text)]","focus:outline-none focus-visible:ring-[3px] focus-visible:ring-offset-2 focus-visible:ring-[var(--color-text)]",n?"opacity-60":"",a?"active:cursor-grabbing":""].join(" "),children:[m.jsxs("div",{className:"flex items-center justify-between gap-2 mb-2",children:[m.jsxs("span",{className:"font-[family-name:var(--font-mono)] font-bold text-[11px] px-2 py-0.5 bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-full",children:["#",e.seq]}),s&&m.jsx("span",{className:"nb-status",style:{background:"var(--color-running-bg)",color:"var(--color-running)"},children:"running"})]}),m.jsx("p",{className:`font-bold text-sm leading-5 mb-2 line-clamp-2 ${n?"line-through decoration-2":""}`,children:e.title}),(e.skills.length>0||e.labels.length>0)&&m.jsxs("div",{className:"flex flex-wrap gap-1 mb-2",children:[e.skills.slice(0,3).map(o=>m.jsx(iS,{name:o},o)),e.labels.filter(o=>o==="NEEDS-FIX").map(o=>m.jsx(aS,{label:o,kind:"warn"},o))]}),e.checklist&&e.checklist.total>0&&m.jsx(uR,{stats:e.checklist}),m.jsxs("div",{className:"pt-2 border-t-[1.5px] border-dashed border-[var(--color-border-light)] flex items-center gap-2 text-[11px] font-[family-name:var(--font-mono)] text-[var(--color-text-subtle)]",children:[m.jsx("span",{children:fR(e.updatedAt??e.createdAt)}),e.branch&&m.jsxs("span",{className:"truncate",children:["· ",e.branch]})]})]})}function uR({stats:e}){return m.jsxs("div",{className:"mb-2",children:[m.jsxs("div",{className:"flex items-center justify-between text-[11px] font-[family-name:var(--font-mono)] mb-1",children:[m.jsxs("span",{className:"font-bold",children:["检查清单 ",e.done,"/",e.total]}),m.jsxs("span",{className:"text-[var(--color-text-subtle)]",children:[e.percent,"%"]})]}),m.jsx("div",{className:"w-full h-1.5 bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-full overflow-hidden mb-1.5",children:m.jsx("div",{className:"h-full bg-[var(--color-cta)] transition-[width] duration-200",style:{width:`${e.percent}%`}})}),m.jsxs("ul",{className:"text-[11px] space-y-0.5",children:[e.items.slice(0,3).map((t,n)=>m.jsxs("li",{className:`flex items-start gap-1 ${t.done?"opacity-60 line-through":""}`,children:[m.jsx("span",{className:"flex-shrink-0 mt-0.5",children:t.done?"✓":"○"}),m.jsx("span",{className:"line-clamp-1",children:t.text})]},n)),e.items.length>3&&m.jsxs("li",{className:"text-[var(--color-text-subtle)] italic pl-3",children:["… 还有 ",e.items.length-3," 条"]})]})]})}function fR(e){if(!e)return"—";const t=new Date(e),n=Date.now()-t.getTime();return n<6e4?"刚才":n<36e5?`${Math.floor(n/6e4)}m ago`:n<864e5?`${Math.floor(n/36e5)}h ago`:t.toLocaleDateString()}function dR({label:e,bg:t,cards:n,onCardClick:a,onDropCard:s}){const[o,c]=M.useState(!1);return m.jsxs("div",{className:["flex flex-col p-3 rounded-2xl border-[3px] min-h-[280px] h-full min-h-0 overflow-hidden","transition-all",o?"border-[var(--color-cta)] shadow-[4px_4px_0_var(--color-cta)]":"border-[var(--color-text)]"].join(" "),style:{background:t},onDragOver:f=>{!s||!f.dataTransfer.types.includes("application/x-sps-card-seq")||(f.preventDefault(),f.dataTransfer.dropEffect="move",o||c(!0))},onDragLeave:()=>c(!1),onDrop:f=>{if(c(!1),!s)return;const d=f.dataTransfer.getData("application/x-sps-card-seq"),h=Number.parseInt(d,10);Number.isFinite(h)&&(f.preventDefault(),s(h))},children:[m.jsxs("div",{className:"flex items-center justify-between px-1 pb-2 mb-2 border-b-2 border-[var(--color-text)] shrink-0",children:[m.jsx("span",{className:"font-[family-name:var(--font-heading)] font-bold text-sm uppercase tracking-wider",children:e}),m.jsx("span",{className:"font-[family-name:var(--font-mono)] font-bold text-xs px-2 py-0.5 bg-[var(--color-bg)] border-2 border-[var(--color-text)] rounded-full",children:n.length})]}),m.jsxs("div",{className:"flex flex-col gap-2 flex-1 min-h-0 overflow-y-auto pr-1 -mr-1",style:{scrollbarWidth:"thin",scrollbarColor:"var(--color-text) transparent"},children:[n.length===0&&m.jsx("div",{className:"text-xs text-[var(--color-text-muted)] text-center py-6 italic",children:"— 空 —"}),n.map(f=>m.jsx(cR,{card:f,onClick:()=>a(f),done:e==="Done",draggable:!!s},f.seq))]})]})}function dp(e,t){if(!e)return"";const n=e.split(`
476
476
  `),a=new RegExp(`^##\\s+${t}\\s*$`),s=n.findIndex(c=>a.test(c));if(s===-1)return"";let o=n.length;for(let c=s+1;c<n.length;c++)if(/^##\s+/.test(n[c]??"")){o=c;break}return n.slice(s+1,o).join(`
477
- `).trim()}function vm(e){return dp(e,"描述")}function hR({project:e,seq:t,onClose:n,onChanged:a}){var K,oe,V,pe,R,L,J,C,me,_e,ve;const s=qn(),{confirm:o,alert:c}=si(),{data:f,isLoading:d,isError:h,error:y,refetch:g}=lt({queryKey:["card",e,t],queryFn:()=>GO(e,t)}),[x,v]=M.useState(!1),[S,w]=M.useState(""),[k,_]=M.useState(""),[A,T]=M.useState(new Set),[D,$]=M.useState([]),[j,q]=M.useState(""),U=lt({queryKey:["skills-all",e],queryFn:()=>lg(e),enabled:x}),O=((oe=(K=lt({queryKey:["projects"],queryFn:_r,refetchInterval:1e4}).data)==null?void 0:K.data.find(ce=>ce.name===e))==null?void 0:oe.pipelineStatus)==="running";M.useEffect(()=>{x&&f&&(w(f.title),_(vm(f.body)),T(new Set(f.skills)),$([...f.labels]))},[x,f]),M.useEffect(()=>{const ce=ke=>{ke.key==="Escape"&&(x?v(!1):n())};return window.addEventListener("keydown",ce),()=>window.removeEventListener("keydown",ce)},[n,x]);const P=Pn({mutationFn:()=>{if(!f)throw new Error("no data");const ce={},ke=S.trim();ke&&ke!==f.title&&(ce.title=ke);const Ke=vm(f.body);k!==Ke&&(ce.description=k);const Dt=[...A].sort(),yn=[...f.skills].sort();return JSON.stringify(Dt)!==JSON.stringify(yn)&&(ce.skills=Dt),JSON.stringify(D)!==JSON.stringify(f.labels)&&(ce.labels=D),Object.keys(ce).length===0?Promise.resolve({ok:!0,noop:!0}):WO(e,t,ce)},onSuccess:()=>{s.invalidateQueries({queryKey:["card",e,t]}),s.invalidateQueries({queryKey:["cards",e]}),v(!1),a()},onError:ce=>{c({title:"保存失败",body:ce instanceof Error?ce.message:String(ce)})}}),G=M.useMemo(()=>{if(!x||!f)return!1;if(S.trim()!==f.title||k!==vm(f.body))return!0;const ce=[...A].sort(),ke=[...f.skills].sort();return JSON.stringify(ce)!==JSON.stringify(ke)||JSON.stringify(D)!==JSON.stringify(f.labels)},[x,f,S,k,A,D]),le=ce=>{const ke=new Set(A);ke.has(ce)?ke.delete(ce):ke.add(ce),T(ke)},ae=()=>{const ce=j.trim();if(ce){if(D.includes(ce)){q("");return}$([...D,ce]),q("")}},W=ce=>{$(D.filter(ke=>ke!==ce))};return m.jsx("div",{role:"dialog","aria-modal":"true","aria-labelledby":"card-modal-title",className:"fixed inset-0 z-40 flex items-start justify-center p-6 bg-black/30 overflow-auto",children:m.jsxs("div",{className:"nb-card mt-12 w-full max-w-3xl bg-[var(--color-bg)]",children:[m.jsxs("header",{className:"flex items-start justify-between gap-4 mb-4",children:[m.jsxs("div",{className:"flex-1 min-w-0",children:[m.jsxs("div",{className:"flex items-center gap-3 mb-1",children:[m.jsxs("span",{className:"font-[family-name:var(--font-mono)] font-bold text-xs px-2 py-0.5 bg-[var(--color-accent-purple)] border-2 border-[var(--color-text)] rounded-full",children:["#",t]}),(f==null?void 0:f.state)&&m.jsx("span",{className:"font-[family-name:var(--font-mono)] text-xs px-2 py-0.5 bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-full font-semibold",children:f.state}),x&&m.jsx("span",{className:"text-xs font-bold text-[var(--color-stuck)]",children:"⚠ 编辑中"})]}),x?m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-heading)] text-xl font-bold",value:S,onChange:ce=>w(ce.target.value),maxLength:200,"aria-label":"卡片标题"}):m.jsx("h2",{id:"card-modal-title",className:"font-[family-name:var(--font-heading)] text-2xl font-bold break-words",children:(f==null?void 0:f.title)??"加载中…"})]}),m.jsxs("div",{className:"flex gap-2 flex-shrink-0",children:[!x&&f&&m.jsxs("button",{onClick:()=>v(!0),className:"nb-btn",style:{padding:"6px 12px"},type:"button","aria-label":"编辑卡片",children:[m.jsx(Hp,{size:12,strokeWidth:2.5})," 编辑"]}),m.jsx("button",{onClick:n,className:"nb-btn nb-btn-mint p-2","aria-label":"关闭",type:"button",children:m.jsx(Er,{size:14,strokeWidth:3})})]})]}),d&&m.jsx("p",{className:"text-[var(--color-text-muted)]",children:"加载中…"}),h&&m.jsxs("p",{className:"text-[var(--color-crashed)]",children:["加载失败: ",y instanceof Error?y.message:String(y)]}),f&&m.jsxs("div",{className:"flex flex-col gap-4",children:[f.branch&&!x&&m.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[m.jsx(QC,{size:14}),m.jsx("span",{className:"font-[family-name:var(--font-mono)]",children:f.branch})]}),x?m.jsxs(m.Fragment,{children:[m.jsxs("div",{children:[m.jsx("div",{className:"text-sm font-bold mb-1.5",children:"Skills"}),U.isLoading&&m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"加载 skill 列表…"}),U.data&&U.data.data.length>0&&m.jsx("div",{className:"flex flex-wrap gap-1.5",children:U.data.data.map(ce=>{const ke=A.has(ce.name);return m.jsx("button",{type:"button",onClick:()=>le(ce.name),"aria-pressed":ke,className:["px-2.5 py-1 text-xs font-[family-name:var(--font-mono)] rounded-full border-2 transition-all",ke?"bg-[var(--color-accent-mint)] border-[var(--color-text)] shadow-[2px_2px_0_var(--color-text)] font-bold":"bg-[var(--color-bg)] border-[var(--color-border-light)] hover:border-[var(--color-text)]"].join(" "),children:ce.name},ce.name)})})]}),m.jsxs("div",{children:[m.jsx("div",{className:"text-sm font-bold mb-1.5",children:"Labels"}),m.jsxs("div",{className:"flex flex-wrap gap-1.5 items-center",children:[D.map(ce=>m.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-[family-name:var(--font-mono)] bg-[var(--color-accent-yellow)] border-2 border-[var(--color-text)] rounded-full",children:[ce,m.jsx("button",{type:"button",onClick:()=>W(ce),className:"hover:text-[var(--color-crashed)]","aria-label":`删除 ${ce}`,children:m.jsx(Er,{size:10,strokeWidth:3})})]},ce)),m.jsx("input",{type:"text",className:"nb-input",style:{padding:"4px 8px",fontSize:12,width:140},placeholder:"+ 添加 label",value:j,onChange:ce=>q(ce.target.value),onKeyDown:ce=>{ce.key==="Enter"&&!ce.nativeEvent.isComposing&&(ce.preventDefault(),ae())}}),j&&m.jsx("button",{type:"button",className:"nb-btn",style:{padding:"2px 6px",fontSize:11},onClick:ae,"aria-label":"添加 label",children:m.jsx(Xi,{size:10,strokeWidth:3})})]}),m.jsx("p",{className:"text-[10px] text-[var(--color-text-muted)] mt-1",children:"注意:AI-PIPELINE / STARTED-* / COMPLETED-* / NEEDS-FIX 由流水线自动管理,手动改可能被覆盖"})]})]}):m.jsxs(m.Fragment,{children:[f.skills.length>0&&m.jsxs("div",{children:[m.jsx("div",{className:"text-sm font-bold mb-1.5",children:"Skills"}),m.jsx("div",{className:"flex items-center gap-2 flex-wrap",children:f.skills.map(ce=>m.jsx(iS,{name:ce},ce))})]}),f.labels.length>0&&m.jsxs("div",{children:[m.jsx("div",{className:"text-sm font-bold mb-1.5",children:"Labels"}),m.jsx("div",{className:"flex items-center gap-2 flex-wrap",children:f.labels.map(ce=>m.jsx(aS,{label:ce,kind:ce==="NEEDS-FIX"?"warn":"default"},ce))})]})]}),x?m.jsxs(m.Fragment,{children:[m.jsxs("div",{children:[m.jsx("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold mb-2 uppercase tracking-wider",children:"描述"}),m.jsx("textarea",{className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",style:{minHeight:180,resize:"vertical"},value:k,onChange:ce=>_(ce.target.value),"aria-label":"卡片描述"}),m.jsx("p",{className:"text-[10px] text-[var(--color-text-muted)] mt-1",children:'只替换 "## 描述" 段的内容;检查清单和日志段不动。'})]}),(((C=f.checklist)==null?void 0:C.total)??0)>0&&m.jsxs("div",{className:"nb-card bg-[var(--color-bg-cream)] p-3",children:[m.jsx("div",{className:"flex items-center justify-between mb-2",children:m.jsxs("span",{className:"font-bold text-sm",children:["检查清单 ",((me=f.checklist)==null?void 0:me.done)??0,"/",((_e=f.checklist)==null?void 0:_e.total)??0]})}),m.jsx("ul",{className:"text-sm space-y-1",children:(((ve=f.checklist)==null?void 0:ve.items)??[]).map((ce,ke)=>m.jsxs("li",{className:`flex items-start gap-2 ${ce.done?"opacity-60 line-through":""}`,children:[m.jsx("span",{children:ce.done?"✓":"○"}),m.jsx("span",{children:ce.text})]},ke))})]})]}):m.jsxs(m.Fragment,{children:[m.jsxs("div",{children:[m.jsx("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold mb-2 uppercase tracking-wider",children:"描述"}),m.jsx("pre",{className:"text-xs whitespace-pre-wrap font-[family-name:var(--font-mono)] bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-lg p-4 max-h-64 overflow-auto",children:dp(f.body,"描述")||"(空)"})]}),m.jsxs("div",{children:[m.jsxs("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold mb-2 uppercase tracking-wider",children:["检查清单 ",m.jsxs("span",{className:"text-[var(--color-text-muted)] normal-case tracking-normal",children:[((V=f.checklist)==null?void 0:V.done)??0,"/",((pe=f.checklist)==null?void 0:pe.total)??0]})]}),m.jsx("div",{className:"nb-card bg-[var(--color-bg-cream)] p-3",children:(((R=f.checklist)==null?void 0:R.total)??0)>0?m.jsxs(m.Fragment,{children:[m.jsx("div",{className:"flex items-center justify-end mb-2",children:m.jsx("div",{className:"w-24 h-2 bg-[var(--color-bg)] border-2 border-[var(--color-text)] rounded-full overflow-hidden",children:m.jsx("div",{className:"h-full bg-[var(--color-cta)]",style:{width:`${((L=f.checklist)==null?void 0:L.percent)??0}%`}})})}),m.jsx("ul",{className:"text-sm space-y-1",children:(((J=f.checklist)==null?void 0:J.items)??[]).map((ce,ke)=>m.jsxs("li",{className:`flex items-start gap-2 ${ce.done?"opacity-60 line-through":""}`,children:[m.jsx("span",{children:ce.done?"✓":"○"}),m.jsx("span",{children:ce.text})]},ke))})]}):m.jsxs("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:["暂无清单项。在描述里用 ",m.jsx("code",{className:"font-[family-name:var(--font-mono)]",children:"- [ ] 项"})," 语法添加。"]})})]}),m.jsxs("div",{children:[m.jsx("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold mb-2 uppercase tracking-wider",children:"日志"}),m.jsx("pre",{className:"text-xs whitespace-pre-wrap font-[family-name:var(--font-mono)] bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-lg p-4 max-h-64 overflow-auto",children:dp(f.body,"日志")||"(空)"})]})]}),m.jsx("div",{className:"flex gap-2 pt-2 border-t-2 border-[var(--color-border-light)] justify-end flex-wrap",children:x?m.jsxs(m.Fragment,{children:[m.jsx("button",{className:"nb-btn",type:"button",onClick:()=>{v(!1),g()},disabled:P.isPending,children:"取消"}),m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"button",onClick:()=>P.mutate(),disabled:!G||!S.trim()||P.isPending,"aria-label":"保存卡片修改",children:[P.isPending?m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(Df,{size:14,strokeWidth:3}),"保存"]})]}):m.jsxs(m.Fragment,{children:[m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"button",disabled:f.state==="Done"||O,title:f.state==="Done"?"卡片已完成;先拖回 Todo 再启动":O?"Pipeline 正在跑——supervisor 会自动 dispatch,无需手动启动":void 0,onClick:async()=>{try{await VO(e,t),a()}catch(ce){c({title:"启动 worker 失败",body:ce instanceof Error?ce.message:String(ce)})}},children:[m.jsx(Kp,{size:14,strokeWidth:3}),"启动 worker"]}),m.jsxs("button",{className:"nb-btn nb-btn-yellow",type:"button",onClick:async()=>{if(await o({title:`重置卡片 #${t}`,body:"卡片状态会回到初始,已做的 checklist 会清空。",confirm:"重置",danger:!0}))try{await QO(e,t),a(),n()}catch(ke){c({title:"重置失败",body:ke instanceof Error?ke.message:String(ke)})}},children:[m.jsx(WE,{size:14,strokeWidth:2.5}),"重置卡片"]}),m.jsxs("button",{className:"nb-btn",style:{background:"var(--color-crashed)",color:"var(--color-bg)"},type:"button",onClick:async()=>{if(!(!await o({title:`删除卡片 #${t}`,body:`即将删除 "${f.title}"。此操作不可恢复(md 文件将被物理删除)。是否继续?`,confirm:"继续",danger:!0})||!await o({title:"最终确认",body:`请再次确认删除卡片 #${t}。`,confirm:"确定删除",danger:!0})))try{await YO(e,t),a(),n()}catch(Ke){c({title:"删除失败",body:Ke instanceof Error?Ke.message:String(Ke)})}},"aria-label":"删除卡片",children:[m.jsx(Il,{size:14,strokeWidth:2.5}),"删除卡片"]})]})})]})]})})}function mR({current:e,onChange:t}){const[n,a]=M.useState(!1),s=M.useRef(null),{data:o}=lt({queryKey:["projects"],queryFn:_r});return M.useEffect(()=>{const c=f=>{var d;(d=s.current)!=null&&d.contains(f.target)||a(!1)};return document.addEventListener("mousedown",c),()=>document.removeEventListener("mousedown",c)},[]),m.jsxs("div",{className:"relative",ref:s,children:[m.jsxs("button",{type:"button",className:"inline-flex items-center gap-2 px-3 py-2 bg-[var(--color-bg)] border-[3px] border-[var(--color-text)] rounded-xl shadow-[3px_3px_0_var(--color-text)] font-[family-name:var(--font-mono)] text-sm font-bold hover:-translate-x-px hover:-translate-y-px hover:shadow-[4px_4px_0_var(--color-text)] transition-[transform,box-shadow] duration-150",onClick:()=>a(c=>!c),children:[e,m.jsx(yc,{size:14,strokeWidth:2.5})]}),n&&o&&m.jsx("div",{className:"absolute right-0 mt-2 z-20 min-w-[200px] bg-[var(--color-bg)] border-[3px] border-[var(--color-text)] rounded-xl shadow-[5px_5px_0_var(--color-text)] overflow-hidden",children:o.data.map(c=>m.jsxs("button",{type:"button",onClick:()=>{t(c.name),a(!1)},className:["w-full text-left px-4 py-2 text-sm font-semibold",c.name===e?"bg-[var(--color-accent-mint)]":"hover:bg-[var(--color-bg-cream)]"].join(" "),children:[m.jsx("span",{className:"font-[family-name:var(--font-mono)]",children:c.name}),m.jsxs("span",{className:"ml-2 text-xs text-[var(--color-text-muted)]",children:[c.cards.total," cards"]})]},c.name))})]})}const pR=[{state:"Planning",label:"Planning",bg:"var(--color-accent-purple)"},{state:"Backlog",label:"Backlog",bg:"var(--color-bg-cream)"},{state:"Todo",label:"Todo",bg:"var(--color-accent-yellow)"},{state:"Inprogress",label:"Inprogress",bg:"var(--color-secondary)"},{state:"QA",label:"QA / Review",bg:"var(--color-accent-pink)"},{state:"Done",label:"Done",bg:"var(--color-accent-mint)"}],rS="sps-console:last-board-project";function gR(){if(typeof window>"u")return null;try{return localStorage.getItem(rS)}catch{return null}}function bR(e){if(!(typeof window>"u"))try{localStorage.setItem(rS,e)}catch{}}function yR(){var W,K,oe;const[e,t]=QE(),n=e.get("project"),[a,s]=M.useState(null),[o,c]=M.useState(""),[f,d]=M.useState(()=>new Set),[h,y]=M.useState(()=>new Set),{confirm:g,alert:x}=si();nR(n);const v=lt({queryKey:["projects"],queryFn:_r}),S=lt({queryKey:["cards",n],queryFn:()=>KO(n??""),enabled:!!n}),w=qn(),k=()=>{w.invalidateQueries({queryKey:["cards",n]}),w.invalidateQueries({queryKey:["projects"]}),w.invalidateQueries({queryKey:["pipeline-status",n]})},_=V=>{t({project:V})};M.useEffect(()=>{var pe;if(n){bR(n);return}const V=gR();V&&((pe=v.data)!=null&&pe.data.some(R=>R.name===V))&&t({project:V},{replace:!0})},[n,v.data,t]);const A=Pn({mutationFn:()=>JO(n),onSuccess:()=>{k()},onError:V=>{x({title:"启动 pipeline 失败",body:V instanceof Error?V.message:String(V)})}}),T=Pn({mutationFn:()=>eR(n),onSuccess:()=>k(),onError:V=>{x({title:"停止 pipeline 失败",body:V instanceof Error?V.message:String(V)})}}),D=Pn({mutationFn:()=>tR(n,{all:!0}),onSuccess:()=>k(),onError:V=>{x({title:"重置失败",body:V instanceof Error?V.message:String(V)})}}),[$,j]=M.useState(!1),q=Pn({mutationFn:V=>XO(n,V),onSuccess:()=>{k(),j(!1)},onError:V=>{x({title:"新建卡片失败",body:V instanceof Error?V.message:String(V)})}}),U=Pn({mutationFn:({seq:V,state:pe})=>ZO(n,V,pe),onMutate:async({seq:V,state:pe})=>{await w.cancelQueries({queryKey:["cards",n]});const R=w.getQueryData(["cards",n]);return R&&w.setQueryData(["cards",n],{...R,data:R.data.map(L=>L.seq===V?{...L,state:pe}:L)}),{prev:R}},onError:(V,pe,R)=>{R!=null&&R.prev&&w.setQueryData(["cards",n],R.prev),x({title:"移动卡片失败",body:V instanceof Error?V.message:String(V)})},onSettled:()=>{w.invalidateQueries({queryKey:["cards",n]})}}),Z=((W=S.data)==null?void 0:W.data)??[],{allSkills:O,allLabels:P}=M.useMemo(()=>{const V=new Set,pe=new Set;for(const R of Z){for(const L of R.skills)V.add(L);for(const L of R.labels)pe.add(L)}return{allSkills:[...V].sort(),allLabels:[...pe].sort()}},[Z]);if(!n)return m.jsxs("div",{className:"flex flex-col gap-6 max-w-4xl",children:[m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-4xl font-bold",children:"看板"}),m.jsxs("div",{className:"nb-card bg-[var(--color-accent-yellow)] max-w-2xl",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-xl font-bold mb-3",children:"选择一个项目 🎯"}),m.jsx("p",{className:"text-sm mb-4 text-[var(--color-text-muted)]",children:"看板按项目分。挑一个开始:"}),m.jsx("div",{className:"flex flex-wrap gap-2",children:(K=v.data)==null?void 0:K.data.map(V=>m.jsx("button",{className:"nb-btn nb-btn-blue",onClick:()=>_(V.name),type:"button",children:V.name},V.name))})]})]});const G=Z.filter(V=>{if(o){const pe=o.toLowerCase();if(!(V.title.toLowerCase().includes(pe)||V.skills.some(L=>L.toLowerCase().includes(pe))||V.labels.some(L=>L.toLowerCase().includes(pe))))return!1}return!(f.size>0&&!V.skills.some(R=>f.has(R))||h.size>0&&!V.labels.some(R=>h.has(R)))}),le=(oe=v.data)==null?void 0:oe.data.find(V=>V.name===n),ae=(le==null?void 0:le.pipelineStatus)==="running";return m.jsxs("div",{className:"flex flex-col gap-4 max-w-full",children:[m.jsxs("header",{className:"flex items-center justify-between flex-wrap gap-3",children:[m.jsxs("div",{children:[m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-4xl font-bold tracking-tight",children:"看板 ✨"}),m.jsx("p",{className:"text-[var(--color-text-muted)] text-sm mt-1",children:le?`${le.name} · ${le.cards.total} cards · ${le.workers.active} workers 活跃`:"加载中…"})]}),m.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[m.jsx(mR,{current:n,onChange:_}),m.jsxs("button",{className:ae?"nb-btn nb-btn-danger":"nb-btn nb-btn-primary",onClick:()=>ae?T.mutate():A.mutate(),disabled:A.isPending||T.isPending,type:"button","aria-label":ae?"停止 pipeline":"启动 pipeline",title:ae?"停止 pipeline":"启动 pipeline",children:[A.isPending||T.isPending?m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}):ae?m.jsx(e1,{size:14,strokeWidth:3}):m.jsx(Kp,{size:14,strokeWidth:3}),ae?"停止":"启动"]}),m.jsxs("button",{className:"nb-btn nb-btn-yellow",type:"button",onClick:async()=>{await g({title:"重置整个流水线",body:"这会清空所有卡片的运行状态、worker marker、分支。不可撤销。",confirm:"重置全部",danger:!0})&&D.mutate()},disabled:D.isPending,children:[D.isPending?m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(WE,{size:14,strokeWidth:2.5}),"重置"]}),m.jsxs("button",{className:"nb-btn nb-btn-mint",type:"button",onClick:()=>j(!0),disabled:q.isPending,children:[q.isPending?m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(Xi,{size:14,strokeWidth:3}),"新卡片"]})]})]}),m.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[m.jsxs("div",{className:"relative flex-1 max-w-md",children:[m.jsx(xf,{size:14,className:"absolute left-3 top-1/2 -translate-y-1/2 text-[var(--color-text-subtle)]"}),m.jsx("input",{className:"nb-input pl-9 w-full",placeholder:"搜索标题 / skill / label…",value:o,onChange:V=>c(V.target.value),"aria-label":"搜索卡片"})]}),m.jsx(Jv,{label:"skill",options:O,selected:f,onChange:d}),m.jsx(Jv,{label:"label",options:P,selected:h,onChange:y}),(o||f.size>0||h.size>0)&&m.jsxs("button",{className:"nb-btn",style:{padding:"4px 10px",fontSize:11},onClick:()=>{c(""),d(new Set),y(new Set)},type:"button","aria-label":"清空筛选",children:[m.jsx(Er,{size:11,strokeWidth:3}),"清空"]}),m.jsxs("span",{className:"text-xs text-[var(--color-text-muted)] flex items-center gap-1 font-[family-name:var(--font-mono)]",children:[m.jsx(KC,{size:12}),G.length," / ",Z.length]})]}),S.isError&&m.jsxs("div",{className:"nb-card bg-[var(--color-crashed-bg)]",children:[m.jsx("p",{className:"font-semibold",children:"加载卡片失败"}),m.jsx("p",{className:"text-sm mt-1 text-[var(--color-text-muted)]",children:S.error instanceof Error?S.error.message:String(S.error)})]}),!S.isError&&m.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6 gap-3",children:pR.map(V=>m.jsx(dR,{label:V.label,bg:V.bg,cards:G.filter(xR(V.state)),onCardClick:pe=>s(pe.seq),onDropCard:pe=>U.mutate({seq:pe,state:V.state})},V.state))}),a!==null&&m.jsx(hR,{project:n,seq:a,onClose:()=>s(null),onChanged:k}),$&&m.jsx(HO,{project:n,isPending:q.isPending,onCancel:()=>j(!1),onCreate:V=>q.mutate(V)})]})}function xR(e){return t=>e==="QA"?t.state==="QA"||t.state==="Review":e==="Done"?t.state==="Done"||t.state==="Canceled":t.state===e}function Jv({label:e,options:t,selected:n,onChange:a}){const[s,o]=M.useState(!1),c=M.useRef(null);M.useEffect(()=>{if(!s)return;const y=x=>{var v;(v=c.current)!=null&&v.contains(x.target)||o(!1)},g=x=>{x.key==="Escape"&&o(!1)};return window.addEventListener("click",y),window.addEventListener("keydown",g),()=>{window.removeEventListener("click",y),window.removeEventListener("keydown",g)}},[s]);const f=y=>{const g=new Set(n);g.has(y)?g.delete(y):g.add(y),a(g)},d=t.length===0,h=n.size;return m.jsxs("div",{ref:c,className:"relative",children:[m.jsxs("button",{type:"button",className:"nb-btn",style:{padding:"6px 12px",fontSize:12},onClick:()=>!d&&o(y=>!y),disabled:d,"aria-haspopup":"listbox","aria-expanded":s,"aria-label":`按 ${e} 筛选`,children:[e,h>0&&m.jsx("span",{className:"ml-1 px-1.5 py-0.5 text-[10px] font-bold rounded-full bg-[var(--color-primary)] text-[var(--color-text)] border border-[var(--color-text)]",children:h}),m.jsx(yc,{size:11,strokeWidth:3,className:["transition-transform",s?"rotate-180":""].join(" ")})]}),s&&m.jsxs("div",{role:"listbox",className:"absolute left-0 top-full mt-2 z-20 min-w-[200px] max-h-64 overflow-auto nb-card p-2",style:{padding:8},children:[t.map(y=>{const g=n.has(y);return m.jsxs("label",{className:["flex items-center gap-2 px-2 py-1.5 rounded cursor-pointer text-sm font-[family-name:var(--font-mono)]",g?"bg-[var(--color-accent-mint)]":"hover:bg-[var(--color-bg-cream)]"].join(" "),children:[m.jsx("input",{type:"checkbox",checked:g,onChange:()=>f(y),className:"flex-shrink-0"}),m.jsx("span",{className:"truncate",children:y})]},y)}),h>0&&m.jsx("button",{type:"button",className:"w-full mt-2 pt-2 border-t-2 border-dashed border-[var(--color-text)] text-xs font-bold text-[var(--color-crashed)] text-center",onClick:()=>a(new Set),children:"清空选择"})]})]})}function vR(){return Ht("/api/workers/all")}function ER(e){return Ht(`/api/projects/${encodeURIComponent(e)}/workers`)}function SR(e,t){return Ht(`/api/projects/${encodeURIComponent(e)}/workers/${t}`)}async function sS(e,t){const n=await fetch(e,{method:"POST",headers:t?{"Content-Type":"application/json"}:void 0,body:t?JSON.stringify(t):void 0});if(!n.ok)throw new Error(`${n.status}: ${await n.text()}`);return n.json().catch(()=>({}))}function e0(e,t){return sS(`/api/projects/${encodeURIComponent(e)}/workers/${t}/kill`)}function wR(e,t,n){return sS(`/api/projects/${encodeURIComponent(e)}/workers/${t}/launch`,n?{seq:n}:void 0)}function og({state:e}){const n={running:{bg:"var(--color-running-bg)",color:"var(--color-running)",label:"running"},starting:{bg:"var(--color-secondary)",color:"var(--color-text)",label:"starting",icon:m.jsx(Wt,{size:9,strokeWidth:3,className:"animate-spin"})},stuck:{bg:"var(--color-stuck-bg)",color:"var(--color-stuck)",label:"stuck"},crashed:{bg:"var(--color-crashed-bg)",color:"var(--color-crashed)",label:"crashed",icon:m.jsx(SA,{size:9,strokeWidth:2.5})},idle:{bg:"var(--color-idle-bg)",color:"var(--color-idle)",label:"idle"}}[e];return m.jsxs("span",{className:"nb-status inline-flex items-center gap-1",style:{background:n.bg,color:n.color},children:[n.icon,n.label]})}function cg(e){if(e==null||e<=0)return"—";const t=Math.floor(e/1e3),n=Math.floor(t/3600),a=Math.floor(t%3600/60),s=t%60;return n>0?`${n}h ${a}m`:a>0?`${a}m ${s}s`:`${s}s`}function _R(e){if(e==null||e<=0)return"text-[var(--color-text-muted)]";const t=e/6e4;return t<10?"text-[var(--color-running)]":t<60?"text-[var(--color-stuck)]":"text-[var(--color-crashed)]"}function ug(e){const t=Date.now()-new Date(e).getTime();return t<6e4?`${Math.floor(t/1e3)}s 前`:t<36e5?`${Math.floor(t/6e4)}m 前`:`${Math.floor(t/36e5)}h 前`}function kR({alerts:e,selected:t,onSelect:n}){return e.length===0?m.jsxs("div",{className:"nb-card bg-[var(--color-running-bg)] flex items-center gap-3",children:[m.jsx(Pp,{size:18,strokeWidth:2.5,className:"text-[var(--color-running)]"}),m.jsx("span",{className:"text-sm font-bold text-[var(--color-running)]",children:"全部 worker 健康"})]}):m.jsxs("section",{children:[m.jsxs("h2",{className:"font-[family-name:var(--font-heading)] text-sm font-bold uppercase tracking-wider mb-2 flex items-center gap-2 text-[var(--color-crashed)]",children:[m.jsx(RA,{size:14,strokeWidth:2.5}),"Alerts (",e.length,")"]}),m.jsx("div",{className:"flex flex-col gap-2",children:e.map(a=>{const s=(t==null?void 0:t.project)===a.project&&(t==null?void 0:t.slot)===a.slot;return m.jsxs("button",{type:"button",onClick:()=>n(a.project,a.slot),className:["nb-card p-3 text-left",a.state==="crashed"?"bg-[var(--color-crashed-bg)]":"bg-[var(--color-stuck-bg)]",s?"ring-4 ring-[var(--color-text)]":""].join(" "),children:[m.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[m.jsx(og,{state:a.state}),m.jsxs("span",{className:"font-[family-name:var(--font-mono)] font-bold",children:[a.project,"/worker-",a.slot]}),a.card&&m.jsxs("span",{className:"truncate",children:["#",a.card.seq," ",a.card.title]}),m.jsxs("span",{className:"ml-auto text-xs text-[var(--color-text-muted)] font-[family-name:var(--font-mono)] flex items-center gap-1",children:[m.jsx(MC,{size:10,strokeWidth:2.5}),cg(a.runtimeMs)]})]}),a.markerUpdatedAt&&m.jsx("div",{className:"text-xs text-[var(--color-text-muted)] mt-1 font-[family-name:var(--font-mono)]",children:a.state==="crashed"?"PID 已死。":`marker 停 ${ug(a.markerUpdatedAt)}。`})]},`${a.project}-${a.slot}`)})})]})}function NR({active:e,selected:t,onSelect:n}){return e.length===0?m.jsx("div",{className:"nb-card bg-[var(--color-bg-cream)]",children:m.jsx("p",{className:"text-sm text-[var(--color-text-muted)] italic",children:"没有 worker 在运行。"})}):m.jsxs("section",{children:[m.jsxs("h2",{className:"font-[family-name:var(--font-heading)] text-sm font-bold uppercase tracking-wider mb-2 flex items-center gap-2",children:[m.jsx(jf,{size:14,strokeWidth:2.5}),"Active (",e.length,")"]}),m.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-3",children:e.map(a=>{const s=(t==null?void 0:t.project)===a.project&&(t==null?void 0:t.slot)===a.slot;return m.jsxs("button",{type:"button",onClick:()=>n(a.project,a.slot),className:["nb-card p-3 text-left",a.state==="starting"?"bg-[var(--color-secondary)]":"bg-[var(--color-running-bg)]",s?"ring-4 ring-[var(--color-text)]":""].join(" "),children:[m.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[m.jsx(og,{state:a.state}),m.jsxs("span",{className:"font-[family-name:var(--font-mono)] font-bold text-sm flex-1 truncate",children:[a.project,"/worker-",a.slot]}),m.jsx("span",{className:`text-xs font-[family-name:var(--font-mono)] ${_R(a.runtimeMs)}`,children:cg(a.runtimeMs)})]}),a.card&&m.jsxs("div",{className:"text-sm font-semibold mb-1 truncate",children:["#",a.card.seq," · ",a.card.title]}),m.jsxs("div",{className:"text-xs text-[var(--color-text-muted)] font-[family-name:var(--font-mono)] flex items-center gap-2 mb-1",children:[a.stage&&m.jsxs("span",{children:["stage: ",a.stage]}),a.markerUpdatedAt&&m.jsxs("span",{className:"ml-auto",children:["marker ",ug(a.markerUpdatedAt)]})]}),a.lastLogLine&&m.jsxs("div",{className:"text-[11px] font-[family-name:var(--font-mono)] text-[var(--color-text-muted)] bg-[var(--color-bg)] border-2 border-[var(--color-text)] rounded px-2 py-1 mt-2 truncate",children:[m.jsx(t1,{size:9,strokeWidth:2.5,className:"inline-block mr-1 align-text-bottom"}),a.lastLogLine.msg]})]},`${a.project}-${a.slot}`)})})]})}function TR({capacity:e,selected:t,onSelect:n}){return e.length===0?null:m.jsxs("section",{children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-sm font-bold uppercase tracking-wider mb-2",children:"Capacity"}),m.jsx("div",{className:"nb-card p-0 overflow-hidden",children:m.jsxs("table",{className:"w-full text-sm",children:[m.jsx("thead",{children:m.jsxs("tr",{className:"bg-[var(--color-bg-cream)] border-b-2 border-[var(--color-text)]",children:[m.jsx("th",{className:"px-3 py-2 text-left font-bold text-xs uppercase tracking-wider",children:"项目"}),m.jsx("th",{className:"px-3 py-2 text-left font-bold text-xs uppercase tracking-wider",children:"占用"}),m.jsx("th",{className:"px-3 py-2 text-right font-bold text-xs uppercase tracking-wider",children:"running"}),m.jsx("th",{className:"px-3 py-2 text-right font-bold text-xs uppercase tracking-wider",children:"其它"}),m.jsx("th",{className:"px-3 py-2"})]})}),m.jsx("tbody",{children:e.map(a=>{const s=a.running+a.starting+a.stuck+a.crashed,o=(t==null?void 0:t.project)===a.project;return m.jsxs("tr",{onClick:()=>n(a.project),className:["border-b border-dashed border-[var(--color-border-light)] last:border-0 cursor-pointer hover:bg-[var(--color-accent-yellow)]",o?"bg-[var(--color-accent-yellow)]":""].join(" "),children:[m.jsx("td",{className:"px-3 py-2 font-[family-name:var(--font-mono)] font-bold",children:a.project}),m.jsx("td",{className:"px-3 py-2",children:m.jsx(CR,{total:a.total,cap:a})}),m.jsxs("td",{className:"px-3 py-2 text-right font-[family-name:var(--font-mono)]",children:[m.jsx("span",{className:"text-[var(--color-running)] font-bold",children:a.running}),m.jsxs("span",{className:"text-[var(--color-text-muted)]",children:["/",a.total]})]}),m.jsxs("td",{className:"px-3 py-2 text-right text-xs font-[family-name:var(--font-mono)] text-[var(--color-text-muted)]",children:[a.starting>0&&m.jsxs("span",{className:"mr-2",children:["starting ",a.starting]}),a.stuck>0&&m.jsxs("span",{className:"text-[var(--color-stuck)] font-bold mr-2",children:["stuck ",a.stuck]}),a.crashed>0&&m.jsxs("span",{className:"text-[var(--color-crashed)] font-bold mr-2",children:["crashed ",a.crashed]}),s===0&&m.jsx("span",{children:"idle"})]}),m.jsx("td",{className:"px-3 py-2 text-right",children:m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:"详情 →"})})]},a.project)})})]})})]})}function CR({total:e,cap:t}){const n=[];for(let a=0;a<t.crashed;a++)n.push("crashed");for(let a=0;a<t.stuck;a++)n.push("stuck");for(let a=0;a<t.starting;a++)n.push("starting");for(let a=0;a<t.running;a++)n.push("running");for(let a=0;a<t.idle;a++)n.push("idle");return m.jsxs("div",{className:"flex gap-1 items-center",children:[n.map((a,s)=>m.jsx("span",{className:"inline-block w-3 h-3 rounded-full border-2 border-[var(--color-text)]",style:{background:AR(a)},title:a},s)),m.jsxs("span",{className:"text-xs text-[var(--color-text-muted)] ml-2 font-[family-name:var(--font-mono)]",children:[e," slot",e!==1?"s":""]})]})}function AR(e){switch(e){case"running":return"var(--color-running-bg)";case"starting":return"var(--color-secondary)";case"stuck":return"var(--color-stuck-bg)";case"crashed":return"var(--color-crashed-bg)";default:return"var(--color-idle-bg)"}}function OR({project:e,initialSlot:t,onChange:n}){var d;const a=lt({queryKey:["workers",e],queryFn:()=>ER(e),refetchInterval:3e3}),s=((d=a.data)==null?void 0:d.data)??[],[o,c]=M.useState(null);M.useEffect(()=>{if(s.length===0){c(null);return}const h=s[0].slot;c(y=>y!=null&&s.some(g=>g.slot===y)?y:t!=null&&s.some(g=>g.slot===t)?t:h)},[e,t,s.length]);const f=s.find(h=>h.slot===o)??null;return m.jsxs("div",{className:"flex flex-col h-full",children:[m.jsxs("div",{className:"px-4 py-3 border-b-2 border-[var(--color-text)] bg-[var(--color-bg-cream)]",children:[m.jsxs("div",{className:"flex items-center justify-between mb-2",children:[m.jsx("span",{className:"font-[family-name:var(--font-mono)] font-bold truncate",children:e}),m.jsx(ds,{to:`/board?project=${encodeURIComponent(e)}`,className:"text-xs underline text-[var(--color-text-muted)] hover:text-[var(--color-text)]",children:"看板 →"})]}),a.isLoading&&s.length===0?m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"加载 workers…"}):s.length===0?m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"该项目没有 worker slot。"}):m.jsx("div",{className:"flex flex-wrap gap-2",children:s.map(h=>m.jsx(RR,{worker:h,active:h.slot===o,onClick:()=>c(h.slot)},h.slot))})]}),f?m.jsx(MR,{project:e,worker:f,onChange:n}):m.jsx("div",{className:"flex-1 flex items-center justify-center p-6 text-center",children:m.jsx("p",{className:"text-sm text-[var(--color-text-muted)]",children:s.length===0?"无 worker":"请选择一个 worker"})})]})}function RR({worker:e,active:t,onClick:n}){return m.jsxs("button",{type:"button",onClick:n,className:["nb-card p-2 text-left min-w-[130px] transition-transform",t?"ring-4 ring-[var(--color-text)]":"opacity-80 hover:opacity-100"].join(" "),children:[m.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[m.jsx(og,{state:e.state}),m.jsxs("span",{className:"font-[family-name:var(--font-mono)] font-bold text-xs",children:["worker-",e.slot]})]}),e.card?m.jsxs("div",{className:"text-[11px] truncate font-[family-name:var(--font-mono)]",children:["#",e.card.seq," ",e.card.title]}):m.jsx("div",{className:"text-[11px] text-[var(--color-text-muted)] italic",children:"空闲"})]})}function MR({project:e,worker:t,onChange:n}){var h,y;const{confirm:a,alert:s}=si(),o=t.state==="crashed"||t.state==="stuck",c=lt({queryKey:["worker-detail",e,t.slot],queryFn:()=>SR(e,t.slot),refetchInterval:3e3}),f=((h=c.data)==null?void 0:h.recentOutput)??[],d=((y=c.data)==null?void 0:y.recentLogs)??[];return m.jsxs(m.Fragment,{children:[m.jsxs("div",{className:"flex-1 overflow-auto p-4 flex flex-col gap-4",children:[t.card?m.jsxs("div",{children:[m.jsx("div",{className:"text-xs font-bold uppercase tracking-wider text-[var(--color-text-muted)] mb-1",children:"当前卡片"}),m.jsxs("div",{className:"text-sm font-semibold break-words",children:["#",t.card.seq," · ",t.card.title]})]}):m.jsx("div",{className:"text-sm text-[var(--color-text-muted)] italic",children:"slot 空闲,没有当前卡片。"}),m.jsxs("dl",{className:"grid grid-cols-[100px_1fr] gap-y-2 text-sm",children:[m.jsx("dt",{className:"font-bold",children:"Stage"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:t.stage??"—"}),m.jsx("dt",{className:"font-bold",children:"PID"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:t.pid??"—"}),m.jsx("dt",{className:"font-bold",children:"Runtime"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:cg(t.runtimeMs)}),m.jsx("dt",{className:"font-bold",children:"Started"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)] text-xs",children:t.startedAt?new Date(t.startedAt).toLocaleString():"—"}),m.jsx("dt",{className:"font-bold",children:"Marker"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)] text-xs",children:t.markerUpdatedAt?ug(t.markerUpdatedAt):"—"})]}),m.jsxs("div",{children:[m.jsxs("div",{className:"text-xs font-bold uppercase tracking-wider text-[var(--color-text-muted)] mb-1 flex items-center gap-1",children:[m.jsx(t1,{size:10,strokeWidth:2.5}),"Claude 输出 · 最近 ",f.length," 行"]}),c.isLoading&&f.length===0?m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"加载中…"}):f.length===0?m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"还没收到 session 输出。Worker 刚启动时需要几秒。"}):m.jsx("pre",{className:"text-xs font-[family-name:var(--font-mono)] bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded p-2 max-h-80 overflow-auto whitespace-pre-wrap break-words",children:f.map(g=>`${g.ts?`${g.ts} [${g.kind}] `:`[${g.kind}] `}${g.text}`).join(`
477
+ `).trim()}function vm(e){return dp(e,"描述")}function hR({project:e,seq:t,onClose:n,onChanged:a}){var K,oe,V,pe,R,L,J,C,me,_e,ve;const s=qn(),{confirm:o,alert:c}=si(),{data:f,isLoading:d,isError:h,error:y,refetch:g}=lt({queryKey:["card",e,t],queryFn:()=>GO(e,t)}),[x,v]=M.useState(!1),[S,w]=M.useState(""),[k,_]=M.useState(""),[A,T]=M.useState(new Set),[D,$]=M.useState([]),[j,q]=M.useState(""),U=lt({queryKey:["skills-all",e],queryFn:()=>lg(e),enabled:x}),O=((oe=(K=lt({queryKey:["projects"],queryFn:_r,refetchInterval:1e4}).data)==null?void 0:K.data.find(ce=>ce.name===e))==null?void 0:oe.pipelineStatus)==="running";M.useEffect(()=>{x&&f&&(w(f.title),_(vm(f.body)),T(new Set(f.skills)),$([...f.labels]))},[x,f]),M.useEffect(()=>{const ce=ke=>{ke.key==="Escape"&&(x?v(!1):n())};return window.addEventListener("keydown",ce),()=>window.removeEventListener("keydown",ce)},[n,x]);const P=Pn({mutationFn:()=>{if(!f)throw new Error("no data");const ce={},ke=S.trim();ke&&ke!==f.title&&(ce.title=ke);const Ke=vm(f.body);k!==Ke&&(ce.description=k);const Dt=[...A].sort(),yn=[...f.skills].sort();return JSON.stringify(Dt)!==JSON.stringify(yn)&&(ce.skills=Dt),JSON.stringify(D)!==JSON.stringify(f.labels)&&(ce.labels=D),Object.keys(ce).length===0?Promise.resolve({ok:!0,noop:!0}):WO(e,t,ce)},onSuccess:()=>{s.invalidateQueries({queryKey:["card",e,t]}),s.invalidateQueries({queryKey:["cards",e]}),v(!1),a()},onError:ce=>{c({title:"保存失败",body:ce instanceof Error?ce.message:String(ce)})}}),G=M.useMemo(()=>{if(!x||!f)return!1;if(S.trim()!==f.title||k!==vm(f.body))return!0;const ce=[...A].sort(),ke=[...f.skills].sort();return JSON.stringify(ce)!==JSON.stringify(ke)||JSON.stringify(D)!==JSON.stringify(f.labels)},[x,f,S,k,A,D]),le=ce=>{const ke=new Set(A);ke.has(ce)?ke.delete(ce):ke.add(ce),T(ke)},ae=()=>{const ce=j.trim();if(ce){if(D.includes(ce)){q("");return}$([...D,ce]),q("")}},W=ce=>{$(D.filter(ke=>ke!==ce))};return m.jsx("div",{role:"dialog","aria-modal":"true","aria-labelledby":"card-modal-title",className:"fixed inset-0 z-40 flex items-start justify-center p-6 bg-black/30 overflow-auto",children:m.jsxs("div",{className:"nb-card mt-12 w-full max-w-3xl bg-[var(--color-bg)]",children:[m.jsxs("header",{className:"flex items-start justify-between gap-4 mb-4",children:[m.jsxs("div",{className:"flex-1 min-w-0",children:[m.jsxs("div",{className:"flex items-center gap-3 mb-1",children:[m.jsxs("span",{className:"font-[family-name:var(--font-mono)] font-bold text-xs px-2 py-0.5 bg-[var(--color-accent-purple)] border-2 border-[var(--color-text)] rounded-full",children:["#",t]}),(f==null?void 0:f.state)&&m.jsx("span",{className:"font-[family-name:var(--font-mono)] text-xs px-2 py-0.5 bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-full font-semibold",children:f.state}),x&&m.jsx("span",{className:"text-xs font-bold text-[var(--color-stuck)]",children:"⚠ 编辑中"})]}),x?m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-heading)] text-xl font-bold",value:S,onChange:ce=>w(ce.target.value),maxLength:200,"aria-label":"卡片标题"}):m.jsx("h2",{id:"card-modal-title",className:"font-[family-name:var(--font-heading)] text-2xl font-bold break-words",children:(f==null?void 0:f.title)??"加载中…"})]}),m.jsxs("div",{className:"flex gap-2 flex-shrink-0",children:[!x&&f&&m.jsxs("button",{onClick:()=>v(!0),className:"nb-btn",style:{padding:"6px 12px"},type:"button","aria-label":"编辑卡片",children:[m.jsx(Hp,{size:12,strokeWidth:2.5})," 编辑"]}),m.jsx("button",{onClick:n,className:"nb-btn nb-btn-mint p-2","aria-label":"关闭",type:"button",children:m.jsx(Er,{size:14,strokeWidth:3})})]})]}),d&&m.jsx("p",{className:"text-[var(--color-text-muted)]",children:"加载中…"}),h&&m.jsxs("p",{className:"text-[var(--color-crashed)]",children:["加载失败: ",y instanceof Error?y.message:String(y)]}),f&&m.jsxs("div",{className:"flex flex-col gap-4",children:[f.branch&&!x&&m.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[m.jsx(QC,{size:14}),m.jsx("span",{className:"font-[family-name:var(--font-mono)]",children:f.branch})]}),x?m.jsxs(m.Fragment,{children:[m.jsxs("div",{children:[m.jsx("div",{className:"text-sm font-bold mb-1.5",children:"Skills"}),U.isLoading&&m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"加载 skill 列表…"}),U.data&&U.data.data.length>0&&m.jsx("div",{className:"flex flex-wrap gap-1.5",children:U.data.data.map(ce=>{const ke=A.has(ce.name);return m.jsx("button",{type:"button",onClick:()=>le(ce.name),"aria-pressed":ke,className:["px-2.5 py-1 text-xs font-[family-name:var(--font-mono)] rounded-full border-2 transition-all",ke?"bg-[var(--color-accent-mint)] border-[var(--color-text)] shadow-[2px_2px_0_var(--color-text)] font-bold":"bg-[var(--color-bg)] border-[var(--color-border-light)] hover:border-[var(--color-text)]"].join(" "),children:ce.name},ce.name)})})]}),m.jsxs("div",{children:[m.jsx("div",{className:"text-sm font-bold mb-1.5",children:"Labels"}),m.jsxs("div",{className:"flex flex-wrap gap-1.5 items-center",children:[D.map(ce=>m.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-[family-name:var(--font-mono)] bg-[var(--color-accent-yellow)] border-2 border-[var(--color-text)] rounded-full",children:[ce,m.jsx("button",{type:"button",onClick:()=>W(ce),className:"hover:text-[var(--color-crashed)]","aria-label":`删除 ${ce}`,children:m.jsx(Er,{size:10,strokeWidth:3})})]},ce)),m.jsx("input",{type:"text",className:"nb-input",style:{padding:"4px 8px",fontSize:12,width:140},placeholder:"+ 添加 label",value:j,onChange:ce=>q(ce.target.value),onKeyDown:ce=>{ce.key==="Enter"&&!ce.nativeEvent.isComposing&&(ce.preventDefault(),ae())}}),j&&m.jsx("button",{type:"button",className:"nb-btn",style:{padding:"2px 6px",fontSize:11},onClick:ae,"aria-label":"添加 label",children:m.jsx(Xi,{size:10,strokeWidth:3})})]}),m.jsx("p",{className:"text-[10px] text-[var(--color-text-muted)] mt-1",children:"注意:AI-PIPELINE / STARTED-* / COMPLETED-* / NEEDS-FIX 由流水线自动管理,手动改可能被覆盖"})]})]}):m.jsxs(m.Fragment,{children:[f.skills.length>0&&m.jsxs("div",{children:[m.jsx("div",{className:"text-sm font-bold mb-1.5",children:"Skills"}),m.jsx("div",{className:"flex items-center gap-2 flex-wrap",children:f.skills.map(ce=>m.jsx(iS,{name:ce},ce))})]}),f.labels.length>0&&m.jsxs("div",{children:[m.jsx("div",{className:"text-sm font-bold mb-1.5",children:"Labels"}),m.jsx("div",{className:"flex items-center gap-2 flex-wrap",children:f.labels.map(ce=>m.jsx(aS,{label:ce,kind:ce==="NEEDS-FIX"?"warn":"default"},ce))})]})]}),x?m.jsxs(m.Fragment,{children:[m.jsxs("div",{children:[m.jsx("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold mb-2 uppercase tracking-wider",children:"描述"}),m.jsx("textarea",{className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",style:{minHeight:180,resize:"vertical"},value:k,onChange:ce=>_(ce.target.value),"aria-label":"卡片描述"}),m.jsx("p",{className:"text-[10px] text-[var(--color-text-muted)] mt-1",children:'只替换 "## 描述" 段的内容;检查清单和日志段不动。'})]}),(((C=f.checklist)==null?void 0:C.total)??0)>0&&m.jsxs("div",{className:"nb-card bg-[var(--color-bg-cream)] p-3",children:[m.jsx("div",{className:"flex items-center justify-between mb-2",children:m.jsxs("span",{className:"font-bold text-sm",children:["检查清单 ",((me=f.checklist)==null?void 0:me.done)??0,"/",((_e=f.checklist)==null?void 0:_e.total)??0]})}),m.jsx("ul",{className:"text-sm space-y-1",children:(((ve=f.checklist)==null?void 0:ve.items)??[]).map((ce,ke)=>m.jsxs("li",{className:`flex items-start gap-2 ${ce.done?"opacity-60 line-through":""}`,children:[m.jsx("span",{children:ce.done?"✓":"○"}),m.jsx("span",{children:ce.text})]},ke))})]})]}):m.jsxs(m.Fragment,{children:[m.jsxs("div",{children:[m.jsx("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold mb-2 uppercase tracking-wider",children:"描述"}),m.jsx("pre",{className:"text-xs whitespace-pre-wrap font-[family-name:var(--font-mono)] bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-lg p-4 max-h-64 overflow-auto",children:dp(f.body,"描述")||"(空)"})]}),m.jsxs("div",{children:[m.jsxs("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold mb-2 uppercase tracking-wider",children:["检查清单 ",m.jsxs("span",{className:"text-[var(--color-text-muted)] normal-case tracking-normal",children:[((V=f.checklist)==null?void 0:V.done)??0,"/",((pe=f.checklist)==null?void 0:pe.total)??0]})]}),m.jsx("div",{className:"nb-card bg-[var(--color-bg-cream)] p-3",children:(((R=f.checklist)==null?void 0:R.total)??0)>0?m.jsxs(m.Fragment,{children:[m.jsx("div",{className:"flex items-center justify-end mb-2",children:m.jsx("div",{className:"w-24 h-2 bg-[var(--color-bg)] border-2 border-[var(--color-text)] rounded-full overflow-hidden",children:m.jsx("div",{className:"h-full bg-[var(--color-cta)]",style:{width:`${((L=f.checklist)==null?void 0:L.percent)??0}%`}})})}),m.jsx("ul",{className:"text-sm space-y-1",children:(((J=f.checklist)==null?void 0:J.items)??[]).map((ce,ke)=>m.jsxs("li",{className:`flex items-start gap-2 ${ce.done?"opacity-60 line-through":""}`,children:[m.jsx("span",{children:ce.done?"✓":"○"}),m.jsx("span",{children:ce.text})]},ke))})]}):m.jsxs("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:["暂无清单项。在描述里用 ",m.jsx("code",{className:"font-[family-name:var(--font-mono)]",children:"- [ ] 项"})," 语法添加。"]})})]}),m.jsxs("div",{children:[m.jsx("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold mb-2 uppercase tracking-wider",children:"日志"}),m.jsx("pre",{className:"text-xs whitespace-pre-wrap font-[family-name:var(--font-mono)] bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-lg p-4 max-h-64 overflow-auto",children:dp(f.body,"日志")||"(空)"})]})]}),m.jsx("div",{className:"flex gap-2 pt-2 border-t-2 border-[var(--color-border-light)] justify-end flex-wrap",children:x?m.jsxs(m.Fragment,{children:[m.jsx("button",{className:"nb-btn",type:"button",onClick:()=>{v(!1),g()},disabled:P.isPending,children:"取消"}),m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"button",onClick:()=>P.mutate(),disabled:!G||!S.trim()||P.isPending,"aria-label":"保存卡片修改",children:[P.isPending?m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(Df,{size:14,strokeWidth:3}),"保存"]})]}):m.jsxs(m.Fragment,{children:[m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"button",disabled:f.state==="Done"||O,title:f.state==="Done"?"卡片已完成;先拖回 Todo 再启动":O?"Pipeline 正在跑——supervisor 会自动 dispatch,无需手动启动":void 0,onClick:async()=>{try{await VO(e,t),a()}catch(ce){c({title:"启动 worker 失败",body:ce instanceof Error?ce.message:String(ce)})}},children:[m.jsx(Kp,{size:14,strokeWidth:3}),"启动 worker"]}),m.jsxs("button",{className:"nb-btn nb-btn-yellow",type:"button",onClick:async()=>{if(await o({title:`重置卡片 #${t}`,body:"卡片状态会回到初始,已做的 checklist 会清空。",confirm:"重置",danger:!0}))try{await QO(e,t),a(),n()}catch(ke){c({title:"重置失败",body:ke instanceof Error?ke.message:String(ke)})}},children:[m.jsx(WE,{size:14,strokeWidth:2.5}),"重置卡片"]}),m.jsxs("button",{className:"nb-btn",style:{background:"var(--color-crashed)",color:"var(--color-bg)"},type:"button",onClick:async()=>{if(!(!await o({title:`删除卡片 #${t}`,body:`即将删除 "${f.title}"。此操作不可恢复(md 文件将被物理删除)。是否继续?`,confirm:"继续",danger:!0})||!await o({title:"最终确认",body:`请再次确认删除卡片 #${t}。`,confirm:"确定删除",danger:!0})))try{await YO(e,t),a(),n()}catch(Ke){c({title:"删除失败",body:Ke instanceof Error?Ke.message:String(Ke)})}},"aria-label":"删除卡片",children:[m.jsx(Il,{size:14,strokeWidth:2.5}),"删除卡片"]})]})})]})]})})}function mR({current:e,onChange:t}){const[n,a]=M.useState(!1),s=M.useRef(null),{data:o}=lt({queryKey:["projects"],queryFn:_r});return M.useEffect(()=>{const c=f=>{var d;(d=s.current)!=null&&d.contains(f.target)||a(!1)};return document.addEventListener("mousedown",c),()=>document.removeEventListener("mousedown",c)},[]),m.jsxs("div",{className:"relative",ref:s,children:[m.jsxs("button",{type:"button",className:"inline-flex items-center gap-2 px-3 py-2 bg-[var(--color-bg)] border-[3px] border-[var(--color-text)] rounded-xl shadow-[3px_3px_0_var(--color-text)] font-[family-name:var(--font-mono)] text-sm font-bold hover:-translate-x-px hover:-translate-y-px hover:shadow-[4px_4px_0_var(--color-text)] transition-[transform,box-shadow] duration-150",onClick:()=>a(c=>!c),children:[e,m.jsx(yc,{size:14,strokeWidth:2.5})]}),n&&o&&m.jsx("div",{className:"absolute right-0 mt-2 z-20 min-w-[200px] bg-[var(--color-bg)] border-[3px] border-[var(--color-text)] rounded-xl shadow-[5px_5px_0_var(--color-text)] overflow-hidden",children:o.data.map(c=>m.jsxs("button",{type:"button",onClick:()=>{t(c.name),a(!1)},className:["w-full text-left px-4 py-2 text-sm font-semibold",c.name===e?"bg-[var(--color-accent-mint)]":"hover:bg-[var(--color-bg-cream)]"].join(" "),children:[m.jsx("span",{className:"font-[family-name:var(--font-mono)]",children:c.name}),m.jsxs("span",{className:"ml-2 text-xs text-[var(--color-text-muted)]",children:[c.cards.total," cards"]})]},c.name))})]})}const pR=[{state:"Planning",label:"Planning",bg:"var(--color-accent-purple)"},{state:"Backlog",label:"Backlog",bg:"var(--color-bg-cream)"},{state:"Todo",label:"Todo",bg:"var(--color-accent-yellow)"},{state:"Inprogress",label:"Inprogress",bg:"var(--color-secondary)"},{state:"QA",label:"QA / Review",bg:"var(--color-accent-pink)"},{state:"Done",label:"Done",bg:"var(--color-accent-mint)"}],rS="sps-console:last-board-project";function gR(){if(typeof window>"u")return null;try{return localStorage.getItem(rS)}catch{return null}}function bR(e){if(!(typeof window>"u"))try{localStorage.setItem(rS,e)}catch{}}function yR(){var W,K,oe;const[e,t]=QE(),n=e.get("project"),[a,s]=M.useState(null),[o,c]=M.useState(""),[f,d]=M.useState(()=>new Set),[h,y]=M.useState(()=>new Set),{confirm:g,alert:x}=si();nR(n);const v=lt({queryKey:["projects"],queryFn:_r}),S=lt({queryKey:["cards",n],queryFn:()=>KO(n??""),enabled:!!n}),w=qn(),k=()=>{w.invalidateQueries({queryKey:["cards",n]}),w.invalidateQueries({queryKey:["projects"]}),w.invalidateQueries({queryKey:["pipeline-status",n]})},_=V=>{t({project:V})};M.useEffect(()=>{var pe;if(n){bR(n);return}const V=gR();V&&((pe=v.data)!=null&&pe.data.some(R=>R.name===V))&&t({project:V},{replace:!0})},[n,v.data,t]);const A=Pn({mutationFn:()=>JO(n),onSuccess:()=>{k()},onError:V=>{x({title:"启动 pipeline 失败",body:V instanceof Error?V.message:String(V)})}}),T=Pn({mutationFn:()=>eR(n),onSuccess:()=>k(),onError:V=>{x({title:"停止 pipeline 失败",body:V instanceof Error?V.message:String(V)})}}),D=Pn({mutationFn:()=>tR(n,{all:!0}),onSuccess:()=>k(),onError:V=>{x({title:"重置失败",body:V instanceof Error?V.message:String(V)})}}),[$,j]=M.useState(!1),q=Pn({mutationFn:V=>XO(n,V),onSuccess:()=>{k(),j(!1)},onError:V=>{x({title:"新建卡片失败",body:V instanceof Error?V.message:String(V)})}}),U=Pn({mutationFn:({seq:V,state:pe})=>ZO(n,V,pe),onMutate:async({seq:V,state:pe})=>{await w.cancelQueries({queryKey:["cards",n]});const R=w.getQueryData(["cards",n]);return R&&w.setQueryData(["cards",n],{...R,data:R.data.map(L=>L.seq===V?{...L,state:pe}:L)}),{prev:R}},onError:(V,pe,R)=>{R!=null&&R.prev&&w.setQueryData(["cards",n],R.prev),x({title:"移动卡片失败",body:V instanceof Error?V.message:String(V)})},onSettled:()=>{w.invalidateQueries({queryKey:["cards",n]})}}),Z=((W=S.data)==null?void 0:W.data)??[],{allSkills:O,allLabels:P}=M.useMemo(()=>{const V=new Set,pe=new Set;for(const R of Z){for(const L of R.skills)V.add(L);for(const L of R.labels)pe.add(L)}return{allSkills:[...V].sort(),allLabels:[...pe].sort()}},[Z]);if(!n)return m.jsxs("div",{className:"flex flex-col gap-6 max-w-4xl",children:[m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-4xl font-bold",children:"看板"}),m.jsxs("div",{className:"nb-card bg-[var(--color-accent-yellow)] max-w-2xl",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-xl font-bold mb-3",children:"选择一个项目 🎯"}),m.jsx("p",{className:"text-sm mb-4 text-[var(--color-text-muted)]",children:"看板按项目分。挑一个开始:"}),m.jsx("div",{className:"flex flex-wrap gap-2",children:(K=v.data)==null?void 0:K.data.map(V=>m.jsx("button",{className:"nb-btn nb-btn-blue",onClick:()=>_(V.name),type:"button",children:V.name},V.name))})]})]});const G=Z.filter(V=>{if(o){const pe=o.toLowerCase();if(!(V.title.toLowerCase().includes(pe)||V.skills.some(L=>L.toLowerCase().includes(pe))||V.labels.some(L=>L.toLowerCase().includes(pe))))return!1}return!(f.size>0&&!V.skills.some(R=>f.has(R))||h.size>0&&!V.labels.some(R=>h.has(R)))}),le=(oe=v.data)==null?void 0:oe.data.find(V=>V.name===n),ae=(le==null?void 0:le.pipelineStatus)==="running";return m.jsxs("div",{className:"flex flex-col gap-4 max-w-full flex-1 min-h-0",children:[m.jsxs("header",{className:"flex items-center justify-between flex-wrap gap-3 shrink-0",children:[m.jsxs("div",{children:[m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-4xl font-bold tracking-tight",children:"看板 ✨"}),m.jsx("p",{className:"text-[var(--color-text-muted)] text-sm mt-1",children:le?`${le.name} · ${le.cards.total} cards · ${le.workers.active} workers 活跃`:"加载中…"})]}),m.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[m.jsx(mR,{current:n,onChange:_}),m.jsxs("button",{className:ae?"nb-btn nb-btn-danger":"nb-btn nb-btn-primary",onClick:()=>ae?T.mutate():A.mutate(),disabled:A.isPending||T.isPending,type:"button","aria-label":ae?"停止 pipeline":"启动 pipeline",title:ae?"停止 pipeline":"启动 pipeline",children:[A.isPending||T.isPending?m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}):ae?m.jsx(e1,{size:14,strokeWidth:3}):m.jsx(Kp,{size:14,strokeWidth:3}),ae?"停止":"启动"]}),m.jsxs("button",{className:"nb-btn nb-btn-yellow",type:"button",onClick:async()=>{await g({title:"重置整个流水线",body:"这会清空所有卡片的运行状态、worker marker、分支。不可撤销。",confirm:"重置全部",danger:!0})&&D.mutate()},disabled:D.isPending,children:[D.isPending?m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(WE,{size:14,strokeWidth:2.5}),"重置"]}),m.jsxs("button",{className:"nb-btn nb-btn-mint",type:"button",onClick:()=>j(!0),disabled:q.isPending,children:[q.isPending?m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(Xi,{size:14,strokeWidth:3}),"新卡片"]})]})]}),m.jsxs("div",{className:"flex items-center gap-3 flex-wrap shrink-0",children:[m.jsxs("div",{className:"relative flex-1 max-w-md",children:[m.jsx(xf,{size:14,className:"absolute left-3 top-1/2 -translate-y-1/2 text-[var(--color-text-subtle)]"}),m.jsx("input",{className:"nb-input pl-9 w-full",placeholder:"搜索标题 / skill / label…",value:o,onChange:V=>c(V.target.value),"aria-label":"搜索卡片"})]}),m.jsx(Jv,{label:"skill",options:O,selected:f,onChange:d}),m.jsx(Jv,{label:"label",options:P,selected:h,onChange:y}),(o||f.size>0||h.size>0)&&m.jsxs("button",{className:"nb-btn",style:{padding:"4px 10px",fontSize:11},onClick:()=>{c(""),d(new Set),y(new Set)},type:"button","aria-label":"清空筛选",children:[m.jsx(Er,{size:11,strokeWidth:3}),"清空"]}),m.jsxs("span",{className:"text-xs text-[var(--color-text-muted)] flex items-center gap-1 font-[family-name:var(--font-mono)]",children:[m.jsx(KC,{size:12}),G.length," / ",Z.length]})]}),S.isError&&m.jsxs("div",{className:"nb-card bg-[var(--color-crashed-bg)]",children:[m.jsx("p",{className:"font-semibold",children:"加载卡片失败"}),m.jsx("p",{className:"text-sm mt-1 text-[var(--color-text-muted)]",children:S.error instanceof Error?S.error.message:String(S.error)})]}),!S.isError&&m.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6 auto-rows-fr gap-3 flex-1 min-h-0",children:pR.map(V=>m.jsx(dR,{label:V.label,bg:V.bg,cards:G.filter(xR(V.state)),onCardClick:pe=>s(pe.seq),onDropCard:pe=>U.mutate({seq:pe,state:V.state})},V.state))}),a!==null&&m.jsx(hR,{project:n,seq:a,onClose:()=>s(null),onChanged:k}),$&&m.jsx(HO,{project:n,isPending:q.isPending,onCancel:()=>j(!1),onCreate:V=>q.mutate(V)})]})}function xR(e){return t=>e==="QA"?t.state==="QA"||t.state==="Review":e==="Done"?t.state==="Done"||t.state==="Canceled":t.state===e}function Jv({label:e,options:t,selected:n,onChange:a}){const[s,o]=M.useState(!1),c=M.useRef(null);M.useEffect(()=>{if(!s)return;const y=x=>{var v;(v=c.current)!=null&&v.contains(x.target)||o(!1)},g=x=>{x.key==="Escape"&&o(!1)};return window.addEventListener("click",y),window.addEventListener("keydown",g),()=>{window.removeEventListener("click",y),window.removeEventListener("keydown",g)}},[s]);const f=y=>{const g=new Set(n);g.has(y)?g.delete(y):g.add(y),a(g)},d=t.length===0,h=n.size;return m.jsxs("div",{ref:c,className:"relative",children:[m.jsxs("button",{type:"button",className:"nb-btn",style:{padding:"6px 12px",fontSize:12},onClick:()=>!d&&o(y=>!y),disabled:d,"aria-haspopup":"listbox","aria-expanded":s,"aria-label":`按 ${e} 筛选`,children:[e,h>0&&m.jsx("span",{className:"ml-1 px-1.5 py-0.5 text-[10px] font-bold rounded-full bg-[var(--color-primary)] text-[var(--color-text)] border border-[var(--color-text)]",children:h}),m.jsx(yc,{size:11,strokeWidth:3,className:["transition-transform",s?"rotate-180":""].join(" ")})]}),s&&m.jsxs("div",{role:"listbox",className:"absolute left-0 top-full mt-2 z-20 min-w-[200px] max-h-64 overflow-auto nb-card p-2",style:{padding:8},children:[t.map(y=>{const g=n.has(y);return m.jsxs("label",{className:["flex items-center gap-2 px-2 py-1.5 rounded cursor-pointer text-sm font-[family-name:var(--font-mono)]",g?"bg-[var(--color-accent-mint)]":"hover:bg-[var(--color-bg-cream)]"].join(" "),children:[m.jsx("input",{type:"checkbox",checked:g,onChange:()=>f(y),className:"flex-shrink-0"}),m.jsx("span",{className:"truncate",children:y})]},y)}),h>0&&m.jsx("button",{type:"button",className:"w-full mt-2 pt-2 border-t-2 border-dashed border-[var(--color-text)] text-xs font-bold text-[var(--color-crashed)] text-center",onClick:()=>a(new Set),children:"清空选择"})]})]})}function vR(){return Ht("/api/workers/all")}function ER(e){return Ht(`/api/projects/${encodeURIComponent(e)}/workers`)}function SR(e,t){return Ht(`/api/projects/${encodeURIComponent(e)}/workers/${t}`)}async function sS(e,t){const n=await fetch(e,{method:"POST",headers:t?{"Content-Type":"application/json"}:void 0,body:t?JSON.stringify(t):void 0});if(!n.ok)throw new Error(`${n.status}: ${await n.text()}`);return n.json().catch(()=>({}))}function e0(e,t){return sS(`/api/projects/${encodeURIComponent(e)}/workers/${t}/kill`)}function wR(e,t,n){return sS(`/api/projects/${encodeURIComponent(e)}/workers/${t}/launch`,n?{seq:n}:void 0)}function og({state:e}){const n={running:{bg:"var(--color-running-bg)",color:"var(--color-running)",label:"running"},starting:{bg:"var(--color-secondary)",color:"var(--color-text)",label:"starting",icon:m.jsx(Wt,{size:9,strokeWidth:3,className:"animate-spin"})},stuck:{bg:"var(--color-stuck-bg)",color:"var(--color-stuck)",label:"stuck"},crashed:{bg:"var(--color-crashed-bg)",color:"var(--color-crashed)",label:"crashed",icon:m.jsx(SA,{size:9,strokeWidth:2.5})},idle:{bg:"var(--color-idle-bg)",color:"var(--color-idle)",label:"idle"}}[e];return m.jsxs("span",{className:"nb-status inline-flex items-center gap-1",style:{background:n.bg,color:n.color},children:[n.icon,n.label]})}function cg(e){if(e==null||e<=0)return"—";const t=Math.floor(e/1e3),n=Math.floor(t/3600),a=Math.floor(t%3600/60),s=t%60;return n>0?`${n}h ${a}m`:a>0?`${a}m ${s}s`:`${s}s`}function _R(e){if(e==null||e<=0)return"text-[var(--color-text-muted)]";const t=e/6e4;return t<10?"text-[var(--color-running)]":t<60?"text-[var(--color-stuck)]":"text-[var(--color-crashed)]"}function ug(e){const t=Date.now()-new Date(e).getTime();return t<6e4?`${Math.floor(t/1e3)}s 前`:t<36e5?`${Math.floor(t/6e4)}m 前`:`${Math.floor(t/36e5)}h 前`}function kR({alerts:e,selected:t,onSelect:n}){return e.length===0?m.jsxs("div",{className:"nb-card bg-[var(--color-running-bg)] flex items-center gap-3",children:[m.jsx(Pp,{size:18,strokeWidth:2.5,className:"text-[var(--color-running)]"}),m.jsx("span",{className:"text-sm font-bold text-[var(--color-running)]",children:"全部 worker 健康"})]}):m.jsxs("section",{children:[m.jsxs("h2",{className:"font-[family-name:var(--font-heading)] text-sm font-bold uppercase tracking-wider mb-2 flex items-center gap-2 text-[var(--color-crashed)]",children:[m.jsx(RA,{size:14,strokeWidth:2.5}),"Alerts (",e.length,")"]}),m.jsx("div",{className:"flex flex-col gap-2",children:e.map(a=>{const s=(t==null?void 0:t.project)===a.project&&(t==null?void 0:t.slot)===a.slot;return m.jsxs("button",{type:"button",onClick:()=>n(a.project,a.slot),className:["nb-card p-3 text-left",a.state==="crashed"?"bg-[var(--color-crashed-bg)]":"bg-[var(--color-stuck-bg)]",s?"ring-4 ring-[var(--color-text)]":""].join(" "),children:[m.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[m.jsx(og,{state:a.state}),m.jsxs("span",{className:"font-[family-name:var(--font-mono)] font-bold",children:[a.project,"/worker-",a.slot]}),a.card&&m.jsxs("span",{className:"truncate",children:["#",a.card.seq," ",a.card.title]}),m.jsxs("span",{className:"ml-auto text-xs text-[var(--color-text-muted)] font-[family-name:var(--font-mono)] flex items-center gap-1",children:[m.jsx(MC,{size:10,strokeWidth:2.5}),cg(a.runtimeMs)]})]}),a.markerUpdatedAt&&m.jsx("div",{className:"text-xs text-[var(--color-text-muted)] mt-1 font-[family-name:var(--font-mono)]",children:a.state==="crashed"?"PID 已死。":`marker 停 ${ug(a.markerUpdatedAt)}。`})]},`${a.project}-${a.slot}`)})})]})}function NR({active:e,selected:t,onSelect:n}){return e.length===0?m.jsx("div",{className:"nb-card bg-[var(--color-bg-cream)]",children:m.jsx("p",{className:"text-sm text-[var(--color-text-muted)] italic",children:"没有 worker 在运行。"})}):m.jsxs("section",{children:[m.jsxs("h2",{className:"font-[family-name:var(--font-heading)] text-sm font-bold uppercase tracking-wider mb-2 flex items-center gap-2",children:[m.jsx(jf,{size:14,strokeWidth:2.5}),"Active (",e.length,")"]}),m.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-3",children:e.map(a=>{const s=(t==null?void 0:t.project)===a.project&&(t==null?void 0:t.slot)===a.slot;return m.jsxs("button",{type:"button",onClick:()=>n(a.project,a.slot),className:["nb-card p-3 text-left",a.state==="starting"?"bg-[var(--color-secondary)]":"bg-[var(--color-running-bg)]",s?"ring-4 ring-[var(--color-text)]":""].join(" "),children:[m.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[m.jsx(og,{state:a.state}),m.jsxs("span",{className:"font-[family-name:var(--font-mono)] font-bold text-sm flex-1 truncate",children:[a.project,"/worker-",a.slot]}),m.jsx("span",{className:`text-xs font-[family-name:var(--font-mono)] ${_R(a.runtimeMs)}`,children:cg(a.runtimeMs)})]}),a.card&&m.jsxs("div",{className:"text-sm font-semibold mb-1 truncate",children:["#",a.card.seq," · ",a.card.title]}),m.jsxs("div",{className:"text-xs text-[var(--color-text-muted)] font-[family-name:var(--font-mono)] flex items-center gap-2 mb-1",children:[a.stage&&m.jsxs("span",{children:["stage: ",a.stage]}),a.markerUpdatedAt&&m.jsxs("span",{className:"ml-auto",children:["marker ",ug(a.markerUpdatedAt)]})]}),a.lastLogLine&&m.jsxs("div",{className:"text-[11px] font-[family-name:var(--font-mono)] text-[var(--color-text-muted)] bg-[var(--color-bg)] border-2 border-[var(--color-text)] rounded px-2 py-1 mt-2 truncate",children:[m.jsx(t1,{size:9,strokeWidth:2.5,className:"inline-block mr-1 align-text-bottom"}),a.lastLogLine.msg]})]},`${a.project}-${a.slot}`)})})]})}function TR({capacity:e,selected:t,onSelect:n}){return e.length===0?null:m.jsxs("section",{children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-sm font-bold uppercase tracking-wider mb-2",children:"Capacity"}),m.jsx("div",{className:"nb-card p-0 overflow-hidden",children:m.jsxs("table",{className:"w-full text-sm",children:[m.jsx("thead",{children:m.jsxs("tr",{className:"bg-[var(--color-bg-cream)] border-b-2 border-[var(--color-text)]",children:[m.jsx("th",{className:"px-3 py-2 text-left font-bold text-xs uppercase tracking-wider",children:"项目"}),m.jsx("th",{className:"px-3 py-2 text-left font-bold text-xs uppercase tracking-wider",children:"占用"}),m.jsx("th",{className:"px-3 py-2 text-right font-bold text-xs uppercase tracking-wider",children:"running"}),m.jsx("th",{className:"px-3 py-2 text-right font-bold text-xs uppercase tracking-wider",children:"其它"}),m.jsx("th",{className:"px-3 py-2"})]})}),m.jsx("tbody",{children:e.map(a=>{const s=a.running+a.starting+a.stuck+a.crashed,o=(t==null?void 0:t.project)===a.project;return m.jsxs("tr",{onClick:()=>n(a.project),className:["border-b border-dashed border-[var(--color-border-light)] last:border-0 cursor-pointer hover:bg-[var(--color-accent-yellow)]",o?"bg-[var(--color-accent-yellow)]":""].join(" "),children:[m.jsx("td",{className:"px-3 py-2 font-[family-name:var(--font-mono)] font-bold",children:a.project}),m.jsx("td",{className:"px-3 py-2",children:m.jsx(CR,{total:a.total,cap:a})}),m.jsxs("td",{className:"px-3 py-2 text-right font-[family-name:var(--font-mono)]",children:[m.jsx("span",{className:"text-[var(--color-running)] font-bold",children:a.running}),m.jsxs("span",{className:"text-[var(--color-text-muted)]",children:["/",a.total]})]}),m.jsxs("td",{className:"px-3 py-2 text-right text-xs font-[family-name:var(--font-mono)] text-[var(--color-text-muted)]",children:[a.starting>0&&m.jsxs("span",{className:"mr-2",children:["starting ",a.starting]}),a.stuck>0&&m.jsxs("span",{className:"text-[var(--color-stuck)] font-bold mr-2",children:["stuck ",a.stuck]}),a.crashed>0&&m.jsxs("span",{className:"text-[var(--color-crashed)] font-bold mr-2",children:["crashed ",a.crashed]}),s===0&&m.jsx("span",{children:"idle"})]}),m.jsx("td",{className:"px-3 py-2 text-right",children:m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:"详情 →"})})]},a.project)})})]})})]})}function CR({total:e,cap:t}){const n=[];for(let a=0;a<t.crashed;a++)n.push("crashed");for(let a=0;a<t.stuck;a++)n.push("stuck");for(let a=0;a<t.starting;a++)n.push("starting");for(let a=0;a<t.running;a++)n.push("running");for(let a=0;a<t.idle;a++)n.push("idle");return m.jsxs("div",{className:"flex gap-1 items-center",children:[n.map((a,s)=>m.jsx("span",{className:"inline-block w-3 h-3 rounded-full border-2 border-[var(--color-text)]",style:{background:AR(a)},title:a},s)),m.jsxs("span",{className:"text-xs text-[var(--color-text-muted)] ml-2 font-[family-name:var(--font-mono)]",children:[e," slot",e!==1?"s":""]})]})}function AR(e){switch(e){case"running":return"var(--color-running-bg)";case"starting":return"var(--color-secondary)";case"stuck":return"var(--color-stuck-bg)";case"crashed":return"var(--color-crashed-bg)";default:return"var(--color-idle-bg)"}}function OR({project:e,initialSlot:t,onChange:n}){var d;const a=lt({queryKey:["workers",e],queryFn:()=>ER(e),refetchInterval:3e3}),s=((d=a.data)==null?void 0:d.data)??[],[o,c]=M.useState(null);M.useEffect(()=>{if(s.length===0){c(null);return}const h=s[0].slot;c(y=>y!=null&&s.some(g=>g.slot===y)?y:t!=null&&s.some(g=>g.slot===t)?t:h)},[e,t,s.length]);const f=s.find(h=>h.slot===o)??null;return m.jsxs("div",{className:"flex flex-col h-full",children:[m.jsxs("div",{className:"px-4 py-3 border-b-2 border-[var(--color-text)] bg-[var(--color-bg-cream)]",children:[m.jsxs("div",{className:"flex items-center justify-between mb-2",children:[m.jsx("span",{className:"font-[family-name:var(--font-mono)] font-bold truncate",children:e}),m.jsx(ds,{to:`/board?project=${encodeURIComponent(e)}`,className:"text-xs underline text-[var(--color-text-muted)] hover:text-[var(--color-text)]",children:"看板 →"})]}),a.isLoading&&s.length===0?m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"加载 workers…"}):s.length===0?m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"该项目没有 worker slot。"}):m.jsx("div",{className:"flex flex-wrap gap-2",children:s.map(h=>m.jsx(RR,{worker:h,active:h.slot===o,onClick:()=>c(h.slot)},h.slot))})]}),f?m.jsx(MR,{project:e,worker:f,onChange:n}):m.jsx("div",{className:"flex-1 flex items-center justify-center p-6 text-center",children:m.jsx("p",{className:"text-sm text-[var(--color-text-muted)]",children:s.length===0?"无 worker":"请选择一个 worker"})})]})}function RR({worker:e,active:t,onClick:n}){return m.jsxs("button",{type:"button",onClick:n,className:["nb-card p-2 text-left min-w-[130px] transition-transform",t?"ring-4 ring-[var(--color-text)]":"opacity-80 hover:opacity-100"].join(" "),children:[m.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[m.jsx(og,{state:e.state}),m.jsxs("span",{className:"font-[family-name:var(--font-mono)] font-bold text-xs",children:["worker-",e.slot]})]}),e.card?m.jsxs("div",{className:"text-[11px] truncate font-[family-name:var(--font-mono)]",children:["#",e.card.seq," ",e.card.title]}):m.jsx("div",{className:"text-[11px] text-[var(--color-text-muted)] italic",children:"空闲"})]})}function MR({project:e,worker:t,onChange:n}){var h,y;const{confirm:a,alert:s}=si(),o=t.state==="crashed"||t.state==="stuck",c=lt({queryKey:["worker-detail",e,t.slot],queryFn:()=>SR(e,t.slot),refetchInterval:3e3}),f=((h=c.data)==null?void 0:h.recentOutput)??[],d=((y=c.data)==null?void 0:y.recentLogs)??[];return m.jsxs(m.Fragment,{children:[m.jsxs("div",{className:"flex-1 overflow-auto p-4 flex flex-col gap-4",children:[t.card?m.jsxs("div",{children:[m.jsx("div",{className:"text-xs font-bold uppercase tracking-wider text-[var(--color-text-muted)] mb-1",children:"当前卡片"}),m.jsxs("div",{className:"text-sm font-semibold break-words",children:["#",t.card.seq," · ",t.card.title]})]}):m.jsx("div",{className:"text-sm text-[var(--color-text-muted)] italic",children:"slot 空闲,没有当前卡片。"}),m.jsxs("dl",{className:"grid grid-cols-[100px_1fr] gap-y-2 text-sm",children:[m.jsx("dt",{className:"font-bold",children:"Stage"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:t.stage??"—"}),m.jsx("dt",{className:"font-bold",children:"PID"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:t.pid??"—"}),m.jsx("dt",{className:"font-bold",children:"Runtime"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:cg(t.runtimeMs)}),m.jsx("dt",{className:"font-bold",children:"Started"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)] text-xs",children:t.startedAt?new Date(t.startedAt).toLocaleString():"—"}),m.jsx("dt",{className:"font-bold",children:"Marker"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)] text-xs",children:t.markerUpdatedAt?ug(t.markerUpdatedAt):"—"})]}),m.jsxs("div",{children:[m.jsxs("div",{className:"text-xs font-bold uppercase tracking-wider text-[var(--color-text-muted)] mb-1 flex items-center gap-1",children:[m.jsx(t1,{size:10,strokeWidth:2.5}),"Claude 输出 · 最近 ",f.length," 行"]}),c.isLoading&&f.length===0?m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"加载中…"}):f.length===0?m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"还没收到 session 输出。Worker 刚启动时需要几秒。"}):m.jsx("pre",{className:"text-xs font-[family-name:var(--font-mono)] bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded p-2 max-h-80 overflow-auto whitespace-pre-wrap break-words",children:f.map(g=>`${g.ts?`${g.ts} [${g.kind}] `:`[${g.kind}] `}${g.text}`).join(`
478
478
  `)})]}),d.length>0&&m.jsxs("div",{children:[m.jsxs("div",{className:"text-xs font-bold uppercase tracking-wider text-[var(--color-text-muted)] mb-1 opacity-60",children:["Supervisor 心跳 · 最近 ",d.length," 行"]}),m.jsx("pre",{className:"text-xs font-[family-name:var(--font-mono)] bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded p-2 max-h-40 overflow-auto whitespace-pre-wrap break-words opacity-80",children:d.map(g=>`${g.ts??""} [${g.level}] ${g.msg}`).join(`
479
479
  `)}),m.jsx(ds,{to:`/logs?project=${encodeURIComponent(e)}&worker=${t.slot}`,className:"text-xs underline text-[var(--color-running)] mt-1 inline-block",children:"查看完整 log →"})]})]}),m.jsxs("div",{className:"px-4 py-3 border-t-2 border-[var(--color-text)] bg-[var(--color-bg-cream)] flex gap-2 justify-end flex-wrap",children:[o&&t.card&&m.jsxs("button",{type:"button",className:"nb-btn nb-btn-mint",style:{padding:"4px 10px",fontSize:11},onClick:async()=>{if(await a({title:`重启 worker-${t.slot}`,body:`先杀进程,再重新 launch 到 #${t.card.seq}`,confirm:"重启"})){try{await e0(e,t.slot)}catch{}try{await wR(e,t.slot,t.card.seq),n()}catch(x){s({title:"重启失败",body:x instanceof Error?x.message:String(x)})}}},children:[m.jsx(CA,{size:11,strokeWidth:2.5})," 重启"]}),t.state!=="idle"&&m.jsxs("button",{type:"button",className:"nb-btn nb-btn-danger",style:{padding:"4px 10px",fontSize:11},onClick:async()=>{if(await a({title:`终止 worker-${t.slot}`,body:"当前任务强制中断。",confirm:"终止",danger:!0}))try{await e0(e,t.slot),n()}catch(x){s({title:"终止失败",body:x instanceof Error?x.message:String(x)})}},children:[m.jsx(zA,{size:11,strokeWidth:2.5})," 终止"]})]})]})}function jR(){var o;const e=qn(),[t,n]=M.useState(null),a=lt({queryKey:["workers-agg"],queryFn:vR,refetchInterval:5e3});M.useEffect(()=>{if(!a.data)return;const c=a.data.capacity.map(d=>d.project),f=[];for(const d of c){const h=new EventSource(`/stream/projects/${encodeURIComponent(d)}`),y=()=>{e.invalidateQueries({queryKey:["workers-agg"]})};h.addEventListener("worker.updated",y),h.addEventListener("worker.added",y),h.addEventListener("worker.deleted",y),h.addEventListener("card.updated",y),f.push(h)}return()=>{for(const d of f)d.close()}},[(o=a.data)==null?void 0:o.capacity.map(c=>c.project).join(","),e]);const s=M.useMemo(()=>{if(!a.data)return{projects:0,running:0,starting:0,stuck:0,crashed:0,idle:0};const c={projects:a.data.capacity.length,running:0,starting:0,stuck:0,crashed:0,idle:0};for(const f of a.data.capacity)c.running+=f.running,c.starting+=f.starting,c.stuck+=f.stuck,c.crashed+=f.crashed,c.idle+=f.idle;return c},[a.data]);return m.jsxs("div",{className:"flex flex-col gap-4 h-[calc(100vh-140px)]",children:[m.jsxs("header",{className:"flex items-center justify-between flex-wrap gap-3",children:[m.jsxs("div",{children:[m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-4xl font-bold tracking-tight",children:"Workers 👷"}),m.jsxs("p",{className:"text-sm text-[var(--color-text-muted)] mt-1",children:["跨 ",s.projects," 项目 · ",s.running," 跑 · ",s.starting," 启动 ·"," ",m.jsxs("span",{className:"text-[var(--color-stuck)]",children:[s.stuck," 卡"]})," ·"," ",m.jsxs("span",{className:"text-[var(--color-crashed)]",children:[s.crashed," 崩"]})," · ",s.idle," 闲"]})]}),m.jsxs("button",{className:"nb-btn",style:{padding:"6px 12px",fontSize:12},onClick:()=>a.refetch(),disabled:a.isFetching,type:"button","aria-label":"刷新",children:[a.isFetching?m.jsx(Wt,{size:12,strokeWidth:3,className:"animate-spin"}):m.jsx(Cl,{size:12,strokeWidth:2.5}),"刷新"]})]}),m.jsxs("div",{className:"grid grid-cols-1 xl:grid-cols-2 gap-4 flex-1 min-h-0",children:[m.jsxs("div",{className:"flex flex-col gap-4 overflow-auto pr-2",children:[a.isLoading&&m.jsx("p",{className:"text-[var(--color-text-muted)] italic",children:"加载中…"}),a.isError&&m.jsx("div",{className:"nb-card bg-[var(--color-crashed-bg)]",children:m.jsxs("p",{children:["加载失败: ",a.error instanceof Error?a.error.message:String(a.error)]})}),a.data&&m.jsxs(m.Fragment,{children:[m.jsx(kR,{alerts:a.data.alerts,selected:t,onSelect:(c,f)=>n({project:c,slot:f})}),m.jsx(NR,{active:a.data.active,selected:t,onSelect:(c,f)=>n({project:c,slot:f})}),m.jsx(TR,{capacity:a.data.capacity,selected:t,onSelect:c=>n({project:c})})]})]}),m.jsx("aside",{className:"nb-card p-0 overflow-hidden flex flex-col h-full",children:t?m.jsx(OR,{project:t.project,initialSlot:t.slot,onChange:()=>e.invalidateQueries({queryKey:["workers-agg"]})}):m.jsx("div",{className:"flex-1 flex items-center justify-center p-6 text-center",children:m.jsxs("div",{children:[m.jsx(jf,{size:32,className:"mx-auto mb-3 text-[var(--color-text-subtle)]",strokeWidth:2}),m.jsx("p",{className:"text-sm text-[var(--color-text-muted)]",children:"点击项目 / worker 查看详情"})]})})})]})]})}function DR(e){const t=new URLSearchParams;return e.project&&t.set("project",e.project),e.worker&&t.set("worker",e.worker),t.set("limit",String(e.limit)),e.since&&t.set("since",e.since),Ht(`/api/logs?${t}`)}function LR(e){const t=new URLSearchParams({project:e.project});return e.worker&&t.set("worker",e.worker),`/stream/logs?${t}`}const IR=["error","warn","info","debug"],zR=["error","warn","info"];function BR(){var U,Z;const[e,t]=QE(),n=e.get("project"),a=e.get("worker")??"",[s,o]=M.useState([]),[c,f]=M.useState(!1),[d,h]=M.useState(!0),[y,g]=M.useState(()=>new Set(zR)),[x,v]=M.useState(""),[S,w]=M.useState("live"),[k,_]=M.useState(()=>{const O=new Date(Date.now()-36e5),P=G=>String(G).padStart(2,"0");return`${O.getFullYear()}-${P(O.getMonth()+1)}-${P(O.getDate())}T${P(O.getHours())}:${P(O.getMinutes())}`}),A=M.useRef(null),T=!n,D=lt({queryKey:["projects"],queryFn:_r}),{data:$,refetch:j}=lt({queryKey:["logs",n??"agg",a,S,S==="history"?k:"live"],queryFn:()=>DR({project:n||void 0,worker:a||void 0,limit:S==="history"?2e3:500,since:S==="history"?new Date(k).toISOString():void 0}),refetchInterval:T&&S==="live"?5e3:!1});M.useEffect(()=>{$!=null&&$.data&&o($.data)},[$]),M.useEffect(()=>{if(!n||S!=="live")return;const O=LR({project:n,worker:a||void 0}),P=new EventSource(O);return P.addEventListener("log.line",G=>{if(!c)try{const le=JSON.parse(G.data);o(ae=>{const W=[...ae,le];return W.length>5e3&&W.splice(0,W.length-5e3),W})}catch{}}),()=>P.close()},[n,a,c,S]),M.useEffect(()=>{if(!d)return;const O=A.current;O&&(O.scrollTop=O.scrollHeight)},[s,d]);const q=M.useMemo(()=>{const O=x.toLowerCase();return s.filter(P=>!(!y.has(P.level)||O&&!P.msg.toLowerCase().includes(O)))},[s,y,x]);return m.jsxs("div",{className:"flex flex-col gap-4 max-w-full",children:[m.jsx("header",{className:"flex items-center justify-between gap-3 flex-wrap",children:m.jsxs("div",{children:[m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-4xl font-bold tracking-tight",children:"Logs 📜"}),m.jsxs("p",{className:"text-sm text-[var(--color-text-muted)] mt-1",children:[T?`全部项目(${((U=D.data)==null?void 0:U.data.length)??0})`:n,a&&` · worker-${a}`," · ",T&&S==="live"?"5s 轮询":"tail -f"," · ",s.length," lines",c&&m.jsx("span",{className:"text-[var(--color-stuck)] ml-2 font-bold",children:"⏸ PAUSED"})]})]})}),m.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[m.jsxs("div",{className:"flex gap-1 p-1 bg-[var(--color-bg)] border-[2px] border-[var(--color-text)] rounded-full shadow-[2px_2px_0_var(--color-text)]",children:[m.jsxs("button",{type:"button",onClick:()=>w("live"),"aria-pressed":S==="live",className:["px-3 py-1 rounded-full text-xs font-bold flex items-center gap-1.5",S==="live"?"bg-[var(--color-primary)] text-[var(--color-text)] shadow-[1px_1px_0_var(--color-text)]":"text-[var(--color-text-muted)]"].join(" "),children:[m.jsx(ZE,{size:11,strokeWidth:2.5}),"实时"]}),m.jsxs("button",{type:"button",onClick:()=>w("history"),"aria-pressed":S==="history",className:["px-3 py-1 rounded-full text-xs font-bold flex items-center gap-1.5",S==="history"?"bg-[var(--color-primary)] text-[var(--color-text)] shadow-[1px_1px_0_var(--color-text)]":"text-[var(--color-text-muted)]"].join(" "),children:[m.jsx(ZC,{size:11,strokeWidth:2.5}),"历史"]})]}),S==="history"&&m.jsxs(m.Fragment,{children:[m.jsx("input",{type:"datetime-local",className:"nb-input",style:{padding:"4px 8px",fontSize:12},value:k,onChange:O=>_(O.target.value),"aria-label":"查询起始时间"}),m.jsxs("button",{className:"nb-btn nb-btn-primary",style:{padding:"6px 12px",fontSize:12},onClick:()=>j(),type:"button","aria-label":"查询",children:[m.jsx(xf,{size:11,strokeWidth:3}),"查询"]})]}),m.jsxs("div",{className:"relative",children:[m.jsx(qC,{size:14,strokeWidth:2.5,className:"absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none text-[var(--color-text)]"}),m.jsxs("select",{className:"nb-input appearance-none pl-9 pr-9 font-[family-name:var(--font-mono)] cursor-pointer",style:{padding:"10px 36px 10px 36px",fontSize:13,minWidth:180},value:n??"",onChange:O=>{const P=O.target.value;t(P?{project:P}:{})},"aria-label":"筛选项目",children:[m.jsx("option",{value:"",children:"全部项目"}),(Z=D.data)==null?void 0:Z.data.map(O=>m.jsx("option",{value:O.name,children:O.name},O.name))]}),m.jsx(yc,{size:14,strokeWidth:3,className:"absolute right-3 top-1/2 -translate-y-1/2 pointer-events-none text-[var(--color-text)]"})]}),m.jsxs("div",{className:"relative flex-1 max-w-md",children:[m.jsx(xf,{size:14,className:"absolute left-3 top-1/2 -translate-y-1/2 text-[var(--color-text-subtle)]"}),m.jsx("input",{className:"nb-input pl-9 w-full",placeholder:"过滤关键字…",value:x,onChange:O=>v(O.target.value),"aria-label":"过滤日志"})]}),m.jsx("div",{className:"flex items-center gap-1 p-1 bg-[var(--color-bg)] border-[2px] border-[var(--color-text)] rounded-full shadow-[2px_2px_0_var(--color-text)]",children:IR.map(O=>m.jsx(UR,{level:O,enabled:y.has(O),onToggle:()=>{g(P=>{const G=new Set(P);return G.has(O)?G.delete(O):G.add(O),G})}},O))}),m.jsxs("div",{className:"ml-auto flex gap-2",children:[S==="live"&&m.jsxs(m.Fragment,{children:[m.jsx("button",{className:"nb-btn",style:{padding:"6px 12px",fontSize:12},onClick:()=>h(O=>!O),type:"button",children:d?"✓ Auto-scroll":"Auto-scroll"}),m.jsx("button",{className:"nb-btn",style:{padding:"6px 12px",fontSize:12},onClick:()=>f(O=>!O),type:"button",children:c?m.jsxs(m.Fragment,{children:[m.jsx(Kp,{size:12,strokeWidth:3})," Resume"]}):m.jsxs(m.Fragment,{children:[m.jsx(cA,{size:12,strokeWidth:3})," Pause"]})})]}),m.jsxs("button",{className:"nb-btn",style:{padding:"6px 12px",fontSize:12},onClick:()=>{const O=new Blob([q.map(le=>le.raw).join(`
480
480
  `)],{type:"text/plain"}),P=URL.createObjectURL(O),G=document.createElement("a");G.href=P,G.download=`${n}-log-${Date.now()}.log`,G.click(),URL.revokeObjectURL(P)},type:"button",children:[m.jsx(XE,{size:12,strokeWidth:2.5})," Export"]})]})]}),m.jsxs("div",{className:"nb-card p-0 overflow-hidden",children:[m.jsxs("div",{className:"px-4 py-2 bg-[var(--color-bg-cream)] border-b-2 border-[var(--color-text)] flex items-center justify-between font-[family-name:var(--font-mono)] text-xs",children:[m.jsx("span",{className:"text-[var(--color-text-muted)]",children:($==null?void 0:$.file)??"~/.coral/projects/.../logs/*.log"}),S==="live"?m.jsx("span",{className:"nb-status",style:{background:"var(--color-running-bg)",color:"var(--color-running)"},children:"live"}):m.jsx("span",{className:"nb-status",style:{background:"var(--color-accent-purple)",color:"var(--color-text)"},children:"history"})]}),m.jsxs("div",{ref:A,className:"overflow-auto font-[family-name:var(--font-mono)] text-[12px] leading-[22px] max-h-[70vh] bg-[var(--color-bg)] p-2",onScroll:O=>{const P=O.currentTarget;!(P.scrollHeight-P.scrollTop-P.clientHeight<40)&&d&&h(!1)},children:[q.map((O,P)=>m.jsx(FR,{line:O},P)),q.length===0&&m.jsx("div",{className:"text-center py-12 text-[var(--color-text-subtle)]",children:"没有匹配的日志"})]})]})]})}function UR({level:e,enabled:t,onToggle:n}){const a={error:"var(--color-crashed-bg)",warn:"var(--color-stuck-bg)",info:"var(--color-secondary)",debug:"var(--color-accent-purple)"},s={error:"var(--color-crashed)",warn:"var(--color-stuck)",info:"var(--color-text)",debug:"var(--color-text)"};return m.jsx("button",{type:"button",onClick:n,"aria-pressed":t,className:["px-3 py-0.5 rounded-full font-[family-name:var(--font-mono)] text-[10px] font-bold tracking-widest cursor-pointer",t?"border-[1.5px] border-[var(--color-text)]":"text-[var(--color-text-subtle)]"].join(" "),style:t?{background:a[e],color:s[e]}:{},children:e.toUpperCase()})}function FR({line:e}){var a;const t={error:"bg-[var(--color-crashed)] text-[var(--color-text)]",warn:"bg-[var(--color-stuck)] text-[var(--color-text)]",info:"bg-[var(--color-secondary)] text-[var(--color-text)]",debug:"",trace:""},n=!!e.project;return m.jsxs("div",{className:["grid gap-2 px-2 py-0.5 rounded hover:bg-[var(--color-bg-cream)]",n?"grid-cols-[100px_90px_60px_1fr]":"grid-cols-[100px_60px_1fr]"].join(" "),children:[m.jsx("span",{className:"text-[var(--color-text-subtle)] whitespace-nowrap",children:e.ts?((a=e.ts.split("T")[1])==null?void 0:a.replace("Z",""))??e.ts:"--"}),n&&m.jsx("span",{className:"truncate text-[var(--color-text-muted)] font-bold",title:e.project,children:e.project}),m.jsx("span",{className:`text-center font-bold ${t[e.level]??""}`,style:{borderRadius:4,padding:"0 6px"},children:e.level.toUpperCase()}),m.jsx("span",{className:"truncate text-[var(--color-text)]",children:e.msg})]})}function $R(e,t){const n={};return(e[e.length-1]===""?[...e,""]:e).join((n.padRight?" ":"")+","+(n.padLeft===!1?"":" ")).trim()}const PR=/^[$_\p{ID_Start}][$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,qR=/^[$_\p{ID_Start}][-$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,HR={};function t0(e,t){return(HR.jsx?qR:PR).test(e)}const KR=/[ \t\n\f\r]/g;function GR(e){return typeof e=="object"?e.type==="text"?n0(e.value):!1:n0(e)}function n0(e){return e.replace(KR,"")===""}class Sc{constructor(t,n,a){this.normal=n,this.property=t,a&&(this.space=a)}}Sc.prototype.normal={};Sc.prototype.property={};Sc.prototype.space=void 0;function lS(e,t){const n={},a={};for(const s of e)Object.assign(n,s.property),Object.assign(a,s.normal);return new Sc(n,a,t)}function hp(e){return e.toLowerCase()}class Hn{constructor(t,n){this.attribute=n,this.property=t}}Hn.prototype.attribute="";Hn.prototype.booleanish=!1;Hn.prototype.boolean=!1;Hn.prototype.commaOrSpaceSeparated=!1;Hn.prototype.commaSeparated=!1;Hn.prototype.defined=!1;Hn.prototype.mustUseProperty=!1;Hn.prototype.number=!1;Hn.prototype.overloadedBoolean=!1;Hn.prototype.property="";Hn.prototype.spaceSeparated=!1;Hn.prototype.space=void 0;let QR=0;const Pe=ps(),Zt=ps(),mp=ps(),fe=ps(),St=ps(),pl=ps(),ti=ps();function ps(){return 2**++QR}const pp=Object.freeze(Object.defineProperty({__proto__:null,boolean:Pe,booleanish:Zt,commaOrSpaceSeparated:ti,commaSeparated:pl,number:fe,overloadedBoolean:mp,spaceSeparated:St},Symbol.toStringTag,{value:"Module"})),Em=Object.keys(pp);class fg extends Hn{constructor(t,n,a,s){let o=-1;if(super(t,n),i0(this,"space",s),typeof a=="number")for(;++o<Em.length;){const c=Em[o];i0(this,Em[o],(a&pp[c])===pp[c])}}}fg.prototype.defined=!0;function i0(e,t,n){n&&(e[t]=n)}function Hl(e){const t={},n={};for(const[a,s]of Object.entries(e.properties)){const o=new fg(a,e.transform(e.attributes||{},a),s,e.space);e.mustUseProperty&&e.mustUseProperty.includes(a)&&(o.mustUseProperty=!0),t[a]=o,n[hp(a)]=a,n[hp(o.attribute)]=a}return new Sc(t,n,e.space)}const oS=Hl({properties:{ariaActiveDescendant:null,ariaAtomic:Zt,ariaAutoComplete:null,ariaBusy:Zt,ariaChecked:Zt,ariaColCount:fe,ariaColIndex:fe,ariaColSpan:fe,ariaControls:St,ariaCurrent:null,ariaDescribedBy:St,ariaDetails:null,ariaDisabled:Zt,ariaDropEffect:St,ariaErrorMessage:null,ariaExpanded:Zt,ariaFlowTo:St,ariaGrabbed:Zt,ariaHasPopup:null,ariaHidden:Zt,ariaInvalid:null,ariaKeyShortcuts:null,ariaLabel:null,ariaLabelledBy:St,ariaLevel:fe,ariaLive:null,ariaModal:Zt,ariaMultiLine:Zt,ariaMultiSelectable:Zt,ariaOrientation:null,ariaOwns:St,ariaPlaceholder:null,ariaPosInSet:fe,ariaPressed:Zt,ariaReadOnly:Zt,ariaRelevant:null,ariaRequired:Zt,ariaRoleDescription:St,ariaRowCount:fe,ariaRowIndex:fe,ariaRowSpan:fe,ariaSelected:Zt,ariaSetSize:fe,ariaSort:null,ariaValueMax:fe,ariaValueMin:fe,ariaValueNow:fe,ariaValueText:null,role:null},transform(e,t){return t==="role"?t:"aria-"+t.slice(4).toLowerCase()}});function cS(e,t){return t in e?e[t]:t}function uS(e,t){return cS(e,t.toLowerCase())}const YR=Hl({attributes:{acceptcharset:"accept-charset",classname:"class",htmlfor:"for",httpequiv:"http-equiv"},mustUseProperty:["checked","multiple","muted","selected"],properties:{abbr:null,accept:pl,acceptCharset:St,accessKey:St,action:null,allow:null,allowFullScreen:Pe,allowPaymentRequest:Pe,allowUserMedia:Pe,alt:null,as:null,async:Pe,autoCapitalize:null,autoComplete:St,autoFocus:Pe,autoPlay:Pe,blocking:St,capture:null,charSet:null,checked:Pe,cite:null,className:St,cols:fe,colSpan:null,content:null,contentEditable:Zt,controls:Pe,controlsList:St,coords:fe|pl,crossOrigin:null,data:null,dateTime:null,decoding:null,default:Pe,defer:Pe,dir:null,dirName:null,disabled:Pe,download:mp,draggable:Zt,encType:null,enterKeyHint:null,fetchPriority:null,form:null,formAction:null,formEncType:null,formMethod:null,formNoValidate:Pe,formTarget:null,headers:St,height:fe,hidden:mp,high:fe,href:null,hrefLang:null,htmlFor:St,httpEquiv:St,id:null,imageSizes:null,imageSrcSet:null,inert:Pe,inputMode:null,integrity:null,is:null,isMap:Pe,itemId:null,itemProp:St,itemRef:St,itemScope:Pe,itemType:St,kind:null,label:null,lang:null,language:null,list:null,loading:null,loop:Pe,low:fe,manifest:null,max:null,maxLength:fe,media:null,method:null,min:null,minLength:fe,multiple:Pe,muted:Pe,name:null,nonce:null,noModule:Pe,noValidate:Pe,onAbort:null,onAfterPrint:null,onAuxClick:null,onBeforeMatch:null,onBeforePrint:null,onBeforeToggle:null,onBeforeUnload:null,onBlur:null,onCancel:null,onCanPlay:null,onCanPlayThrough:null,onChange:null,onClick:null,onClose:null,onContextLost:null,onContextMenu:null,onContextRestored:null,onCopy:null,onCueChange:null,onCut:null,onDblClick:null,onDrag:null,onDragEnd:null,onDragEnter:null,onDragExit:null,onDragLeave:null,onDragOver:null,onDragStart:null,onDrop:null,onDurationChange:null,onEmptied:null,onEnded:null,onError:null,onFocus:null,onFormData:null,onHashChange:null,onInput:null,onInvalid:null,onKeyDown:null,onKeyPress:null,onKeyUp:null,onLanguageChange:null,onLoad:null,onLoadedData:null,onLoadedMetadata:null,onLoadEnd:null,onLoadStart:null,onMessage:null,onMessageError:null,onMouseDown:null,onMouseEnter:null,onMouseLeave:null,onMouseMove:null,onMouseOut:null,onMouseOver:null,onMouseUp:null,onOffline:null,onOnline:null,onPageHide:null,onPageShow:null,onPaste:null,onPause:null,onPlay:null,onPlaying:null,onPopState:null,onProgress:null,onRateChange:null,onRejectionHandled:null,onReset:null,onResize:null,onScroll:null,onScrollEnd:null,onSecurityPolicyViolation:null,onSeeked:null,onSeeking:null,onSelect:null,onSlotChange:null,onStalled:null,onStorage:null,onSubmit:null,onSuspend:null,onTimeUpdate:null,onToggle:null,onUnhandledRejection:null,onUnload:null,onVolumeChange:null,onWaiting:null,onWheel:null,open:Pe,optimum:fe,pattern:null,ping:St,placeholder:null,playsInline:Pe,popover:null,popoverTarget:null,popoverTargetAction:null,poster:null,preload:null,readOnly:Pe,referrerPolicy:null,rel:St,required:Pe,reversed:Pe,rows:fe,rowSpan:fe,sandbox:St,scope:null,scoped:Pe,seamless:Pe,selected:Pe,shadowRootClonable:Pe,shadowRootDelegatesFocus:Pe,shadowRootMode:null,shape:null,size:fe,sizes:null,slot:null,span:fe,spellCheck:Zt,src:null,srcDoc:null,srcLang:null,srcSet:null,start:fe,step:null,style:null,tabIndex:fe,target:null,title:null,translate:null,type:null,typeMustMatch:Pe,useMap:null,value:Zt,width:fe,wrap:null,writingSuggestions:null,align:null,aLink:null,archive:St,axis:null,background:null,bgColor:null,border:fe,borderColor:null,bottomMargin:fe,cellPadding:null,cellSpacing:null,char:null,charOff:null,classId:null,clear:null,code:null,codeBase:null,codeType:null,color:null,compact:Pe,declare:Pe,event:null,face:null,frame:null,frameBorder:null,hSpace:fe,leftMargin:fe,link:null,longDesc:null,lowSrc:null,marginHeight:fe,marginWidth:fe,noResize:Pe,noHref:Pe,noShade:Pe,noWrap:Pe,object:null,profile:null,prompt:null,rev:null,rightMargin:fe,rules:null,scheme:null,scrolling:Zt,standby:null,summary:null,text:null,topMargin:fe,valueType:null,version:null,vAlign:null,vLink:null,vSpace:fe,allowTransparency:null,autoCorrect:null,autoSave:null,disablePictureInPicture:Pe,disableRemotePlayback:Pe,prefix:null,property:null,results:fe,security:null,unselectable:null},space:"html",transform:uS}),VR=Hl({attributes:{accentHeight:"accent-height",alignmentBaseline:"alignment-baseline",arabicForm:"arabic-form",baselineShift:"baseline-shift",capHeight:"cap-height",className:"class",clipPath:"clip-path",clipRule:"clip-rule",colorInterpolation:"color-interpolation",colorInterpolationFilters:"color-interpolation-filters",colorProfile:"color-profile",colorRendering:"color-rendering",crossOrigin:"crossorigin",dataType:"datatype",dominantBaseline:"dominant-baseline",enableBackground:"enable-background",fillOpacity:"fill-opacity",fillRule:"fill-rule",floodColor:"flood-color",floodOpacity:"flood-opacity",fontFamily:"font-family",fontSize:"font-size",fontSizeAdjust:"font-size-adjust",fontStretch:"font-stretch",fontStyle:"font-style",fontVariant:"font-variant",fontWeight:"font-weight",glyphName:"glyph-name",glyphOrientationHorizontal:"glyph-orientation-horizontal",glyphOrientationVertical:"glyph-orientation-vertical",hrefLang:"hreflang",horizAdvX:"horiz-adv-x",horizOriginX:"horiz-origin-x",horizOriginY:"horiz-origin-y",imageRendering:"image-rendering",letterSpacing:"letter-spacing",lightingColor:"lighting-color",markerEnd:"marker-end",markerMid:"marker-mid",markerStart:"marker-start",navDown:"nav-down",navDownLeft:"nav-down-left",navDownRight:"nav-down-right",navLeft:"nav-left",navNext:"nav-next",navPrev:"nav-prev",navRight:"nav-right",navUp:"nav-up",navUpLeft:"nav-up-left",navUpRight:"nav-up-right",onAbort:"onabort",onActivate:"onactivate",onAfterPrint:"onafterprint",onBeforePrint:"onbeforeprint",onBegin:"onbegin",onCancel:"oncancel",onCanPlay:"oncanplay",onCanPlayThrough:"oncanplaythrough",onChange:"onchange",onClick:"onclick",onClose:"onclose",onCopy:"oncopy",onCueChange:"oncuechange",onCut:"oncut",onDblClick:"ondblclick",onDrag:"ondrag",onDragEnd:"ondragend",onDragEnter:"ondragenter",onDragExit:"ondragexit",onDragLeave:"ondragleave",onDragOver:"ondragover",onDragStart:"ondragstart",onDrop:"ondrop",onDurationChange:"ondurationchange",onEmptied:"onemptied",onEnd:"onend",onEnded:"onended",onError:"onerror",onFocus:"onfocus",onFocusIn:"onfocusin",onFocusOut:"onfocusout",onHashChange:"onhashchange",onInput:"oninput",onInvalid:"oninvalid",onKeyDown:"onkeydown",onKeyPress:"onkeypress",onKeyUp:"onkeyup",onLoad:"onload",onLoadedData:"onloadeddata",onLoadedMetadata:"onloadedmetadata",onLoadStart:"onloadstart",onMessage:"onmessage",onMouseDown:"onmousedown",onMouseEnter:"onmouseenter",onMouseLeave:"onmouseleave",onMouseMove:"onmousemove",onMouseOut:"onmouseout",onMouseOver:"onmouseover",onMouseUp:"onmouseup",onMouseWheel:"onmousewheel",onOffline:"onoffline",onOnline:"ononline",onPageHide:"onpagehide",onPageShow:"onpageshow",onPaste:"onpaste",onPause:"onpause",onPlay:"onplay",onPlaying:"onplaying",onPopState:"onpopstate",onProgress:"onprogress",onRateChange:"onratechange",onRepeat:"onrepeat",onReset:"onreset",onResize:"onresize",onScroll:"onscroll",onSeeked:"onseeked",onSeeking:"onseeking",onSelect:"onselect",onShow:"onshow",onStalled:"onstalled",onStorage:"onstorage",onSubmit:"onsubmit",onSuspend:"onsuspend",onTimeUpdate:"ontimeupdate",onToggle:"ontoggle",onUnload:"onunload",onVolumeChange:"onvolumechange",onWaiting:"onwaiting",onZoom:"onzoom",overlinePosition:"overline-position",overlineThickness:"overline-thickness",paintOrder:"paint-order",panose1:"panose-1",pointerEvents:"pointer-events",referrerPolicy:"referrerpolicy",renderingIntent:"rendering-intent",shapeRendering:"shape-rendering",stopColor:"stop-color",stopOpacity:"stop-opacity",strikethroughPosition:"strikethrough-position",strikethroughThickness:"strikethrough-thickness",strokeDashArray:"stroke-dasharray",strokeDashOffset:"stroke-dashoffset",strokeLineCap:"stroke-linecap",strokeLineJoin:"stroke-linejoin",strokeMiterLimit:"stroke-miterlimit",strokeOpacity:"stroke-opacity",strokeWidth:"stroke-width",tabIndex:"tabindex",textAnchor:"text-anchor",textDecoration:"text-decoration",textRendering:"text-rendering",transformOrigin:"transform-origin",typeOf:"typeof",underlinePosition:"underline-position",underlineThickness:"underline-thickness",unicodeBidi:"unicode-bidi",unicodeRange:"unicode-range",unitsPerEm:"units-per-em",vAlphabetic:"v-alphabetic",vHanging:"v-hanging",vIdeographic:"v-ideographic",vMathematical:"v-mathematical",vectorEffect:"vector-effect",vertAdvY:"vert-adv-y",vertOriginX:"vert-origin-x",vertOriginY:"vert-origin-y",wordSpacing:"word-spacing",writingMode:"writing-mode",xHeight:"x-height",playbackOrder:"playbackorder",timelineBegin:"timelinebegin"},properties:{about:ti,accentHeight:fe,accumulate:null,additive:null,alignmentBaseline:null,alphabetic:fe,amplitude:fe,arabicForm:null,ascent:fe,attributeName:null,attributeType:null,azimuth:fe,bandwidth:null,baselineShift:null,baseFrequency:null,baseProfile:null,bbox:null,begin:null,bias:fe,by:null,calcMode:null,capHeight:fe,className:St,clip:null,clipPath:null,clipPathUnits:null,clipRule:null,color:null,colorInterpolation:null,colorInterpolationFilters:null,colorProfile:null,colorRendering:null,content:null,contentScriptType:null,contentStyleType:null,crossOrigin:null,cursor:null,cx:null,cy:null,d:null,dataType:null,defaultAction:null,descent:fe,diffuseConstant:fe,direction:null,display:null,dur:null,divisor:fe,dominantBaseline:null,download:Pe,dx:null,dy:null,edgeMode:null,editable:null,elevation:fe,enableBackground:null,end:null,event:null,exponent:fe,externalResourcesRequired:null,fill:null,fillOpacity:fe,fillRule:null,filter:null,filterRes:null,filterUnits:null,floodColor:null,floodOpacity:null,focusable:null,focusHighlight:null,fontFamily:null,fontSize:null,fontSizeAdjust:null,fontStretch:null,fontStyle:null,fontVariant:null,fontWeight:null,format:null,fr:null,from:null,fx:null,fy:null,g1:pl,g2:pl,glyphName:pl,glyphOrientationHorizontal:null,glyphOrientationVertical:null,glyphRef:null,gradientTransform:null,gradientUnits:null,handler:null,hanging:fe,hatchContentUnits:null,hatchUnits:null,height:null,href:null,hrefLang:null,horizAdvX:fe,horizOriginX:fe,horizOriginY:fe,id:null,ideographic:fe,imageRendering:null,initialVisibility:null,in:null,in2:null,intercept:fe,k:fe,k1:fe,k2:fe,k3:fe,k4:fe,kernelMatrix:ti,kernelUnitLength:null,keyPoints:null,keySplines:null,keyTimes:null,kerning:null,lang:null,lengthAdjust:null,letterSpacing:null,lightingColor:null,limitingConeAngle:fe,local:null,markerEnd:null,markerMid:null,markerStart:null,markerHeight:null,markerUnits:null,markerWidth:null,mask:null,maskContentUnits:null,maskUnits:null,mathematical:null,max:null,media:null,mediaCharacterEncoding:null,mediaContentEncodings:null,mediaSize:fe,mediaTime:null,method:null,min:null,mode:null,name:null,navDown:null,navDownLeft:null,navDownRight:null,navLeft:null,navNext:null,navPrev:null,navRight:null,navUp:null,navUpLeft:null,navUpRight:null,numOctaves:null,observer:null,offset:null,onAbort:null,onActivate:null,onAfterPrint:null,onBeforePrint:null,onBegin:null,onCancel:null,onCanPlay:null,onCanPlayThrough:null,onChange:null,onClick:null,onClose:null,onCopy:null,onCueChange:null,onCut:null,onDblClick:null,onDrag:null,onDragEnd:null,onDragEnter:null,onDragExit:null,onDragLeave:null,onDragOver:null,onDragStart:null,onDrop:null,onDurationChange:null,onEmptied:null,onEnd:null,onEnded:null,onError:null,onFocus:null,onFocusIn:null,onFocusOut:null,onHashChange:null,onInput:null,onInvalid:null,onKeyDown:null,onKeyPress:null,onKeyUp:null,onLoad:null,onLoadedData:null,onLoadedMetadata:null,onLoadStart:null,onMessage:null,onMouseDown:null,onMouseEnter:null,onMouseLeave:null,onMouseMove:null,onMouseOut:null,onMouseOver:null,onMouseUp:null,onMouseWheel:null,onOffline:null,onOnline:null,onPageHide:null,onPageShow:null,onPaste:null,onPause:null,onPlay:null,onPlaying:null,onPopState:null,onProgress:null,onRateChange:null,onRepeat:null,onReset:null,onResize:null,onScroll:null,onSeeked:null,onSeeking:null,onSelect:null,onShow:null,onStalled:null,onStorage:null,onSubmit:null,onSuspend:null,onTimeUpdate:null,onToggle:null,onUnload:null,onVolumeChange:null,onWaiting:null,onZoom:null,opacity:null,operator:null,order:null,orient:null,orientation:null,origin:null,overflow:null,overlay:null,overlinePosition:fe,overlineThickness:fe,paintOrder:null,panose1:null,path:null,pathLength:fe,patternContentUnits:null,patternTransform:null,patternUnits:null,phase:null,ping:St,pitch:null,playbackOrder:null,pointerEvents:null,points:null,pointsAtX:fe,pointsAtY:fe,pointsAtZ:fe,preserveAlpha:null,preserveAspectRatio:null,primitiveUnits:null,propagate:null,property:ti,r:null,radius:null,referrerPolicy:null,refX:null,refY:null,rel:ti,rev:ti,renderingIntent:null,repeatCount:null,repeatDur:null,requiredExtensions:ti,requiredFeatures:ti,requiredFonts:ti,requiredFormats:ti,resource:null,restart:null,result:null,rotate:null,rx:null,ry:null,scale:null,seed:null,shapeRendering:null,side:null,slope:null,snapshotTime:null,specularConstant:fe,specularExponent:fe,spreadMethod:null,spacing:null,startOffset:null,stdDeviation:null,stemh:null,stemv:null,stitchTiles:null,stopColor:null,stopOpacity:null,strikethroughPosition:fe,strikethroughThickness:fe,string:null,stroke:null,strokeDashArray:ti,strokeDashOffset:null,strokeLineCap:null,strokeLineJoin:null,strokeMiterLimit:fe,strokeOpacity:fe,strokeWidth:null,style:null,surfaceScale:fe,syncBehavior:null,syncBehaviorDefault:null,syncMaster:null,syncTolerance:null,syncToleranceDefault:null,systemLanguage:ti,tabIndex:fe,tableValues:null,target:null,targetX:fe,targetY:fe,textAnchor:null,textDecoration:null,textRendering:null,textLength:null,timelineBegin:null,title:null,transformBehavior:null,type:null,typeOf:ti,to:null,transform:null,transformOrigin:null,u1:null,u2:null,underlinePosition:fe,underlineThickness:fe,unicode:null,unicodeBidi:null,unicodeRange:null,unitsPerEm:fe,values:null,vAlphabetic:fe,vMathematical:fe,vectorEffect:null,vHanging:fe,vIdeographic:fe,version:null,vertAdvY:fe,vertOriginX:fe,vertOriginY:fe,viewBox:null,viewTarget:null,visibility:null,width:null,widths:null,wordSpacing:null,writingMode:null,x:null,x1:null,x2:null,xChannelSelector:null,xHeight:fe,y:null,y1:null,y2:null,yChannelSelector:null,z:null,zoomAndPan:null},space:"svg",transform:cS}),fS=Hl({properties:{xLinkActuate:null,xLinkArcRole:null,xLinkHref:null,xLinkRole:null,xLinkShow:null,xLinkTitle:null,xLinkType:null},space:"xlink",transform(e,t){return"xlink:"+t.slice(5).toLowerCase()}}),dS=Hl({attributes:{xmlnsxlink:"xmlns:xlink"},properties:{xmlnsXLink:null,xmlns:null},space:"xmlns",transform:uS}),hS=Hl({properties:{xmlBase:null,xmlLang:null,xmlSpace:null},space:"xml",transform(e,t){return"xml:"+t.slice(3).toLowerCase()}}),XR={classId:"classID",dataType:"datatype",itemId:"itemID",strokeDashArray:"strokeDasharray",strokeDashOffset:"strokeDashoffset",strokeLineCap:"strokeLinecap",strokeLineJoin:"strokeLinejoin",strokeMiterLimit:"strokeMiterlimit",typeOf:"typeof",xLinkActuate:"xlinkActuate",xLinkArcRole:"xlinkArcrole",xLinkHref:"xlinkHref",xLinkRole:"xlinkRole",xLinkShow:"xlinkShow",xLinkTitle:"xlinkTitle",xLinkType:"xlinkType",xmlnsXLink:"xmlnsXlink"},ZR=/[A-Z]/g,a0=/-[a-z]/g,WR=/^data[-\w.:]+$/i;function JR(e,t){const n=hp(t);let a=t,s=Hn;if(n in e.normal)return e.property[e.normal[n]];if(n.length>4&&n.slice(0,4)==="data"&&WR.test(t)){if(t.charAt(4)==="-"){const o=t.slice(5).replace(a0,tM);a="data"+o.charAt(0).toUpperCase()+o.slice(1)}else{const o=t.slice(4);if(!a0.test(o)){let c=o.replace(ZR,eM);c.charAt(0)!=="-"&&(c="-"+c),t="data"+c}}s=fg}return new s(a,t)}function eM(e){return"-"+e.toLowerCase()}function tM(e){return e.charAt(1).toUpperCase()}const nM=lS([oS,YR,fS,dS,hS],"html"),dg=lS([oS,VR,fS,dS,hS],"svg");function iM(e){return e.join(" ").trim()}var al={},Sm,r0;function aM(){if(r0)return Sm;r0=1;var e=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//g,t=/\n/g,n=/^\s*/,a=/^(\*?[-#/*\\\w]+(\[[0-9a-z_-]+\])?)\s*/,s=/^:\s*/,o=/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};])+)/,c=/^[;\s]*/,f=/^\s+|\s+$/g,d=`