@coralai/sps-cli 0.50.9 → 0.50.10

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.
@@ -1 +1 @@
1
- {"version":3,"file":"workers.d.ts","sourceRoot":"","sources":["../../../src/console/routes/workers.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AASrE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CA6C/D;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAuBxE"}
1
+ {"version":3,"file":"workers.d.ts","sourceRoot":"","sources":["../../../src/console/routes/workers.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AASrE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAkD/D;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAuBxE"}
@@ -33,11 +33,16 @@ export function createWorkersRoute(workers) {
33
33
  /* ignore */
34
34
  }
35
35
  const recentLogs = await readWorkerLogTail(project, slot, 20);
36
+ // v0.50.10:Claude code 实际输出走 sps-acp-<proj>-<slot>-acp-*.log
37
+ // (SessionUpdateAccumulator.appendLog 写入)。tick 的 pipeline-*.log 里
38
+ // 只有 supervisor 心跳,看不到 Claude 文本和工具调用。这里加一条独立 tail。
39
+ const recentOutput = await readAcpSessionLogTail(project, slot, 500);
36
40
  return c.json({
37
41
  ...r.value,
38
42
  markerPath: markerPath.replace(home(), '~'),
39
43
  markerData,
40
44
  recentLogs,
45
+ recentOutput,
41
46
  });
42
47
  });
43
48
  app.post('/:project/workers/:slot/kill', async (c) => {
@@ -114,6 +119,54 @@ async function readWorkerLogTail(project, slot, limit) {
114
119
  });
115
120
  return matches.slice(-limit);
116
121
  }
122
+ /**
123
+ * v0.50.10:读 ACP session log 尾部 N 行 —— Claude Code 真正的输出流。
124
+ *
125
+ * 文件命名:sps-acp-<project>-<slot>-acp-<ts>.log(AcpSdkAdapter 写入,SessionUpdateAccumulator.appendLog)
126
+ * 每行格式:`HH:mm:ss.SSS [assistant|tool:kind|tool_update|usage] <content>`
127
+ *
128
+ * 每次 run 会新建一个文件,所以列目录取当前 slot 匹配的最新一个。
129
+ */
130
+ async function readAcpSessionLogTail(project, slot, limit) {
131
+ const dir = logsDir(project);
132
+ if (!existsSync(dir))
133
+ return [];
134
+ const prefix = `sps-acp-${project}-worker-${slot}-acp-`;
135
+ const files = readdirSync(dir)
136
+ .filter((f) => f.startsWith(prefix) && f.endsWith('.log'))
137
+ .map((f) => ({ f, full: resolve(dir, f), mtime: statSync(resolve(dir, f)).mtimeMs }))
138
+ .sort((a, b) => b.mtime - a.mtime);
139
+ const file = files[0]?.full;
140
+ if (!file)
141
+ return [];
142
+ // 最多读尾部 8 MB(ACP session 可能很长)
143
+ const MAX_BYTES = 8 * 1024 * 1024;
144
+ const stat = statSync(file);
145
+ const start = Math.max(0, stat.size - MAX_BYTES);
146
+ const lines = [];
147
+ await new Promise((done) => {
148
+ const stream = createReadStream(file, { start, encoding: 'utf-8' });
149
+ const rl = createInterface({ input: stream });
150
+ rl.on('line', (raw) => {
151
+ if (!raw)
152
+ return;
153
+ // 格式:`HH:mm:ss.SSS [kind...] rest`
154
+ const m = raw.match(/^(\d{2}:\d{2}:\d{2}\.\d{3})\s+\[([^\]]+)\]\s?(.*)$/);
155
+ if (m) {
156
+ lines.push({ ts: m[1], kind: m[2], text: m[3] });
157
+ }
158
+ else {
159
+ // 不匹配就原样保留(比如 assistant 多行 content 被 \n 截断后的续行)
160
+ lines.push({ ts: null, kind: 'raw', text: raw });
161
+ }
162
+ if (lines.length > limit * 3)
163
+ lines.splice(0, lines.length - limit * 3);
164
+ });
165
+ rl.on('close', () => done());
166
+ rl.on('error', () => done());
167
+ });
168
+ return lines.slice(-limit);
169
+ }
117
170
  async function readLatestLogLine(project, slot) {
118
171
  const dir = logsDir(project);
119
172
  if (!existsSync(dir))
@@ -1 +1 @@
1
- {"version":3,"file":"workers.js","sourceRoot":"","sources":["../../../src/console/routes/workers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workers.js","sourceRoot":"","sources":["../../../src/console/routes/workers.ts"],"names":[],"mappings":"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"}
@@ -474,7 +474,8 @@ ${n.comment}`:n.comment}this.doc.range[2]=n.offset;break}default:this.errors.pus
474
474
  ${g.join(`
475
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(en,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(zl,{size:14,strokeWidth:3}),"永久删除"]})]})}function fg(e){const t=e?`?project=${encodeURIComponent(e)}`:"";return Bt(`/api/skills${t}`)}function qO(e){return Bt(`/api/skills/${encodeURIComponent(e)}`)}function HO(e,t){return Bt(`/api/skills/${encodeURIComponent(e)}/references/${encodeURIComponent(t)}`)}async function Zf(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 KO(e,t){return Zf(`/api/skills/${encodeURIComponent(e)}/link`,{project:t})}function GO(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 QO(e,t){return Zf(`/api/skills/${encodeURIComponent(e)}/freeze`,{project:t})}function YO(e,t){return Zf(`/api/skills/${encodeURIComponent(e)}/unfreeze`,{project:t})}function VO(){return Zf("/api/skills/sync")}function XO({project:e,isPending:t,onCancel:n,onCreate:a}){var j;const[s,o]=M.useState(""),[c,f]=M.useState(""),[d,h]=M.useState(new Set),[y,g]=M.useState(!0),x=dt({queryKey:["skills-all",e],queryFn:()=>fg(e)});M.useEffect(()=>{const C=D=>{D.key==="Escape"&&n()};return window.addEventListener("keydown",C),()=>window.removeEventListener("keydown",C)},[n]);const S=s.trim().length>0&&s.trim().length<=200&&!t,w=C=>{const D=new Set(d);D.has(C)?D.delete(C):D.add(C),h(D)},_=()=>{S&&a({title:s.trim(),description:c.trim(),skills:[...d],labels:y?["AI-PIPELINE"]:[]})},N=((j=x.data)==null?void 0:j.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:C=>{C.preventDefault(),_()},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:C=>o(C.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:C=>f(C.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)]}),N.length>0&&m.jsx("div",{className:"flex flex-wrap gap-2",children:N.map(C=>{const D=d.has(C.name);return m.jsx("button",{type:"button",onClick:()=>w(C.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:C.name},C.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:C=>g(C.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:_,disabled:!S,type:"button","aria-label":"创建卡片",children:[t?m.jsx(en,{size:13,strokeWidth:3,className:"animate-spin"}):m.jsx(Zi,{size:13,strokeWidth:3}),"创建"]})]})]})})}function ZO(e){return Bt(`/api/projects/${encodeURIComponent(e)}/cards`)}function WO(e,t){return Bt(`/api/projects/${encodeURIComponent(e)}/cards/${t}`)}async function Kl(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 JO(e,t){return Kl(`/api/projects/${encodeURIComponent(e)}/cards/${t}/reset`)}async function eR(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 tR(e,t){return Kl(`/api/projects/${encodeURIComponent(e)}/cards/${t}/launch`)}function nR(e,t){const n=typeof t=="string"?{title:t}:t;return Kl(`/api/projects/${encodeURIComponent(e)}/cards`,n)}async function iR(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 aR(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 rR(e){return Kl(`/api/projects/${encodeURIComponent(e)}/pipeline/start`)}function sR(e){return Kl(`/api/projects/${encodeURIComponent(e)}/pipeline/stop`)}function lR(e,t){return Kl(`/api/projects/${encodeURIComponent(e)}/pipeline/reset`,t??{})}function aS(e){const t=Tn();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 oR=new Set(["python","typescript","golang","rust","kotlin","swift","java"]),cR=new Set(["frontend","backend","mobile","database","devops"]),uR=new Set(["backend-architect","frontend-developer","code-reviewer","database-optimizer","devops-automator","security-engineer","qa-tester","security","qa","architect","db-opt"]),fR=new Set(["coding-standards","tdd-workflow","git-workflow","architecture-decision-records","debugging-workflow"]);function dR(e){return oR.has(e)?"lang":cR.has(e)?"end":uR.has(e)?"persona":fR.has(e)?"workflow":"other"}const hR={lang:"var(--color-accent-purple)",end:"var(--color-secondary)",persona:"var(--color-primary)",workflow:"var(--color-accent-mint)",other:"var(--color-bg)"};function rS({name:e}){const t=hR[dR(e)];return m.jsx("span",{className:"nb-badge",style:{background:t},children:e})}function sS({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 mR({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(rS,{name:o},o)),e.labels.filter(o=>o==="NEEDS-FIX").map(o=>m.jsx(sS,{label:o,kind:"warn"},o))]}),e.checklist&&e.checklist.total>0&&m.jsx(pR,{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:gR(e.updatedAt??e.createdAt)}),e.branch&&m.jsxs("span",{className:"truncate",children:["· ",e.branch]})]})]})}function pR({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 gR(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 bR({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(mR,{card:f,onClick:()=>a(f),done:e==="Done",draggable:!!s},f.seq))]})]})}function mp(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 wm(e){return mp(e,"描述")}function yR({project:e,seq:t,onClose:n,onChanged:a}){var ae,W,K,oe,V,me,O,L,J;const s=Tn(),{confirm:o,alert:c}=qn(),{data:f,isLoading:d,isError:h,error:y,refetch:g}=dt({queryKey:["card",e,t],queryFn:()=>WO(e,t)}),[x,v]=M.useState(!1),[S,w]=M.useState(""),[_,N]=M.useState(""),[j,C]=M.useState(new Set),[D,F]=M.useState([]),[R,q]=M.useState(""),U=dt({queryKey:["skills-all",e],queryFn:()=>fg(e),enabled:x});M.useEffect(()=>{x&&f&&(w(f.title),N(wm(f.body)),C(new Set(f.skills)),F([...f.labels]))},[x,f]),M.useEffect(()=>{const k=ce=>{ce.key==="Escape"&&(x?v(!1):n())};return window.addEventListener("keydown",k),()=>window.removeEventListener("keydown",k)},[n,x]);const Z=Pn({mutationFn:()=>{if(!f)throw new Error("no data");const k={},ce=S.trim();ce&&ce!==f.title&&(k.title=ce);const Ee=wm(f.body);_!==Ee&&(k.description=_);const xe=[...j].sort(),ze=[...f.skills].sort();return JSON.stringify(xe)!==JSON.stringify(ze)&&(k.skills=xe),JSON.stringify(D)!==JSON.stringify(f.labels)&&(k.labels=D),Object.keys(k).length===0?Promise.resolve({ok:!0,noop:!0}):aR(e,t,k)},onSuccess:()=>{s.invalidateQueries({queryKey:["card",e,t]}),s.invalidateQueries({queryKey:["cards",e]}),v(!1),a()},onError:k=>{c({title:"保存失败",body:k instanceof Error?k.message:String(k)})}}),A=M.useMemo(()=>{if(!x||!f)return!1;if(S.trim()!==f.title||_!==wm(f.body))return!0;const k=[...j].sort(),ce=[...f.skills].sort();return JSON.stringify(k)!==JSON.stringify(ce)||JSON.stringify(D)!==JSON.stringify(f.labels)},[x,f,S,_,j,D]),P=k=>{const ce=new Set(j);ce.has(k)?ce.delete(k):ce.add(k),C(ce)},G=()=>{const k=R.trim();if(k){if(D.includes(k)){q("");return}F([...D,k]),q("")}},le=k=>{F(D.filter(ce=>ce!==k))};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:k=>w(k.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(Gp,{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(ZC,{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(k=>{const ce=j.has(k.name);return m.jsx("button",{type:"button",onClick:()=>P(k.name),"aria-pressed":ce,className:["px-2.5 py-1 text-xs font-[family-name:var(--font-mono)] rounded-full border-2 transition-all",ce?"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:k.name},k.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(k=>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:[k,m.jsx("button",{type:"button",onClick:()=>le(k),className:"hover:text-[var(--color-crashed)]","aria-label":`删除 ${k}`,children:m.jsx(Er,{size:10,strokeWidth:3})})]},k)),m.jsx("input",{type:"text",className:"nb-input",style:{padding:"4px 8px",fontSize:12,width:140},placeholder:"+ 添加 label",value:R,onChange:k=>q(k.target.value),onKeyDown:k=>{k.key==="Enter"&&!k.nativeEvent.isComposing&&(k.preventDefault(),G())}}),R&&m.jsx("button",{type:"button",className:"nb-btn",style:{padding:"2px 6px",fontSize:11},onClick:G,"aria-label":"添加 label",children:m.jsx(Zi,{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(k=>m.jsx(rS,{name:k},k))})]}),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(k=>m.jsx(sS,{label:k,kind:k==="NEEDS-FIX"?"warn":"default"},k))})]})]}),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:_,onChange:k=>N(k.target.value),"aria-label":"卡片描述"}),m.jsx("p",{className:"text-[10px] text-[var(--color-text-muted)] mt-1",children:'只替换 "## 描述" 段的内容;检查清单和日志段不动。'})]}),(((me=f.checklist)==null?void 0:me.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:["检查清单 ",((O=f.checklist)==null?void 0:O.done)??0,"/",((L=f.checklist)==null?void 0:L.total)??0]})}),m.jsx("ul",{className:"text-sm space-y-1",children:(((J=f.checklist)==null?void 0:J.items)??[]).map((k,ce)=>m.jsxs("li",{className:`flex items-start gap-2 ${k.done?"opacity-60 line-through":""}`,children:[m.jsx("span",{children:k.done?"✓":"○"}),m.jsx("span",{children:k.text})]},ce))})]})]}):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:mp(f.body,"描述")||"(空)"})]}),(((ae=f.checklist)==null?void 0:ae.total)??0)>0&&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:[((W=f.checklist)==null?void 0:W.done)??0,"/",((K=f.checklist)==null?void 0:K.total)??0]})]}),m.jsxs("div",{className:"nb-card bg-[var(--color-bg-cream)] p-3",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:`${((oe=f.checklist)==null?void 0:oe.percent)??0}%`}})})}),m.jsx("ul",{className:"text-sm space-y-1",children:(((V=f.checklist)==null?void 0:V.items)??[]).map((k,ce)=>m.jsxs("li",{className:`flex items-start gap-2 ${k.done?"opacity-60 line-through":""}`,children:[m.jsx("span",{children:k.done?"✓":"○"}),m.jsx("span",{children:k.text})]},ce))})]})]}),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:mp(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:Z.isPending,children:"取消"}),m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"button",onClick:()=>Z.mutate(),disabled:!A||!S.trim()||Z.isPending,"aria-label":"保存卡片修改",children:[Z.isPending?m.jsx(en,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(zf,{size:14,strokeWidth:3}),"保存"]})]}):m.jsxs(m.Fragment,{children:[m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"button",onClick:async()=>{try{await tR(e,t),a()}catch(k){c({title:"启动 worker 失败",body:k instanceof Error?k.message:String(k)})}},children:[m.jsx(Qp,{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 JO(e,t),a(),n()}catch(ce){c({title:"重置失败",body:ce instanceof Error?ce.message:String(ce)})}},children:[m.jsx(If,{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 eR(e,t),a(),n()}catch(Ee){c({title:"删除失败",body:Ee instanceof Error?Ee.message:String(Ee)})}},"aria-label":"删除卡片",children:[m.jsx(zl,{size:14,strokeWidth:2.5}),"删除卡片"]})]})})]})]})})}function lS({current:e,onChange:t}){const[n,a]=M.useState(!1),s=M.useRef(null),{data:o}=dt({queryKey:["projects"],queryFn:Bl});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(Lf,{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 xR=[{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)"}],oS="sps-console:last-board-project";function vR(){if(typeof window>"u")return null;try{return localStorage.getItem(oS)}catch{return null}}function ER(e){if(!(typeof window>"u"))try{localStorage.setItem(oS,e)}catch{}}function SR(){var W,K,oe;const[e,t]=jf(),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}=qn();aS(n);const v=dt({queryKey:["projects"],queryFn:Bl}),S=dt({queryKey:["cards",n],queryFn:()=>ZO(n??""),enabled:!!n}),w=Tn(),_=()=>{w.invalidateQueries({queryKey:["cards",n]}),w.invalidateQueries({queryKey:["projects"]}),w.invalidateQueries({queryKey:["pipeline-status",n]})},N=V=>{t({project:V})};M.useEffect(()=>{var me;if(n){ER(n);return}const V=vR();V&&((me=v.data)!=null&&me.data.some(O=>O.name===V))&&t({project:V},{replace:!0})},[n,v.data,t]);const j=Pn({mutationFn:()=>rR(n),onSuccess:()=>{_()},onError:V=>{x({title:"启动 pipeline 失败",body:V instanceof Error?V.message:String(V)})}}),C=Pn({mutationFn:()=>sR(n),onSuccess:()=>_(),onError:V=>{x({title:"停止 pipeline 失败",body:V instanceof Error?V.message:String(V)})}}),D=Pn({mutationFn:()=>lR(n,{all:!0}),onSuccess:()=>_(),onError:V=>{x({title:"重置失败",body:V instanceof Error?V.message:String(V)})}}),[F,R]=M.useState(!1),q=Pn({mutationFn:V=>nR(n,V),onSuccess:()=>{_(),R(!1)},onError:V=>{x({title:"新建卡片失败",body:V instanceof Error?V.message:String(V)})}}),U=Pn({mutationFn:({seq:V,state:me})=>iR(n,V,me),onMutate:async({seq:V,state:me})=>{await w.cancelQueries({queryKey:["cards",n]});const O=w.getQueryData(["cards",n]);return O&&w.setQueryData(["cards",n],{...O,data:O.data.map(L=>L.seq===V?{...L,state:me}:L)}),{prev:O}},onError:(V,me,O)=>{O!=null&&O.prev&&w.setQueryData(["cards",n],O.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:A,allLabels:P}=M.useMemo(()=>{const V=new Set,me=new Set;for(const O of Z){for(const L of O.skills)V.add(L);for(const L of O.labels)me.add(L)}return{allSkills:[...V].sort(),allLabels:[...me].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:()=>N(V.name),type:"button",children:V.name},V.name))})]})]});const G=Z.filter(V=>{if(o){const me=o.toLowerCase();if(!(V.title.toLowerCase().includes(me)||V.skills.some(L=>L.toLowerCase().includes(me))||V.labels.some(L=>L.toLowerCase().includes(me))))return!1}return!(f.size>0&&!V.skills.some(O=>f.has(O))||h.size>0&&!V.labels.some(O=>h.has(O)))}),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(lS,{current:n,onChange:N}),m.jsxs("button",{className:ae?"nb-btn nb-btn-danger":"nb-btn nb-btn-primary",onClick:()=>ae?C.mutate():j.mutate(),disabled:j.isPending||C.isPending,type:"button","aria-label":ae?"停止 pipeline":"启动 pipeline",title:ae?"停止 pipeline":"启动 pipeline",children:[j.isPending||C.isPending?m.jsx(en,{size:14,strokeWidth:3,className:"animate-spin"}):ae?m.jsx(i1,{size:14,strokeWidth:3}):m.jsx(Qp,{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(en,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(If,{size:14,strokeWidth:2.5}),"重置"]}),m.jsxs("button",{className:"nb-btn nb-btn-mint",type:"button",onClick:()=>R(!0),disabled:q.isPending,children:[q.isPending?m.jsx(en,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(Zi,{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(a0,{label:"skill",options:A,selected:f,onChange:d}),m.jsx(a0,{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(VC,{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:xR.map(V=>m.jsx(bR,{label:V.label,bg:V.bg,cards:G.filter(wR(V.state)),onCardClick:me=>s(me.seq),onDropCard:me=>U.mutate({seq:me,state:V.state})},V.state))}),a!==null&&m.jsx(yR,{project:n,seq:a,onClose:()=>s(null),onChanged:_}),F&&m.jsx(XO,{project:n,isPending:q.isPending,onCancel:()=>R(!1),onCreate:V=>q.mutate(V)})]})}function wR(e){return t=>e==="QA"?t.state==="QA"||t.state==="Review":e==="Done"?t.state==="Done"||t.state==="Canceled":t.state===e}function a0({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(Lf,{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 _R(){return Bt("/api/workers/all")}function NR(e){return Bt(`/api/projects/${encodeURIComponent(e)}/workers`)}function kR(e,t){return Bt(`/api/projects/${encodeURIComponent(e)}/workers/${t}`)}async function cS(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 Rl(e,t){return cS(`/api/projects/${encodeURIComponent(e)}/workers/${t}/kill`)}function dg(e,t,n){return cS(`/api/projects/${encodeURIComponent(e)}/workers/${t}/launch`,n?{seq:n}:void 0)}function TR(){const[e,t]=jf(),n=e.get("project");aS(n);const a=Tn(),[s,o]=M.useState(null),{data:c,isLoading:f,isError:d,error:h,refetch:y}=dt({queryKey:["workers",n],queryFn:()=>NR(n??""),enabled:!!n,refetchInterval:5e3});if(!n)return m.jsxs("div",{className:"nb-card max-w-2xl bg-[var(--color-accent-yellow)]",children:[m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-2xl font-bold mb-2",children:"Workers 👷"}),m.jsxs("p",{className:"text-sm text-[var(--color-text-muted)]",children:["在 URL 上加 ",m.jsx("code",{className:"bg-[var(--color-bg)] border-2 border-[var(--color-text)] px-2 py-0.5 rounded",children:"?project=xx"}),",或从",m.jsx(ji,{to:"/projects",className:"underline font-semibold",children:" 项目列表"})," 打开看板后跳转。"]})]});const g=(c==null?void 0:c.data)??[],x=g.filter(w=>w.state==="running").length,v=g.filter(w=>w.state==="stuck").length,S=g.filter(w=>w.state==="crashed").length;return m.jsxs("div",{className:"flex flex-col gap-4 max-w-6xl",children:[m.jsxs("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:"Workers 👷"}),m.jsxs("p",{className:"text-sm text-[var(--color-text-muted)] mt-1",children:[g.length," 个 slot · ",x," running · ",v," stuck · ",S," crashed"]})]}),m.jsxs("div",{className:"flex gap-3 items-center",children:[m.jsx(lS,{current:n,onChange:w=>t({project:w})}),m.jsxs("button",{className:"nb-btn nb-btn-yellow",onClick:()=>y(),type:"button",children:[m.jsx(If,{size:14,strokeWidth:2.5})," 刷新"]})]})]}),f&&m.jsx("p",{className:"text-[var(--color-text-muted)]",children:"加载中…"}),d&&m.jsx("div",{className:"nb-card bg-[var(--color-crashed-bg)]",children:m.jsxs("p",{className:"font-semibold",children:["加载失败: ",h instanceof Error?h.message:String(h)]})}),!f&&g.length===0&&m.jsx("div",{className:"nb-card bg-[var(--color-bg-cream)]",children:m.jsx("p",{className:"text-[var(--color-text-muted)]",children:"当前没有 worker slot。启动一次 pipeline 就会出现。"})}),g.length>0&&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(Vr,{w:"70px",children:"Slot"}),m.jsx(Vr,{children:"Card"}),m.jsx(Vr,{w:"110px",children:"Status"}),m.jsx(Vr,{w:"90px",children:"Stage"}),m.jsx(Vr,{w:"90px",children:"PID"}),m.jsx(Vr,{w:"120px",children:"Runtime"}),m.jsx(Vr,{w:"260px",right:!0,children:"Action"})]})}),m.jsx("tbody",{children:g.map(w=>m.jsx(CR,{project:n,worker:w,onChange:()=>a.invalidateQueries({queryKey:["workers",n]}),onDetail:()=>o(w.slot)},w.slot))})]})}),s!==null&&m.jsx(AR,{project:n,slot:s,onClose:()=>o(null),onChange:()=>a.invalidateQueries({queryKey:["workers",n]})})]})}function Vr({children:e,w:t,right:n}){return m.jsx("th",{className:["px-4 py-3 text-left font-[family-name:var(--font-heading)] font-bold text-[12px] uppercase tracking-wider text-[var(--color-text-muted)]",n?"text-right":""].join(" "),style:t?{width:t}:void 0,children:e})}function CR({project:e,worker:t,onChange:n,onDetail:a}){const{confirm:s,alert:o}=qn(),c=t.state==="idle",f=t.state==="crashed"||t.state==="stuck";return m.jsxs("tr",{className:"border-b border-dashed border-[var(--color-border-light)] last:border-0 hover:bg-[var(--color-accent-yellow)] transition-colors",children:[m.jsx("td",{className:"px-4 py-3 font-[family-name:var(--font-mono)] font-bold",children:t.slot}),m.jsx("td",{className:"px-4 py-3",children:t.card?m.jsxs("span",{className:"font-semibold",children:[m.jsxs("span",{className:"inline-block px-2 py-0.5 text-xs bg-[var(--color-accent-purple)] border-2 border-[var(--color-text)] rounded-full font-[family-name:var(--font-mono)] mr-2",children:["#",t.card.seq]}),t.card.title]}):m.jsx("em",{className:"text-[var(--color-text-subtle)]",children:"— 空闲 —"})}),m.jsx("td",{className:"px-4 py-3",children:m.jsx(uS,{state:t.state})}),m.jsx("td",{className:"px-4 py-3 font-[family-name:var(--font-mono)] text-[var(--color-text-muted)]",children:t.stage||"—"}),m.jsx("td",{className:"px-4 py-3 font-[family-name:var(--font-mono)] text-[var(--color-text-muted)]",children:t.pid??"—"}),m.jsx("td",{className:"px-4 py-3 font-[family-name:var(--font-mono)] text-[var(--color-text-muted)]",children:fS(t.runtimeMs)}),m.jsxs("td",{className:"px-4 py-3 text-right space-x-2",children:[m.jsxs("button",{className:"nb-btn",style:{padding:"4px 10px",fontSize:11},onClick:a,type:"button","aria-label":`查看 worker-${t.slot} 详情`,children:[m.jsx(iA,{size:12,strokeWidth:2.5})," 详情"]}),f&&t.card&&m.jsxs("button",{className:"nb-btn nb-btn-mint",style:{padding:"4px 10px",fontSize:11},onClick:async()=>{if(await s({title:`重启 worker-${t.slot}`,body:`先杀掉当前进程,然后重新 launch 到卡 #${t.card.seq}。`,confirm:"重启"})){try{await Rl(e,t.slot)}catch{}try{await dg(e,t.slot,t.card.seq),n()}catch(h){o({title:"重启失败",body:h instanceof Error?h.message:String(h)})}}},type:"button",children:[m.jsx(hs,{size:12,strokeWidth:2.5})," 重启"]}),!c&&m.jsxs(m.Fragment,{children:[m.jsxs(ji,{to:`/logs?project=${encodeURIComponent(e)}&worker=${t.slot}`,className:"nb-btn",style:{display:"inline-flex",padding:"4px 10px",fontSize:11},children:[m.jsx(Yp,{size:12,strokeWidth:2.5})," log"]}),m.jsxs("button",{className:"nb-btn nb-btn-danger",style:{padding:"4px 10px",fontSize:11},onClick:async()=>{await s({title:`终止 worker-${t.slot}`,body:"当前任务会被强制中断,未保存的工作可能丢失。",confirm:"终止",danger:!0})&&(await Rl(e,t.slot),n())},type:"button",children:[m.jsx(Vp,{size:12,strokeWidth:2.5})," 终止"]})]})]})]})}function AR({project:e,slot:t,onClose:n,onChange:a}){const{confirm:s,alert:o}=qn(),{data:c,isLoading:f,isError:d,error:h,refetch:y}=dt({queryKey:["worker-detail",e,t],queryFn:()=>kR(e,t),refetchInterval:3e3});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-3xl",children:[m.jsxs("header",{className:"flex items-center justify-between mb-3",children:[m.jsxs("div",{children:[m.jsxs("h2",{className:"font-[family-name:var(--font-heading)] text-2xl font-bold",children:["worker-",t]}),m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] font-[family-name:var(--font-mono)] mt-0.5",children:e})]}),m.jsxs("div",{className:"flex gap-2",children:[m.jsxs("button",{className:"nb-btn",style:{padding:"6px 12px"},onClick:()=>y(),type:"button","aria-label":"刷新",children:[m.jsx(If,{size:12,strokeWidth:2.5})," 刷新"]}),m.jsx("button",{className:"nb-btn nb-btn-mint p-2",onClick:n,type:"button","aria-label":"关闭",children:"✕"})]})]}),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&&m.jsxs("div",{className:"flex flex-col gap-4",children:[m.jsx("div",{className:"nb-card bg-[var(--color-bg-cream)] p-4",children:m.jsxs("dl",{className:"grid grid-cols-[130px_1fr] gap-y-2 text-sm",children:[m.jsx("dt",{className:"font-bold",children:"状态"}),m.jsx("dd",{children:m.jsx(uS,{state:c.state})}),m.jsx("dt",{className:"font-bold",children:"PID"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:c.pid??"—"}),m.jsx("dt",{className:"font-bold",children:"Card"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:c.card?`#${c.card.seq} · ${c.card.title}`:"—"}),m.jsx("dt",{className:"font-bold",children:"Stage"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:c.stage??"—"}),m.jsx("dt",{className:"font-bold",children:"Runtime"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:fS(c.runtimeMs)}),m.jsx("dt",{className:"font-bold",children:"Marker"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)] text-xs text-[var(--color-text-muted)] break-all",children:c.markerPath}),m.jsx("dt",{className:"font-bold",children:"Marker 更新"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)] text-xs",children:c.markerUpdatedAt?`${new Date(c.markerUpdatedAt).toLocaleString()} (${OR(c.markerUpdatedAt)})`:"—"})]})}),m.jsxs("div",{children:[m.jsxs("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold mb-2 uppercase tracking-wider",children:["最近 ",c.recentLogs.length," 行日志"]}),c.recentLogs.length===0?m.jsxs("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:["没找到带 worker-",t," 标签的日志。去 Logs 页看全量。"]}):m.jsx("pre",{className:"text-xs font-[family-name:var(--font-mono)] bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-lg p-3 max-h-64 overflow-auto whitespace-pre-wrap break-words",children:c.recentLogs.map(g=>`${g.ts??""} [${g.level}] ${g.msg}`).join(`
477
+ `).trim()}function wm(e){return mp(e,"描述")}function yR({project:e,seq:t,onClose:n,onChanged:a}){var ae,W,K,oe,V,me,O,L,J;const s=Tn(),{confirm:o,alert:c}=qn(),{data:f,isLoading:d,isError:h,error:y,refetch:g}=dt({queryKey:["card",e,t],queryFn:()=>WO(e,t)}),[x,v]=M.useState(!1),[S,w]=M.useState(""),[_,N]=M.useState(""),[j,C]=M.useState(new Set),[D,F]=M.useState([]),[R,q]=M.useState(""),U=dt({queryKey:["skills-all",e],queryFn:()=>fg(e),enabled:x});M.useEffect(()=>{x&&f&&(w(f.title),N(wm(f.body)),C(new Set(f.skills)),F([...f.labels]))},[x,f]),M.useEffect(()=>{const k=ce=>{ce.key==="Escape"&&(x?v(!1):n())};return window.addEventListener("keydown",k),()=>window.removeEventListener("keydown",k)},[n,x]);const Z=Pn({mutationFn:()=>{if(!f)throw new Error("no data");const k={},ce=S.trim();ce&&ce!==f.title&&(k.title=ce);const Ee=wm(f.body);_!==Ee&&(k.description=_);const xe=[...j].sort(),ze=[...f.skills].sort();return JSON.stringify(xe)!==JSON.stringify(ze)&&(k.skills=xe),JSON.stringify(D)!==JSON.stringify(f.labels)&&(k.labels=D),Object.keys(k).length===0?Promise.resolve({ok:!0,noop:!0}):aR(e,t,k)},onSuccess:()=>{s.invalidateQueries({queryKey:["card",e,t]}),s.invalidateQueries({queryKey:["cards",e]}),v(!1),a()},onError:k=>{c({title:"保存失败",body:k instanceof Error?k.message:String(k)})}}),A=M.useMemo(()=>{if(!x||!f)return!1;if(S.trim()!==f.title||_!==wm(f.body))return!0;const k=[...j].sort(),ce=[...f.skills].sort();return JSON.stringify(k)!==JSON.stringify(ce)||JSON.stringify(D)!==JSON.stringify(f.labels)},[x,f,S,_,j,D]),P=k=>{const ce=new Set(j);ce.has(k)?ce.delete(k):ce.add(k),C(ce)},G=()=>{const k=R.trim();if(k){if(D.includes(k)){q("");return}F([...D,k]),q("")}},le=k=>{F(D.filter(ce=>ce!==k))};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:k=>w(k.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(Gp,{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(ZC,{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(k=>{const ce=j.has(k.name);return m.jsx("button",{type:"button",onClick:()=>P(k.name),"aria-pressed":ce,className:["px-2.5 py-1 text-xs font-[family-name:var(--font-mono)] rounded-full border-2 transition-all",ce?"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:k.name},k.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(k=>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:[k,m.jsx("button",{type:"button",onClick:()=>le(k),className:"hover:text-[var(--color-crashed)]","aria-label":`删除 ${k}`,children:m.jsx(Er,{size:10,strokeWidth:3})})]},k)),m.jsx("input",{type:"text",className:"nb-input",style:{padding:"4px 8px",fontSize:12,width:140},placeholder:"+ 添加 label",value:R,onChange:k=>q(k.target.value),onKeyDown:k=>{k.key==="Enter"&&!k.nativeEvent.isComposing&&(k.preventDefault(),G())}}),R&&m.jsx("button",{type:"button",className:"nb-btn",style:{padding:"2px 6px",fontSize:11},onClick:G,"aria-label":"添加 label",children:m.jsx(Zi,{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(k=>m.jsx(rS,{name:k},k))})]}),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(k=>m.jsx(sS,{label:k,kind:k==="NEEDS-FIX"?"warn":"default"},k))})]})]}),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:_,onChange:k=>N(k.target.value),"aria-label":"卡片描述"}),m.jsx("p",{className:"text-[10px] text-[var(--color-text-muted)] mt-1",children:'只替换 "## 描述" 段的内容;检查清单和日志段不动。'})]}),(((me=f.checklist)==null?void 0:me.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:["检查清单 ",((O=f.checklist)==null?void 0:O.done)??0,"/",((L=f.checklist)==null?void 0:L.total)??0]})}),m.jsx("ul",{className:"text-sm space-y-1",children:(((J=f.checklist)==null?void 0:J.items)??[]).map((k,ce)=>m.jsxs("li",{className:`flex items-start gap-2 ${k.done?"opacity-60 line-through":""}`,children:[m.jsx("span",{children:k.done?"✓":"○"}),m.jsx("span",{children:k.text})]},ce))})]})]}):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:mp(f.body,"描述")||"(空)"})]}),(((ae=f.checklist)==null?void 0:ae.total)??0)>0&&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:[((W=f.checklist)==null?void 0:W.done)??0,"/",((K=f.checklist)==null?void 0:K.total)??0]})]}),m.jsxs("div",{className:"nb-card bg-[var(--color-bg-cream)] p-3",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:`${((oe=f.checklist)==null?void 0:oe.percent)??0}%`}})})}),m.jsx("ul",{className:"text-sm space-y-1",children:(((V=f.checklist)==null?void 0:V.items)??[]).map((k,ce)=>m.jsxs("li",{className:`flex items-start gap-2 ${k.done?"opacity-60 line-through":""}`,children:[m.jsx("span",{children:k.done?"✓":"○"}),m.jsx("span",{children:k.text})]},ce))})]})]}),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:mp(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:Z.isPending,children:"取消"}),m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"button",onClick:()=>Z.mutate(),disabled:!A||!S.trim()||Z.isPending,"aria-label":"保存卡片修改",children:[Z.isPending?m.jsx(en,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(zf,{size:14,strokeWidth:3}),"保存"]})]}):m.jsxs(m.Fragment,{children:[m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"button",onClick:async()=>{try{await tR(e,t),a()}catch(k){c({title:"启动 worker 失败",body:k instanceof Error?k.message:String(k)})}},children:[m.jsx(Qp,{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 JO(e,t),a(),n()}catch(ce){c({title:"重置失败",body:ce instanceof Error?ce.message:String(ce)})}},children:[m.jsx(If,{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 eR(e,t),a(),n()}catch(Ee){c({title:"删除失败",body:Ee instanceof Error?Ee.message:String(Ee)})}},"aria-label":"删除卡片",children:[m.jsx(zl,{size:14,strokeWidth:2.5}),"删除卡片"]})]})})]})]})})}function lS({current:e,onChange:t}){const[n,a]=M.useState(!1),s=M.useRef(null),{data:o}=dt({queryKey:["projects"],queryFn:Bl});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(Lf,{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 xR=[{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)"}],oS="sps-console:last-board-project";function vR(){if(typeof window>"u")return null;try{return localStorage.getItem(oS)}catch{return null}}function ER(e){if(!(typeof window>"u"))try{localStorage.setItem(oS,e)}catch{}}function SR(){var W,K,oe;const[e,t]=jf(),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}=qn();aS(n);const v=dt({queryKey:["projects"],queryFn:Bl}),S=dt({queryKey:["cards",n],queryFn:()=>ZO(n??""),enabled:!!n}),w=Tn(),_=()=>{w.invalidateQueries({queryKey:["cards",n]}),w.invalidateQueries({queryKey:["projects"]}),w.invalidateQueries({queryKey:["pipeline-status",n]})},N=V=>{t({project:V})};M.useEffect(()=>{var me;if(n){ER(n);return}const V=vR();V&&((me=v.data)!=null&&me.data.some(O=>O.name===V))&&t({project:V},{replace:!0})},[n,v.data,t]);const j=Pn({mutationFn:()=>rR(n),onSuccess:()=>{_()},onError:V=>{x({title:"启动 pipeline 失败",body:V instanceof Error?V.message:String(V)})}}),C=Pn({mutationFn:()=>sR(n),onSuccess:()=>_(),onError:V=>{x({title:"停止 pipeline 失败",body:V instanceof Error?V.message:String(V)})}}),D=Pn({mutationFn:()=>lR(n,{all:!0}),onSuccess:()=>_(),onError:V=>{x({title:"重置失败",body:V instanceof Error?V.message:String(V)})}}),[F,R]=M.useState(!1),q=Pn({mutationFn:V=>nR(n,V),onSuccess:()=>{_(),R(!1)},onError:V=>{x({title:"新建卡片失败",body:V instanceof Error?V.message:String(V)})}}),U=Pn({mutationFn:({seq:V,state:me})=>iR(n,V,me),onMutate:async({seq:V,state:me})=>{await w.cancelQueries({queryKey:["cards",n]});const O=w.getQueryData(["cards",n]);return O&&w.setQueryData(["cards",n],{...O,data:O.data.map(L=>L.seq===V?{...L,state:me}:L)}),{prev:O}},onError:(V,me,O)=>{O!=null&&O.prev&&w.setQueryData(["cards",n],O.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:A,allLabels:P}=M.useMemo(()=>{const V=new Set,me=new Set;for(const O of Z){for(const L of O.skills)V.add(L);for(const L of O.labels)me.add(L)}return{allSkills:[...V].sort(),allLabels:[...me].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:()=>N(V.name),type:"button",children:V.name},V.name))})]})]});const G=Z.filter(V=>{if(o){const me=o.toLowerCase();if(!(V.title.toLowerCase().includes(me)||V.skills.some(L=>L.toLowerCase().includes(me))||V.labels.some(L=>L.toLowerCase().includes(me))))return!1}return!(f.size>0&&!V.skills.some(O=>f.has(O))||h.size>0&&!V.labels.some(O=>h.has(O)))}),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(lS,{current:n,onChange:N}),m.jsxs("button",{className:ae?"nb-btn nb-btn-danger":"nb-btn nb-btn-primary",onClick:()=>ae?C.mutate():j.mutate(),disabled:j.isPending||C.isPending,type:"button","aria-label":ae?"停止 pipeline":"启动 pipeline",title:ae?"停止 pipeline":"启动 pipeline",children:[j.isPending||C.isPending?m.jsx(en,{size:14,strokeWidth:3,className:"animate-spin"}):ae?m.jsx(i1,{size:14,strokeWidth:3}):m.jsx(Qp,{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(en,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(If,{size:14,strokeWidth:2.5}),"重置"]}),m.jsxs("button",{className:"nb-btn nb-btn-mint",type:"button",onClick:()=>R(!0),disabled:q.isPending,children:[q.isPending?m.jsx(en,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(Zi,{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(a0,{label:"skill",options:A,selected:f,onChange:d}),m.jsx(a0,{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(VC,{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:xR.map(V=>m.jsx(bR,{label:V.label,bg:V.bg,cards:G.filter(wR(V.state)),onCardClick:me=>s(me.seq),onDropCard:me=>U.mutate({seq:me,state:V.state})},V.state))}),a!==null&&m.jsx(yR,{project:n,seq:a,onClose:()=>s(null),onChanged:_}),F&&m.jsx(XO,{project:n,isPending:q.isPending,onCancel:()=>R(!1),onCreate:V=>q.mutate(V)})]})}function wR(e){return t=>e==="QA"?t.state==="QA"||t.state==="Review":e==="Done"?t.state==="Done"||t.state==="Canceled":t.state===e}function a0({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(Lf,{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 _R(){return Bt("/api/workers/all")}function NR(e){return Bt(`/api/projects/${encodeURIComponent(e)}/workers`)}function kR(e,t){return Bt(`/api/projects/${encodeURIComponent(e)}/workers/${t}`)}async function cS(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 Rl(e,t){return cS(`/api/projects/${encodeURIComponent(e)}/workers/${t}/kill`)}function dg(e,t,n){return cS(`/api/projects/${encodeURIComponent(e)}/workers/${t}/launch`,n?{seq:n}:void 0)}function TR(){const[e,t]=jf(),n=e.get("project");aS(n);const a=Tn(),[s,o]=M.useState(null),{data:c,isLoading:f,isError:d,error:h,refetch:y}=dt({queryKey:["workers",n],queryFn:()=>NR(n??""),enabled:!!n,refetchInterval:5e3});if(!n)return m.jsxs("div",{className:"nb-card max-w-2xl bg-[var(--color-accent-yellow)]",children:[m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-2xl font-bold mb-2",children:"Workers 👷"}),m.jsxs("p",{className:"text-sm text-[var(--color-text-muted)]",children:["在 URL 上加 ",m.jsx("code",{className:"bg-[var(--color-bg)] border-2 border-[var(--color-text)] px-2 py-0.5 rounded",children:"?project=xx"}),",或从",m.jsx(ji,{to:"/projects",className:"underline font-semibold",children:" 项目列表"})," 打开看板后跳转。"]})]});const g=(c==null?void 0:c.data)??[],x=g.filter(w=>w.state==="running").length,v=g.filter(w=>w.state==="stuck").length,S=g.filter(w=>w.state==="crashed").length;return m.jsxs("div",{className:"flex flex-col gap-4 max-w-6xl",children:[m.jsxs("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:"Workers 👷"}),m.jsxs("p",{className:"text-sm text-[var(--color-text-muted)] mt-1",children:[g.length," 个 slot · ",x," running · ",v," stuck · ",S," crashed"]})]}),m.jsxs("div",{className:"flex gap-3 items-center",children:[m.jsx(lS,{current:n,onChange:w=>t({project:w})}),m.jsxs("button",{className:"nb-btn nb-btn-yellow",onClick:()=>y(),type:"button",children:[m.jsx(If,{size:14,strokeWidth:2.5})," 刷新"]})]})]}),f&&m.jsx("p",{className:"text-[var(--color-text-muted)]",children:"加载中…"}),d&&m.jsx("div",{className:"nb-card bg-[var(--color-crashed-bg)]",children:m.jsxs("p",{className:"font-semibold",children:["加载失败: ",h instanceof Error?h.message:String(h)]})}),!f&&g.length===0&&m.jsx("div",{className:"nb-card bg-[var(--color-bg-cream)]",children:m.jsx("p",{className:"text-[var(--color-text-muted)]",children:"当前没有 worker slot。启动一次 pipeline 就会出现。"})}),g.length>0&&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(Vr,{w:"70px",children:"Slot"}),m.jsx(Vr,{children:"Card"}),m.jsx(Vr,{w:"110px",children:"Status"}),m.jsx(Vr,{w:"90px",children:"Stage"}),m.jsx(Vr,{w:"90px",children:"PID"}),m.jsx(Vr,{w:"120px",children:"Runtime"}),m.jsx(Vr,{w:"260px",right:!0,children:"Action"})]})}),m.jsx("tbody",{children:g.map(w=>m.jsx(CR,{project:n,worker:w,onChange:()=>a.invalidateQueries({queryKey:["workers",n]}),onDetail:()=>o(w.slot)},w.slot))})]})}),s!==null&&m.jsx(AR,{project:n,slot:s,onClose:()=>o(null),onChange:()=>a.invalidateQueries({queryKey:["workers",n]})})]})}function Vr({children:e,w:t,right:n}){return m.jsx("th",{className:["px-4 py-3 text-left font-[family-name:var(--font-heading)] font-bold text-[12px] uppercase tracking-wider text-[var(--color-text-muted)]",n?"text-right":""].join(" "),style:t?{width:t}:void 0,children:e})}function CR({project:e,worker:t,onChange:n,onDetail:a}){const{confirm:s,alert:o}=qn(),c=t.state==="idle",f=t.state==="crashed"||t.state==="stuck";return m.jsxs("tr",{className:"border-b border-dashed border-[var(--color-border-light)] last:border-0 hover:bg-[var(--color-accent-yellow)] transition-colors",children:[m.jsx("td",{className:"px-4 py-3 font-[family-name:var(--font-mono)] font-bold",children:t.slot}),m.jsx("td",{className:"px-4 py-3",children:t.card?m.jsxs("span",{className:"font-semibold",children:[m.jsxs("span",{className:"inline-block px-2 py-0.5 text-xs bg-[var(--color-accent-purple)] border-2 border-[var(--color-text)] rounded-full font-[family-name:var(--font-mono)] mr-2",children:["#",t.card.seq]}),t.card.title]}):m.jsx("em",{className:"text-[var(--color-text-subtle)]",children:"— 空闲 —"})}),m.jsx("td",{className:"px-4 py-3",children:m.jsx(uS,{state:t.state})}),m.jsx("td",{className:"px-4 py-3 font-[family-name:var(--font-mono)] text-[var(--color-text-muted)]",children:t.stage||"—"}),m.jsx("td",{className:"px-4 py-3 font-[family-name:var(--font-mono)] text-[var(--color-text-muted)]",children:t.pid??"—"}),m.jsx("td",{className:"px-4 py-3 font-[family-name:var(--font-mono)] text-[var(--color-text-muted)]",children:fS(t.runtimeMs)}),m.jsxs("td",{className:"px-4 py-3 text-right space-x-2",children:[m.jsxs("button",{className:"nb-btn",style:{padding:"4px 10px",fontSize:11},onClick:a,type:"button","aria-label":`查看 worker-${t.slot} 详情`,children:[m.jsx(iA,{size:12,strokeWidth:2.5})," 详情"]}),f&&t.card&&m.jsxs("button",{className:"nb-btn nb-btn-mint",style:{padding:"4px 10px",fontSize:11},onClick:async()=>{if(await s({title:`重启 worker-${t.slot}`,body:`先杀掉当前进程,然后重新 launch 到卡 #${t.card.seq}。`,confirm:"重启"})){try{await Rl(e,t.slot)}catch{}try{await dg(e,t.slot,t.card.seq),n()}catch(h){o({title:"重启失败",body:h instanceof Error?h.message:String(h)})}}},type:"button",children:[m.jsx(hs,{size:12,strokeWidth:2.5})," 重启"]}),!c&&m.jsxs(m.Fragment,{children:[m.jsxs(ji,{to:`/logs?project=${encodeURIComponent(e)}&worker=${t.slot}`,className:"nb-btn",style:{display:"inline-flex",padding:"4px 10px",fontSize:11},children:[m.jsx(Yp,{size:12,strokeWidth:2.5})," log"]}),m.jsxs("button",{className:"nb-btn nb-btn-danger",style:{padding:"4px 10px",fontSize:11},onClick:async()=>{await s({title:`终止 worker-${t.slot}`,body:"当前任务会被强制中断,未保存的工作可能丢失。",confirm:"终止",danger:!0})&&(await Rl(e,t.slot),n())},type:"button",children:[m.jsx(Vp,{size:12,strokeWidth:2.5})," 终止"]})]})]})]})}function AR({project:e,slot:t,onClose:n,onChange:a}){const{confirm:s,alert:o}=qn(),{data:c,isLoading:f,isError:d,error:h,refetch:y}=dt({queryKey:["worker-detail",e,t],queryFn:()=>kR(e,t),refetchInterval:3e3});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-3xl",children:[m.jsxs("header",{className:"flex items-center justify-between mb-3",children:[m.jsxs("div",{children:[m.jsxs("h2",{className:"font-[family-name:var(--font-heading)] text-2xl font-bold",children:["worker-",t]}),m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] font-[family-name:var(--font-mono)] mt-0.5",children:e})]}),m.jsxs("div",{className:"flex gap-2",children:[m.jsxs("button",{className:"nb-btn",style:{padding:"6px 12px"},onClick:()=>y(),type:"button","aria-label":"刷新",children:[m.jsx(If,{size:12,strokeWidth:2.5})," 刷新"]}),m.jsx("button",{className:"nb-btn nb-btn-mint p-2",onClick:n,type:"button","aria-label":"关闭",children:"✕"})]})]}),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&&m.jsxs("div",{className:"flex flex-col gap-4",children:[m.jsx("div",{className:"nb-card bg-[var(--color-bg-cream)] p-4",children:m.jsxs("dl",{className:"grid grid-cols-[130px_1fr] gap-y-2 text-sm",children:[m.jsx("dt",{className:"font-bold",children:"状态"}),m.jsx("dd",{children:m.jsx(uS,{state:c.state})}),m.jsx("dt",{className:"font-bold",children:"PID"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:c.pid??"—"}),m.jsx("dt",{className:"font-bold",children:"Card"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:c.card?`#${c.card.seq} · ${c.card.title}`:"—"}),m.jsx("dt",{className:"font-bold",children:"Stage"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:c.stage??"—"}),m.jsx("dt",{className:"font-bold",children:"Runtime"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:fS(c.runtimeMs)}),m.jsx("dt",{className:"font-bold",children:"Marker"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)] text-xs text-[var(--color-text-muted)] break-all",children:c.markerPath}),m.jsx("dt",{className:"font-bold",children:"Marker 更新"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)] text-xs",children:c.markerUpdatedAt?`${new Date(c.markerUpdatedAt).toLocaleString()} (${OR(c.markerUpdatedAt)})`:"—"})]})}),m.jsxs("div",{children:[m.jsxs("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold mb-2 uppercase tracking-wider",children:["Claude 输出 · 最近 ",c.recentOutput.length," 行"]}),c.recentOutput.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-lg p-3 max-h-96 overflow-auto whitespace-pre-wrap break-words",children:c.recentOutput.map(g=>`${g.ts?`${g.ts} [${g.kind}] `:`[${g.kind}] `}${g.text}`).join(`
478
+ `)})]}),m.jsxs("div",{children:[m.jsxs("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold mb-2 uppercase tracking-wider text-[var(--color-text-muted)]",children:["Supervisor 心跳 · 最近 ",c.recentLogs.length," 行"]}),c.recentLogs.length===0?m.jsxs("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:["没找到带 worker-",t," 标签的 supervisor 日志。"]}):m.jsx("pre",{className:"text-xs font-[family-name:var(--font-mono)] bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-lg p-3 max-h-40 overflow-auto whitespace-pre-wrap break-words",children:c.recentLogs.map(g=>`${g.ts??""} [${g.level}] ${g.msg}`).join(`
478
479
  `)}),m.jsx(ji,{to:`/logs?project=${encodeURIComponent(e)}&worker=${t}`,className:"inline-block mt-2 text-xs underline text-[var(--color-running)]",children:"查看完整 log →"})]}),m.jsxs("div",{className:"flex gap-2 justify-end border-t-2 border-dashed border-[var(--color-text)] pt-3",children:[(c.state==="crashed"||c.state==="stuck")&&c.card&&m.jsxs("button",{className:"nb-btn nb-btn-mint",onClick:async()=>{if(await s({title:`重启 worker-${t}`,body:`先杀掉当前进程,重新 launch 到卡 #${c.card.seq}。`,confirm:"重启"})){try{await Rl(e,t)}catch{}try{await dg(e,t,c.card.seq),a(),y()}catch(x){o({title:"重启失败",body:x instanceof Error?x.message:String(x)})}}},type:"button",children:[m.jsx(hs,{size:14,strokeWidth:2.5})," 重启"]}),c.state!=="idle"&&m.jsxs("button",{className:"nb-btn nb-btn-danger",onClick:async()=>{if(await s({title:`终止 worker-${t}`,body:"当前任务会被强制中断。",confirm:"终止",danger:!0}))try{await Rl(e,t),a(),y()}catch(x){o({title:"终止失败",body:x instanceof Error?x.message:String(x)})}},type:"button",children:[m.jsx(Vp,{size:14,strokeWidth:3})," 终止"]}),c.state==="running"&&m.jsx(en,{size:14,strokeWidth:3,className:"animate-spin self-center text-[var(--color-running)]"})]})]})]})})}function OR(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 uS({state:e}){const t={running:{bg:"var(--color-running-bg)",color:"var(--color-running)"},starting:{bg:"var(--color-secondary)",color:"var(--color-text)"},stuck:{bg:"var(--color-stuck-bg)",color:"var(--color-stuck)"},crashed:{bg:"var(--color-crashed-bg)",color:"var(--color-crashed)"},idle:{bg:"var(--color-idle-bg)",color:"var(--color-idle)"}},{bg:n,color:a}=t[e];return m.jsx("span",{className:"nb-status",style:{background:n,color:a},children:e})}function fS(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,o=c=>c.toString().padStart(2,"0");return n>0?`${o(n)}:${o(a)}:${o(s)}`:`${o(a)}:${o(s)}`}function RR(){var f;const e=Tn(),[t,n]=M.useState(null),a=dt({queryKey:["workers-agg"],queryFn:_R,refetchInterval:5e3});M.useEffect(()=>{if(!a.data)return;const d=a.data.capacity.map(y=>y.project),h=[];for(const y of d){const g=new EventSource(`/stream/projects/${encodeURIComponent(y)}`),x=()=>{e.invalidateQueries({queryKey:["workers-agg"]})};g.addEventListener("worker.updated",x),g.addEventListener("worker.added",x),g.addEventListener("worker.deleted",x),g.addEventListener("card.updated",x),h.push(g)}return()=>{for(const y of h)y.close()}},[(f=a.data)==null?void 0:f.capacity.map(d=>d.project).join(","),e]);const s=M.useMemo(()=>{var h,y;return[...((h=a.data)==null?void 0:h.alerts)??[],...((y=a.data)==null?void 0:y.active)??[]]},[a.data]),o=t&&s.find(d=>d.project===t.project&&d.slot===t.slot),c=M.useMemo(()=>{if(!a.data)return{projects:0,running:0,starting:0,stuck:0,crashed:0,idle:0};const d={projects:a.data.capacity.length,running:0,starting:0,stuck:0,crashed:0,idle:0};for(const h of a.data.capacity)d.running+=h.running,d.starting+=h.starting,d.stuck+=h.stuck,d.crashed+=h.crashed,d.idle+=h.idle;return d},[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:["跨 ",c.projects," 项目 · ",c.running," 跑 · ",c.starting," 启动 ·"," ",m.jsxs("span",{className:"text-[var(--color-stuck)]",children:[c.stuck," 卡"]})," ·"," ",m.jsxs("span",{className:"text-[var(--color-crashed)]",children:[c.crashed," 崩"]})," · ",c.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(en,{size:12,strokeWidth:3,className:"animate-spin"}):m.jsx(hs,{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(MR,{alerts:a.data.alerts,selected:t,onSelect:(d,h)=>n({project:d,slot:h})}),m.jsx(jR,{active:a.data.active,selected:t,onSelect:(d,h)=>n({project:d,slot:h})}),m.jsx(DR,{capacity:a.data.capacity})]})]}),m.jsx("aside",{className:"nb-card p-0 overflow-hidden flex flex-col h-full",children:o?m.jsx(zR,{worker:o,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(Df,{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 MR({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(Hp,{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(zA,{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(hg,{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(BC,{size:10,strokeWidth:2.5}),mg(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 停 ${pg(a.markerUpdatedAt)}。`})]},`${a.project}-${a.slot}`)})})]})}function jR({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(Df,{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(hg,{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)] ${BR(a.runtimeMs)}`,children:mg(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 ",pg(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(Yp,{size:9,strokeWidth:2.5,className:"inline-block mr-1 align-text-bottom"}),a.lastLogLine.msg]})]},`${a.project}-${a.slot}`)})})]})}function DR({capacity:e}){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(t=>{const n=t.running+t.starting+t.stuck+t.crashed;return m.jsxs("tr",{className:"border-b border-dashed border-[var(--color-border-light)] last:border-0 hover:bg-[var(--color-accent-yellow)]",children:[m.jsx("td",{className:"px-3 py-2 font-[family-name:var(--font-mono)] font-bold",children:t.project}),m.jsx("td",{className:"px-3 py-2",children:m.jsx(LR,{total:t.total,cap:t})}),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:t.running}),m.jsxs("span",{className:"text-[var(--color-text-muted)]",children:["/",t.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:[t.starting>0&&m.jsxs("span",{className:"mr-2",children:["starting ",t.starting]}),t.stuck>0&&m.jsxs("span",{className:"text-[var(--color-stuck)] font-bold mr-2",children:["stuck ",t.stuck]}),t.crashed>0&&m.jsxs("span",{className:"text-[var(--color-crashed)] font-bold mr-2",children:["crashed ",t.crashed]}),n===0&&m.jsx("span",{children:"idle"})]}),m.jsx("td",{className:"px-3 py-2 text-right",children:m.jsx(ji,{to:`/workers?project=${encodeURIComponent(t.project)}`,className:"text-xs underline text-[var(--color-text-muted)] hover:text-[var(--color-text)]",children:"详情 →"})})]},t.project)})})]})})]})}function LR({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:IR(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 IR(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 zR({worker:e,onChange:t}){const{confirm:n,alert:a}=qn(),s=e.state==="crashed"||e.state==="stuck";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)] flex items-center gap-2",children:[m.jsx(hg,{state:e.state}),m.jsxs("span",{className:"font-[family-name:var(--font-mono)] font-bold truncate",children:[e.project,"/worker-",e.slot]})]}),m.jsxs("div",{className:"flex-1 overflow-auto p-4 flex flex-col gap-4",children:[e.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:["#",e.card.seq," · ",e.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:e.stage??"—"}),m.jsx("dt",{className:"font-bold",children:"PID"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:e.pid??"—"}),m.jsx("dt",{className:"font-bold",children:"Runtime"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:mg(e.runtimeMs)}),m.jsx("dt",{className:"font-bold",children:"Started"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)] text-xs",children:e.startedAt?new Date(e.startedAt).toLocaleString():"—"}),m.jsx("dt",{className:"font-bold",children:"Marker"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)] text-xs",children:e.markerUpdatedAt?pg(e.markerUpdatedAt):"—"})]}),e.lastLogLine&&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(Yp,{size:10,strokeWidth:2.5}),"最近日志"]}),m.jsxs("pre",{className:"text-xs font-[family-name:var(--font-mono)] bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded p-2 whitespace-pre-wrap break-words",children:[e.lastLogLine.ts&&m.jsxs("span",{className:"text-[var(--color-text-muted)]",children:[e.lastLogLine.ts,`
479
480
  `]}),e.lastLogLine.msg]}),m.jsx(ji,{to:`/logs?project=${encodeURIComponent(e.project)}&worker=${e.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:[m.jsx(ji,{to:`/board?project=${encodeURIComponent(e.project)}${e.card?`&card=${e.card.seq}`:""}`,className:"nb-btn",style:{padding:"4px 10px",fontSize:11},children:"看板"}),s&&e.card&&m.jsxs("button",{type:"button",className:"nb-btn nb-btn-mint",style:{padding:"4px 10px",fontSize:11},onClick:async()=>{if(await n({title:`重启 worker-${e.slot}`,body:`先杀进程,再重新 launch 到 #${e.card.seq}`,confirm:"重启"})){try{await Rl(e.project,e.slot)}catch{}try{await dg(e.project,e.slot,e.card.seq),t()}catch(c){a({title:"重启失败",body:c instanceof Error?c.message:String(c)})}}},children:[m.jsx(DA,{size:11,strokeWidth:2.5})," 重启"]}),e.state!=="idle"&&m.jsxs("button",{type:"button",className:"nb-btn nb-btn-danger",style:{padding:"4px 10px",fontSize:11},onClick:async()=>{if(await n({title:`终止 worker-${e.slot}`,body:"当前任务强制中断。",confirm:"终止",danger:!0}))try{await Rl(e.project,e.slot),t()}catch(c){a({title:"终止失败",body:c instanceof Error?c.message:String(c)})}},children:[m.jsx(Vp,{size:11,strokeWidth:2.5})," 终止"]})]})]})}function hg({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(en,{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(CA,{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 mg(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 BR(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 pg(e){const t=Date.now()-new Date(e).getTime();return t<1e4?`${Math.floor(t/1e3)}s 前`:t<6e4?`${Math.floor(t/1e3)}s 前`:t<36e5?`${Math.floor(t/6e4)}m 前`:`${Math.floor(t/36e5)}h 前`}function UR(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),Bt(`/api/logs?${t}`)}function $R(e){const t=new URLSearchParams({project:e.project});return e.worker&&t.set("worker",e.worker),`/stream/logs?${t}`}const FR=["error","warn","info","debug"],PR=["error","warn","info"];function qR(){var U,Z;const[e,t]=jf(),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(PR)),[x,v]=M.useState(""),[S,w]=M.useState("live"),[_,N]=M.useState(()=>{const A=new Date(Date.now()-36e5),P=G=>String(G).padStart(2,"0");return`${A.getFullYear()}-${P(A.getMonth()+1)}-${P(A.getDate())}T${P(A.getHours())}:${P(A.getMinutes())}`}),j=M.useRef(null),C=!n,D=dt({queryKey:["projects"],queryFn:Bl}),{data:F,refetch:R}=dt({queryKey:["logs",n??"agg",a,S,S==="history"?_:"live"],queryFn:()=>UR({project:n||void 0,worker:a||void 0,limit:S==="history"?2e3:500,since:S==="history"?new Date(_).toISOString():void 0}),refetchInterval:C&&S==="live"?5e3:!1});M.useEffect(()=>{F!=null&&F.data&&o(F.data)},[F]),M.useEffect(()=>{if(!n||S!=="live")return;const A=$R({project:n,worker:a||void 0}),P=new EventSource(A);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 A=j.current;A&&(A.scrollTop=A.scrollHeight)},[s,d]);const q=M.useMemo(()=>{const A=x.toLowerCase();return s.filter(P=>!(!y.has(P.level)||A&&!P.msg.toLowerCase().includes(A)))},[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:[C?`全部项目(${((U=D.data)==null?void 0:U.data.length)??0})`:n,a&&` · worker-${a}`," · ",C&&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(t1,{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(tA,{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:_,onChange:A=>N(A.target.value),"aria-label":"查询起始时间"}),m.jsxs("button",{className:"nb-btn nb-btn-primary",style:{padding:"6px 12px",fontSize:12},onClick:()=>R(),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:A=>{const P=A.target.value;t(P?{project:P}:{})},"aria-label":"筛选项目",children:[m.jsx("option",{value:"",children:"全部项目"}),(Z=D.data)==null?void 0:Z.data.map(A=>m.jsx("option",{value:A.name,children:A.name},A.name))]}),m.jsx(Lf,{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:A=>v(A.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:FR.map(A=>m.jsx(HR,{level:A,enabled:y.has(A),onToggle:()=>{g(P=>{const G=new Set(P);return G.has(A)?G.delete(A):G.add(A),G})}},A))}),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(A=>!A),type:"button",children:d?"✓ Auto-scroll":"Auto-scroll"}),m.jsx("button",{className:"nb-btn",style:{padding:"6px 12px",fontSize:12},onClick:()=>f(A=>!A),type:"button",children:c?m.jsxs(m.Fragment,{children:[m.jsx(Qp,{size:12,strokeWidth:3})," Resume"]}):m.jsxs(m.Fragment,{children:[m.jsx(pA,{size:12,strokeWidth:3})," Pause"]})})]}),m.jsxs("button",{className:"nb-btn",style:{padding:"6px 12px",fontSize:12},onClick:()=>{const A=new Blob([q.map(le=>le.raw).join(`
480
481
  `)],{type:"text/plain"}),P=URL.createObjectURL(A),G=document.createElement("a");G.href=P,G.download=`${n}-log-${Date.now()}.log`,G.click(),URL.revokeObjectURL(P)},type:"button",children:[m.jsx(e1,{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:(F==null?void 0:F.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:j,className:"overflow-auto font-[family-name:var(--font-mono)] text-[12px] leading-[22px] max-h-[70vh] bg-[var(--color-bg)] p-2",onScroll:A=>{const P=A.currentTarget;!(P.scrollHeight-P.scrollTop-P.clientHeight<40)&&d&&h(!1)},children:[q.map((A,P)=>m.jsx(KR,{line:A},P)),q.length===0&&m.jsx("div",{className:"text-center py-12 text-[var(--color-text-subtle)]",children:"没有匹配的日志"})]})]})]})}function HR({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 KR({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 GR(e,t){const n={};return(e[e.length-1]===""?[...e,""]:e).join((n.padRight?" ":"")+","+(n.padLeft===!1?"":" ")).trim()}const QR=/^[$_\p{ID_Start}][$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,YR=/^[$_\p{ID_Start}][-$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,VR={};function r0(e,t){return(VR.jsx?YR:QR).test(e)}const XR=/[ \t\n\f\r]/g;function ZR(e){return typeof e=="object"?e.type==="text"?s0(e.value):!1:s0(e)}function s0(e){return e.replace(XR,"")===""}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 dS(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 pp(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 WR=0;const Fe=gs(),Xt=gs(),gp=gs(),fe=gs(),St=gs(),gl=gs(),ni=gs();function gs(){return 2**++WR}const bp=Object.freeze(Object.defineProperty({__proto__:null,boolean:Fe,booleanish:Xt,commaOrSpaceSeparated:ni,commaSeparated:gl,number:fe,overloadedBoolean:gp,spaceSeparated:St},Symbol.toStringTag,{value:"Module"})),_m=Object.keys(bp);class gg extends Hn{constructor(t,n,a,s){let o=-1;if(super(t,n),l0(this,"space",s),typeof a=="number")for(;++o<_m.length;){const c=_m[o];l0(this,_m[o],(a&bp[c])===bp[c])}}}gg.prototype.defined=!0;function l0(e,t,n){n&&(e[t]=n)}function Gl(e){const t={},n={};for(const[a,s]of Object.entries(e.properties)){const o=new gg(a,e.transform(e.attributes||{},a),s,e.space);e.mustUseProperty&&e.mustUseProperty.includes(a)&&(o.mustUseProperty=!0),t[a]=o,n[pp(a)]=a,n[pp(o.attribute)]=a}return new Sc(t,n,e.space)}const hS=Gl({properties:{ariaActiveDescendant:null,ariaAtomic:Xt,ariaAutoComplete:null,ariaBusy:Xt,ariaChecked:Xt,ariaColCount:fe,ariaColIndex:fe,ariaColSpan:fe,ariaControls:St,ariaCurrent:null,ariaDescribedBy:St,ariaDetails:null,ariaDisabled:Xt,ariaDropEffect:St,ariaErrorMessage:null,ariaExpanded:Xt,ariaFlowTo:St,ariaGrabbed:Xt,ariaHasPopup:null,ariaHidden:Xt,ariaInvalid:null,ariaKeyShortcuts:null,ariaLabel:null,ariaLabelledBy:St,ariaLevel:fe,ariaLive:null,ariaModal:Xt,ariaMultiLine:Xt,ariaMultiSelectable:Xt,ariaOrientation:null,ariaOwns:St,ariaPlaceholder:null,ariaPosInSet:fe,ariaPressed:Xt,ariaReadOnly:Xt,ariaRelevant:null,ariaRequired:Xt,ariaRoleDescription:St,ariaRowCount:fe,ariaRowIndex:fe,ariaRowSpan:fe,ariaSelected:Xt,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 mS(e,t){return t in e?e[t]:t}function pS(e,t){return mS(e,t.toLowerCase())}const JR=Gl({attributes:{acceptcharset:"accept-charset",classname:"class",htmlfor:"for",httpequiv:"http-equiv"},mustUseProperty:["checked","multiple","muted","selected"],properties:{abbr:null,accept:gl,acceptCharset:St,accessKey:St,action:null,allow:null,allowFullScreen:Fe,allowPaymentRequest:Fe,allowUserMedia:Fe,alt:null,as:null,async:Fe,autoCapitalize:null,autoComplete:St,autoFocus:Fe,autoPlay:Fe,blocking:St,capture:null,charSet:null,checked:Fe,cite:null,className:St,cols:fe,colSpan:null,content:null,contentEditable:Xt,controls:Fe,controlsList:St,coords:fe|gl,crossOrigin:null,data:null,dateTime:null,decoding:null,default:Fe,defer:Fe,dir:null,dirName:null,disabled:Fe,download:gp,draggable:Xt,encType:null,enterKeyHint:null,fetchPriority:null,form:null,formAction:null,formEncType:null,formMethod:null,formNoValidate:Fe,formTarget:null,headers:St,height:fe,hidden:gp,high:fe,href:null,hrefLang:null,htmlFor:St,httpEquiv:St,id:null,imageSizes:null,imageSrcSet:null,inert:Fe,inputMode:null,integrity:null,is:null,isMap:Fe,itemId:null,itemProp:St,itemRef:St,itemScope:Fe,itemType:St,kind:null,label:null,lang:null,language:null,list:null,loading:null,loop:Fe,low:fe,manifest:null,max:null,maxLength:fe,media:null,method:null,min:null,minLength:fe,multiple:Fe,muted:Fe,name:null,nonce:null,noModule:Fe,noValidate:Fe,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:Fe,optimum:fe,pattern:null,ping:St,placeholder:null,playsInline:Fe,popover:null,popoverTarget:null,popoverTargetAction:null,poster:null,preload:null,readOnly:Fe,referrerPolicy:null,rel:St,required:Fe,reversed:Fe,rows:fe,rowSpan:fe,sandbox:St,scope:null,scoped:Fe,seamless:Fe,selected:Fe,shadowRootClonable:Fe,shadowRootDelegatesFocus:Fe,shadowRootMode:null,shape:null,size:fe,sizes:null,slot:null,span:fe,spellCheck:Xt,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:Fe,useMap:null,value:Xt,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:Fe,declare:Fe,event:null,face:null,frame:null,frameBorder:null,hSpace:fe,leftMargin:fe,link:null,longDesc:null,lowSrc:null,marginHeight:fe,marginWidth:fe,noResize:Fe,noHref:Fe,noShade:Fe,noWrap:Fe,object:null,profile:null,prompt:null,rev:null,rightMargin:fe,rules:null,scheme:null,scrolling:Xt,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:Fe,disableRemotePlayback:Fe,prefix:null,property:null,results:fe,security:null,unselectable:null},space:"html",transform:pS}),eM=Gl({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:ni,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:Fe,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:gl,g2:gl,glyphName:gl,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:ni,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:ni,r:null,radius:null,referrerPolicy:null,refX:null,refY:null,rel:ni,rev:ni,renderingIntent:null,repeatCount:null,repeatDur:null,requiredExtensions:ni,requiredFeatures:ni,requiredFonts:ni,requiredFormats:ni,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:ni,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:ni,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:ni,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:mS}),gS=Gl({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()}}),bS=Gl({attributes:{xmlnsxlink:"xmlns:xlink"},properties:{xmlnsXLink:null,xmlns:null},space:"xmlns",transform:pS}),yS=Gl({properties:{xmlBase:null,xmlLang:null,xmlSpace:null},space:"xml",transform(e,t){return"xml:"+t.slice(3).toLowerCase()}}),tM={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"},nM=/[A-Z]/g,o0=/-[a-z]/g,iM=/^data[-\w.:]+$/i;function aM(e,t){const n=pp(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"&&iM.test(t)){if(t.charAt(4)==="-"){const o=t.slice(5).replace(o0,sM);a="data"+o.charAt(0).toUpperCase()+o.slice(1)}else{const o=t.slice(4);if(!o0.test(o)){let c=o.replace(nM,rM);c.charAt(0)!=="-"&&(c="-"+c),t="data"+c}}s=gg}return new s(a,t)}function rM(e){return"-"+e.toLowerCase()}function sM(e){return e.charAt(1).toUpperCase()}const lM=dS([hS,JR,gS,bS,yS],"html"),bg=dS([hS,eM,gS,bS,yS],"svg");function oM(e){return e.join(" ").trim()}var rl={},Nm,c0;function cM(){if(c0)return Nm;c0=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=`
@@ -7,7 +7,7 @@
7
7
  <link rel="preconnect" href="https://fonts.googleapis.com">
8
8
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
9
  <link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&family=DM+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
10
- <script type="module" crossorigin src="/assets/index-CGiD8z0L.js"></script>
10
+ <script type="module" crossorigin src="/assets/index-BdOli9a5.js"></script>
11
11
  <link rel="stylesheet" crossorigin href="/assets/index-BoeKHzoZ.css">
12
12
  </head>
13
13
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coralai/sps-cli",
3
- "version": "0.50.9",
3
+ "version": "0.50.10",
4
4
  "description": "SPS CLI — AI-driven development pipeline orchestrator",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",