@humwick/server 0.130.3 → 0.130.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/docs/openapi.json +103 -1
  2. package/package.json +6 -6
  3. package/public/assets/{MessageBubble-Bq9kr21N.js → MessageBubble-BOkmEvgZ.js} +2 -2
  4. package/public/assets/{PlanGraphPanel-Dqiroy06.js → PlanGraphPanel-BkaDJp0r.js} +2 -2
  5. package/public/assets/{TraceView-DYU962-H.js → TraceView-B99Uu2yT.js} +2 -2
  6. package/public/assets/{VaultDecisionCard-DhPfzioE.js → VaultDecisionCard-DUIfTTFF.js} +2 -2
  7. package/public/assets/{activity-DzCcQTee.js → activity-ZIX0N1El.js} +2 -2
  8. package/public/assets/{agent-lineage-SgDt9i3T.js → agent-lineage-kq9TPYFw.js} +2 -2
  9. package/public/assets/agent-liveness-DSQY1Aa_.js +2 -0
  10. package/public/assets/{agent-name-CcY3Aijy.js → agent-name-C_7F4DFR.js} +2 -2
  11. package/public/assets/{agent-profiles-cxtRBn6O.js → agent-profiles-BNOcrGcY.js} +2 -2
  12. package/public/assets/{agent-project-badge-DGYbIhaI.js → agent-project-badge-B6yAh70a.js} +2 -2
  13. package/public/assets/{agent-tools-DHbftV0N.js → agent-tools-CcrhmOzF.js} +2 -2
  14. package/public/assets/{agent-type-icon-CY113sp-.js → agent-type-icon-CXSLrKiq.js} +2 -2
  15. package/public/assets/{agents-BPzY7IlQ.js → agents-DIZG97_X.js} +2 -2
  16. package/public/assets/{analytics-DENFPv_a.js → analytics-rasmoPjR.js} +2 -2
  17. package/public/assets/{artifact-viewer-KRvSc7sl.js → artifact-viewer-tBpTrEPb.js} +2 -2
  18. package/public/assets/{artifacts-C9gSmL3s.js → artifacts-BNkrynP1.js} +2 -2
  19. package/public/assets/{artifacts-DT-HkI5O.js → artifacts-Bjq-ZyBA.js} +2 -2
  20. package/public/assets/{automation-BsmjQhKD.js → automation-Cx422L3L.js} +2 -2
  21. package/public/assets/{backlog-8NYH_62t.js → backlog-RuFQ8PUu.js} +2 -2
  22. package/public/assets/{busy-health-D3hwvYb4.js → busy-health-BvNQ9g5x.js} +2 -2
  23. package/public/assets/{channels-DCJ5WL7O.js → channels-DNbKAS0I.js} +2 -2
  24. package/public/assets/{chat-DAIl357U.js → chat-Bp3Fx73h.js} +2 -2
  25. package/public/assets/{code-preview-CzrZfr9U.js → code-preview-KIRZA6cz.js} +2 -2
  26. package/public/assets/{connectors-xTxtlyou.js → connectors-k7vO4vvc.js} +2 -2
  27. package/public/assets/{cosmos-BpebFLK2.js → cosmos-BuVoq1aw.js} +2 -2
  28. package/public/assets/{crate-agent-BHvI5wXC.js → crate-agent-irqlt4NH.js} +2 -2
  29. package/public/assets/{dependency-graph-DGT0o3wJ.js → dependency-graph-D_rurNBz.js} +2 -2
  30. package/public/assets/{deploys-hqWOHSHE.js → deploys-yzZqIpxE.js} +2 -2
  31. package/public/assets/{display-CDeH4I8T.js → display-BemJG1f_.js} +2 -2
  32. package/public/assets/{files-BTeGVmTg.js → files-DXWcrxOz.js} +2 -2
  33. package/public/assets/{fleet-DgXtNgCa.js → fleet-TEuOCZXE.js} +2 -2
  34. package/public/assets/{fleet-metrics-BHEt5yc_.js → fleet-metrics-BGoDAFI-.js} +2 -2
  35. package/public/assets/{formatted-body-impl-CAe664Z8.js → formatted-body-impl-BB9eq9nN.js} +2 -2
  36. package/public/assets/{formatted-body-MLtodyPp.js → formatted-body-qy2nTD_1.js} +3 -3
  37. package/public/assets/{host-providers-dialog-mapF4Fj9.js → host-providers-dialog-BGPHxuwT.js} +2 -2
  38. package/public/assets/{index-CqqgOI5R.js → index-BC5XZc0z.js} +5 -5
  39. package/public/assets/{index-MYAIwYTX.css → index-D8Rp9pz2.css} +1 -1
  40. package/public/assets/{insights-DNyf7IzF.js → insights-C-KQG0h-.js} +2 -2
  41. package/public/assets/{integrations-DlYOHq7T.js → integrations-ClPRPyKU.js} +2 -2
  42. package/public/assets/{issue-ref-chip-CeWBNWn7.js → issue-ref-chip-DbH8J9Ak.js} +2 -2
  43. package/public/assets/{log-viewer-Cib8nqdE.js → log-viewer-PH4zVn24.js} +2 -2
  44. package/public/assets/{maintenance-DSn1cPm7.js → maintenance-5lV43uTL.js} +2 -2
  45. package/public/assets/{managed-agents-C3CkM81m.js → managed-agents-BdgU35aX.js} +2 -2
  46. package/public/assets/{markdown-preview-W4VQQPAv.js → markdown-preview-DNT4OUwQ.js} +3 -3
  47. package/public/assets/{markdown-preview-impl-CMsTdhjq.js → markdown-preview-impl-CnCcPy0A.js} +2 -2
  48. package/public/assets/{memory-BV17qtO4.js → memory--GgWH1gH.js} +2 -2
  49. package/public/assets/{messages-Bm_1AqSA.js → messages-CzFl_97O.js} +2 -2
  50. package/public/assets/{orchestrators-Dg-vfP09.js → orchestrators-CVvJVkzv.js} +2 -2
  51. package/public/assets/overview-DsrZvE86.js +2 -0
  52. package/public/assets/{pairs-8o9nuG3V.js → pairs-D2d0d2py.js} +2 -2
  53. package/public/assets/{profile-icon-BsRyBMea.js → profile-icon-_SMuSbYF.js} +2 -2
  54. package/public/assets/{project-profile-instructions-DETKFn_E.js → project-profile-instructions-Apn15y43.js} +2 -2
  55. package/public/assets/{projects-M_m6AHws.js → projects-D3B6kto5.js} +2 -2
  56. package/public/assets/{prompt-settings-C_mNCgeL.js → prompt-settings-DnPB6Ez6.js} +2 -2
  57. package/public/assets/provider-display-bWwiuedV.js +2 -0
  58. package/public/assets/{registry-DDHHHE5N.js → registry-D790cIhN.js} +2 -2
  59. package/public/assets/{run-card-Dt4I4jaP.js → run-card-BCro-Odj.js} +2 -2
  60. package/public/assets/{secrets-BkVwxI5O.js → secrets-CVXvfvbU.js} +2 -2
  61. package/public/assets/{service-access-settings-Crq-6a-B.js → service-access-settings-D3Xxqb9w.js} +2 -2
  62. package/public/assets/{settings-CYcavMFu.js → settings-CoUC7Jci.js} +2 -2
  63. package/public/assets/{shipping-H6gzEeZB.js → shipping-D_Lp9n_J.js} +2 -2
  64. package/public/assets/{stats-BJVeWkpV.js → stats-CXiNjB9S.js} +2 -2
  65. package/public/assets/{status-dot-BcHyw1Vw.js → status-dot-C703YIy1.js} +2 -2
  66. package/public/assets/store-BgDALGIX.js +9 -0
  67. package/public/assets/{tasks-qJjlQPpx.js → tasks-DO0WpJCx.js} +2 -2
  68. package/public/assets/{teams-Cd5Sk1uX.js → teams-FGkdi_tL.js} +2 -2
  69. package/public/assets/{terminal-viewer-CpY5_m7W.js → terminal-viewer-Dh8dSC7e.js} +3 -3
  70. package/public/assets/{terminal-viewer-impl-DI_2llFR.js → terminal-viewer-impl-B5Zriip3.js} +2 -2
  71. package/public/assets/{use-agent-terminal-0yJA_buM.js → use-agent-terminal-CRUVDvLC.js} +2 -2
  72. package/public/assets/{use-decisions-uJXHf34W.js → use-decisions-CoaqRh4l.js} +2 -2
  73. package/public/assets/{use-project-list-CpWl6eHQ.js → use-project-list-X-BgT53X.js} +2 -2
  74. package/public/assets/{use-selectors-BdxBW8mL.js → use-selectors-0X_UZkk-.js} +2 -2
  75. package/public/assets/{user-avatar-3IndfpOc.js → user-avatar-CkLhVBGu.js} +2 -2
  76. package/public/assets/{versioned-prompt-editor-CIVg7XB1.js → versioned-prompt-editor-BkTi7eim.js} +2 -2
  77. package/public/assets/{work-queue-B9rnLwHZ.js → work-queue-DDOLEyKo.js} +2 -2
  78. package/public/assets/{workflow-marker-X8wxyhzC.js → workflow-marker-CzOsB8BM.js} +2 -2
  79. package/public/assets/{workflows-o5YyMFW7.js → workflows-DJilvmRM.js} +2 -2
  80. package/public/assets/{workspaces-CzEGoAng.js → workspaces-CHcfbLR3.js} +2 -2
  81. package/public/cosmos.html +4 -4
  82. package/public/index.html +29 -29
  83. package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
  84. package/runner/src/adapters/claude-api.ts +1 -1
  85. package/runner/src/provider-setup.ts +2 -2
  86. package/src/auth/login-link.ts +35 -0
  87. package/src/cli/index.ts +7 -1
  88. package/src/cli/init.ts +53 -0
  89. package/src/cli/orchestrator.ts +1 -7
  90. package/src/cli/setup.ts +6 -4
  91. package/src/db/spawn-delegation.ts +2 -1
  92. package/src/db/workflow-execution.ts +3 -3
  93. package/src/dev.ts +4 -13
  94. package/src/init.ts +299 -0
  95. package/src/invite-link.ts +16 -9
  96. package/src/routes/auth.ts +30 -2
  97. package/src/routes/host-providers.ts +18 -0
  98. package/src/routes/index.ts +5 -2
  99. package/src/routes/orchestrator-bootstrap.ts +2 -0
  100. package/src/routes/secrets-backup.ts +2 -3
  101. package/src/routes/secrets-import.ts +2 -3
  102. package/src/routes/secrets-vault.ts +5 -7
  103. package/src/runtime-install.ts +30 -0
  104. package/src/server.ts +4 -4
  105. package/src/services/auth-context.ts +6 -0
  106. package/src/services/provider-api-key.ts +73 -0
  107. package/src/setup.ts +47 -8
  108. package/src/utils.ts +7 -0
  109. package/public/assets/agent-liveness-Bq-s73jW.js +0 -2
  110. package/public/assets/overview-DcYCrvlr.js +0 -2
  111. package/public/assets/provider-display-BEeLXC_D.js +0 -2
  112. package/public/assets/store-DKPDIZBe.js +0 -9
@@ -1,6 +1,6 @@
1
- import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{o as t,p as n,u as r}from"./dist-DeW2Y1R5.js";import{t as i}from"./store-DKPDIZBe.js";import"./provider-display-BEeLXC_D.js";import{h as a}from"./display-CDeH4I8T.js";import{i as o,r as s,t as c}from"./file-code-corner-CXhIR1vB.js";import{a as l,i as u,n as d,o as f,r as p,s as m,t as h}from"./dialog-uuJ9_geR.js";import{t as ee}from"./switch-DuCA7mrB.js";import{i as g,r as _,t as v}from"./tabs-jZgNvNHr.js";import{t as y}from"./arrow-right-vFsRqG8V.js";import{t as b}from"./git-commit-horizontal-DS1pJ_SS.js";import{n as x,r as S}from"./workflow-marker-X8wxyhzC.js";import{t as C}from"./button-Do6Z3vvn.js";import{t as w}from"./copy-button-CjOj4HEf.js";import{t as T}from"./textarea-hs6Mpyfl.js";import{n as E,r as D}from"./shipping-stats-BiMTsA4A.js";import{a as O,i as te,n as k,r as A,t as j}from"./run-card-Dt4I4jaP.js";import{n as M,r as ne}from"./stats-BJVeWkpV.js";var N=r(),P={running:`Running`,done:`Done`,escalated:`Escalated`,cancelled:`Cancelled`,failed:`Failed`};function F({route:e}){return(0,N.jsxs)(`li`,{className:`flex flex-wrap items-center gap-1 text-xs`,children:[(0,N.jsx)(`span`,{className:`rounded bg-muted px-1.5 font-mono text-[11px]`,children:e.on}),(0,N.jsx)(y,{className:`h-3 w-3 shrink-0 text-muted-foreground`,"aria-label":`goes to`}),(0,N.jsx)(`span`,{className:`font-medium`,children:e.to}),e.condition!==void 0&&(0,N.jsxs)(`code`,{children:[`if `,String(e.condition)]}),e.max!==void 0&&(0,N.jsxs)(`span`,{className:`text-muted-foreground`,children:[`at most `,e.max===1?`once`:`${e.max} times`,`, then `,e.else]})]})}function I({step:e}){let t=[...e.decision?[`wait for operator`,...e.decision.deadlineMs?[`deadline ${D(e.decision.deadlineMs)}`]:[]]:e.script?[`host ${e.script.host}`,...e.script.everyMs?[`poll every ${D(e.script.everyMs)}`]:[],`time limit ${D(e.script.timeoutMs)}`]:[e.task===`input`?`on the run’s Task`:`on a new Task`],e.gate&&`verdict gate ${e.gate}`,e.crossProvider&&`another provider than ${e.crossProvider}`,e.reap&&`reap ${e.reap}`,e.timeoutMs!==void 0&&`time limit ${D(e.timeoutMs)}`].filter(Boolean);return(0,N.jsxs)(`li`,{"data-testid":`workflow-def-step-${e.name}`,className:`grid min-w-0 gap-1.5 border-t border-border/60 py-2 first:border-t-0 sm:grid-cols-[minmax(0,14rem)_1fr] sm:gap-4`,children:[(0,N.jsxs)(`div`,{className:`min-w-0`,children:[(0,N.jsxs)(`div`,{className:`flex flex-wrap items-baseline gap-x-2`,children:[(0,N.jsx)(`span`,{className:`text-sm font-semibold`,children:e.name}),(0,N.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:e.script?`script`:`role ${e.role}`})]}),(0,N.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:t.join(` · `)}),e.script&&(0,N.jsx)(`code`,{className:`block break-all text-xs`,children:e.script.run})]}),(0,N.jsx)(`ul`,{"aria-label":`${e.name} routes`,className:`space-y-1`,children:e.routes.map((e,t)=>(0,N.jsx)(F,{route:e},`${e.on}-${t}`))})]})}function re({def:e,now:t,project:n}){let r=[...!e.stations||e.stations.includes(`land`)?[`land${e.land?.timeoutMs===void 0?``:` (time limit ${D(e.land.timeoutMs)})`}`]:[],...e.ciMain?[`CI on main${e.ciMain.workflow?` (${e.ciMain.workflow})`:``}${e.ciMain.timeoutMs===void 0?``:`, up to ${D(e.ciMain.timeoutMs)}`}`]:[]];return(0,N.jsxs)(`article`,{"data-testid":`workflow-def-${e.workflow}`,"aria-label":`${e.workflow} definition`,className:`wf-run min-w-0 space-y-2 rounded-lg p-3`,children:[(0,N.jsxs)(`header`,{className:`flex flex-wrap items-center gap-x-3 gap-y-1`,children:[(0,N.jsxs)(`h3`,{className:`flex min-w-0 max-w-full items-center gap-1.5 text-sm font-semibold`,children:[(0,N.jsx)(x,{workflow:e.workflow,className:`h-3.5 w-3.5 shrink-0`}),(0,N.jsx)(O,{text:e.workflow})]}),(0,N.jsxs)(`span`,{className:`flex min-w-0 items-center gap-1 text-xs text-muted-foreground`,title:`.agent-relay/workflows/${e.workflow}.yaml at ${e.ref} ${e.sha}`,children:[(0,N.jsx)(b,{className:`h-3.5 w-3.5 shrink-0`,"aria-hidden":!0}),(0,N.jsxs)(`span`,{className:`truncate`,children:[`.agent-relay/workflows/`,e.workflow,`.yaml`]}),(0,N.jsxs)(`span`,{className:`shrink-0 font-mono`,children:[e.ref,` `,e.sha.slice(0,7)]})]}),n&&(0,N.jsx)(O,{text:n,className:`text-xs text-muted-foreground`})]}),e.description&&(0,N.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e.description}),(0,N.jsx)(`ol`,{"aria-label":`Steps`,children:e.steps.map(e=>(0,N.jsx)(I,{step:e},e.name))}),r.length>0&&(0,N.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`After the steps: `,r.join(`, then `),`.`]}),(0,N.jsxs)(`footer`,{className:`flex flex-wrap items-center gap-x-2 gap-y-1 border-t border-border/60 pt-2 text-xs text-muted-foreground`,children:[(0,N.jsx)(`span`,{children:`Last run`}),(0,N.jsx)(`span`,{className:`font-medium text-foreground`,children:P[e.lastRun.status]}),(0,N.jsx)(`div`,{className:`min-w-0 flex-1`,children:(0,N.jsx)(A,{taskId:e.lastRun.taskId,title:e.lastRun.taskTitle})}),(0,N.jsxs)(`span`,{title:new Date(e.lastRun.at).toLocaleString(),children:[a(t,e.lastRun.at),` ago`]})]})]})}function ie({projectTitles:e}){let t=i(e=>e.workflowDefinitions),n=i(e=>e.workflowLoading),r=i(e=>e.workflowError),a=Date.now();return(0,N.jsxs)(`div`,{className:`space-y-3`,children:[(0,N.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Each workflow a run used, as its newest run read the file from the repo’s default branch. Edit the file and land it to change the next run.`}),r&&(0,N.jsxs)(`div`,{className:`rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive`,children:[`Could not load the workflows: `,r]}),!t&&n&&(0,N.jsx)(`div`,{className:`py-8 text-center text-sm text-muted-foreground`,children:`Loading the workflows…`}),t&&t.length===0&&(0,N.jsx)(`p`,{className:`rounded-md border border-dashed border-border px-3 py-8 text-center text-sm text-muted-foreground`,children:`No workflow has run yet. A coordinator starts one with relay_workflow_start.`}),t&&t.map(t=>(0,N.jsx)(re,{def:t,now:a,project:t.lastRun.projectId?e.get(t.lastRun.projectId):void 0},t.workflow))]})}var L=e(n(),1);function R(e){let t=Math.max(0,...Array.from(e.matchAll(/`+/g),e=>e[0].length));return"`".repeat(Math.max(3,t+1))}function z(e){let t=R(e.text),n=e.path.endsWith(`.yaml`)?`yaml`:`markdown`;return`${e.path}\n\n${t}${n}\n${e.text}${e.text.endsWith(`
1
+ import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{o as t,p as n,u as r}from"./dist-DeW2Y1R5.js";import{t as i}from"./store-BgDALGIX.js";import"./provider-display-bWwiuedV.js";import{h as a}from"./display-BemJG1f_.js";import{i as o,r as s,t as c}from"./file-code-corner-CXhIR1vB.js";import{a as l,i as u,n as d,o as f,r as p,s as m,t as h}from"./dialog-uuJ9_geR.js";import{t as ee}from"./switch-DuCA7mrB.js";import{i as g,r as _,t as v}from"./tabs-jZgNvNHr.js";import{t as y}from"./arrow-right-vFsRqG8V.js";import{t as b}from"./git-commit-horizontal-DS1pJ_SS.js";import{n as x,r as S}from"./workflow-marker-CzOsB8BM.js";import{t as C}from"./button-Do6Z3vvn.js";import{t as w}from"./copy-button-CjOj4HEf.js";import{t as T}from"./textarea-hs6Mpyfl.js";import{n as E,r as D}from"./shipping-stats-BiMTsA4A.js";import{a as O,i as te,n as k,r as A,t as j}from"./run-card-BCro-Odj.js";import{n as M,r as ne}from"./stats-CXiNjB9S.js";var N=r(),P={running:`Running`,done:`Done`,escalated:`Escalated`,cancelled:`Cancelled`,failed:`Failed`};function F({route:e}){return(0,N.jsxs)(`li`,{className:`flex flex-wrap items-center gap-1 text-xs`,children:[(0,N.jsx)(`span`,{className:`rounded bg-muted px-1.5 font-mono text-[11px]`,children:e.on}),(0,N.jsx)(y,{className:`h-3 w-3 shrink-0 text-muted-foreground`,"aria-label":`goes to`}),(0,N.jsx)(`span`,{className:`font-medium`,children:e.to}),e.condition!==void 0&&(0,N.jsxs)(`code`,{children:[`if `,String(e.condition)]}),e.max!==void 0&&(0,N.jsxs)(`span`,{className:`text-muted-foreground`,children:[`at most `,e.max===1?`once`:`${e.max} times`,`, then `,e.else]})]})}function I({step:e}){let t=[...e.decision?[`wait for operator`,...e.decision.deadlineMs?[`deadline ${D(e.decision.deadlineMs)}`]:[]]:e.script?[`host ${e.script.host}`,...e.script.everyMs?[`poll every ${D(e.script.everyMs)}`]:[],`time limit ${D(e.script.timeoutMs)}`]:[e.task===`input`?`on the run’s Task`:`on a new Task`],e.gate&&`verdict gate ${e.gate}`,e.crossProvider&&`another provider than ${e.crossProvider}`,e.reap&&`reap ${e.reap}`,e.timeoutMs!==void 0&&`time limit ${D(e.timeoutMs)}`].filter(Boolean);return(0,N.jsxs)(`li`,{"data-testid":`workflow-def-step-${e.name}`,className:`grid min-w-0 gap-1.5 border-t border-border/60 py-2 first:border-t-0 sm:grid-cols-[minmax(0,14rem)_1fr] sm:gap-4`,children:[(0,N.jsxs)(`div`,{className:`min-w-0`,children:[(0,N.jsxs)(`div`,{className:`flex flex-wrap items-baseline gap-x-2`,children:[(0,N.jsx)(`span`,{className:`text-sm font-semibold`,children:e.name}),(0,N.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:e.script?`script`:`role ${e.role}`})]}),(0,N.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:t.join(` · `)}),e.script&&(0,N.jsx)(`code`,{className:`block break-all text-xs`,children:e.script.run})]}),(0,N.jsx)(`ul`,{"aria-label":`${e.name} routes`,className:`space-y-1`,children:e.routes.map((e,t)=>(0,N.jsx)(F,{route:e},`${e.on}-${t}`))})]})}function re({def:e,now:t,project:n}){let r=[...!e.stations||e.stations.includes(`land`)?[`land${e.land?.timeoutMs===void 0?``:` (time limit ${D(e.land.timeoutMs)})`}`]:[],...e.ciMain?[`CI on main${e.ciMain.workflow?` (${e.ciMain.workflow})`:``}${e.ciMain.timeoutMs===void 0?``:`, up to ${D(e.ciMain.timeoutMs)}`}`]:[]];return(0,N.jsxs)(`article`,{"data-testid":`workflow-def-${e.workflow}`,"aria-label":`${e.workflow} definition`,className:`wf-run min-w-0 space-y-2 rounded-lg p-3`,children:[(0,N.jsxs)(`header`,{className:`flex flex-wrap items-center gap-x-3 gap-y-1`,children:[(0,N.jsxs)(`h3`,{className:`flex min-w-0 max-w-full items-center gap-1.5 text-sm font-semibold`,children:[(0,N.jsx)(x,{workflow:e.workflow,className:`h-3.5 w-3.5 shrink-0`}),(0,N.jsx)(O,{text:e.workflow})]}),(0,N.jsxs)(`span`,{className:`flex min-w-0 items-center gap-1 text-xs text-muted-foreground`,title:`.agent-relay/workflows/${e.workflow}.yaml at ${e.ref} ${e.sha}`,children:[(0,N.jsx)(b,{className:`h-3.5 w-3.5 shrink-0`,"aria-hidden":!0}),(0,N.jsxs)(`span`,{className:`truncate`,children:[`.agent-relay/workflows/`,e.workflow,`.yaml`]}),(0,N.jsxs)(`span`,{className:`shrink-0 font-mono`,children:[e.ref,` `,e.sha.slice(0,7)]})]}),n&&(0,N.jsx)(O,{text:n,className:`text-xs text-muted-foreground`})]}),e.description&&(0,N.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e.description}),(0,N.jsx)(`ol`,{"aria-label":`Steps`,children:e.steps.map(e=>(0,N.jsx)(I,{step:e},e.name))}),r.length>0&&(0,N.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`After the steps: `,r.join(`, then `),`.`]}),(0,N.jsxs)(`footer`,{className:`flex flex-wrap items-center gap-x-2 gap-y-1 border-t border-border/60 pt-2 text-xs text-muted-foreground`,children:[(0,N.jsx)(`span`,{children:`Last run`}),(0,N.jsx)(`span`,{className:`font-medium text-foreground`,children:P[e.lastRun.status]}),(0,N.jsx)(`div`,{className:`min-w-0 flex-1`,children:(0,N.jsx)(A,{taskId:e.lastRun.taskId,title:e.lastRun.taskTitle})}),(0,N.jsxs)(`span`,{title:new Date(e.lastRun.at).toLocaleString(),children:[a(t,e.lastRun.at),` ago`]})]})]})}function ie({projectTitles:e}){let t=i(e=>e.workflowDefinitions),n=i(e=>e.workflowLoading),r=i(e=>e.workflowError),a=Date.now();return(0,N.jsxs)(`div`,{className:`space-y-3`,children:[(0,N.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Each workflow a run used, as its newest run read the file from the repo’s default branch. Edit the file and land it to change the next run.`}),r&&(0,N.jsxs)(`div`,{className:`rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive`,children:[`Could not load the workflows: `,r]}),!t&&n&&(0,N.jsx)(`div`,{className:`py-8 text-center text-sm text-muted-foreground`,children:`Loading the workflows…`}),t&&t.length===0&&(0,N.jsx)(`p`,{className:`rounded-md border border-dashed border-border px-3 py-8 text-center text-sm text-muted-foreground`,children:`No workflow has run yet. A coordinator starts one with relay_workflow_start.`}),t&&t.map(t=>(0,N.jsx)(re,{def:t,now:a,project:t.lastRun.projectId?e.get(t.lastRun.projectId):void 0},t.workflow))]})}var L=e(n(),1);function R(e){let t=Math.max(0,...Array.from(e.matchAll(/`+/g),e=>e[0].length));return"`".repeat(Math.max(3,t+1))}function z(e){let t=R(e.text),n=e.path.endsWith(`.yaml`)?`yaml`:`markdown`;return`${e.path}\n\n${t}${n}\n${e.text}${e.text.endsWith(`
2
2
  `)?``:`
3
3
  `}${t}`}function B(e){let t=e.files.map(e=>e.path),n=t.length>1?`${t.slice(0,-1).join(`, `)} and ${t[t.length-1]}`:t[0]??``;return{title:`Override the bundled ${e.workflow} workflow in ${e.projectName}`,intent:`Land ${n} on the default branch with exactly the content in the context, so relay_workflow_start ${e.workflow} uses the project's files instead of Relay's bundled ones. Change nothing else.`,context:e.files.map(z).join(`
4
4
 
5
5
  `),doneWhen:`${n} landed on the default branch with this content.`,projectId:e.projectId}}var V={bundled:`Bundled`,project:`Project`,"project-overrides-bundled":`Overrides bundled`},H={bundled:`border-border text-muted-foreground`,project:`border-primary/40 text-primary`,"project-overrides-bundled":`border-tone-warning/50 text-tone-warning-fg`};function U({source:e}){return e?(0,N.jsx)(`span`,{"data-testid":`catalog-source`,className:t(`shrink-0 rounded-full border px-1.5 text-[11px] font-medium`,H[e]),children:V[e]}):(0,N.jsx)(`span`,{className:`rounded-full border border-destructive/50 px-1.5 text-[11px] text-destructive`,children:`Missing`})}function W(e,t){return[...new Set((e.steps??[]).map(e=>e.role))].flatMap(e=>t.filter(t=>t.name===e))}function G({label:e,text:t}){return(0,N.jsxs)(`section`,{className:`space-y-1`,children:[(0,N.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,N.jsx)(`h4`,{className:`min-w-0 truncate font-mono text-xs text-muted-foreground`,children:e}),(0,N.jsx)(w,{value:t,label:`Copy ${e}`})]}),(0,N.jsx)(`pre`,{className:`max-h-[50vh] overflow-auto rounded-md border border-border bg-muted/40 p-3 font-mono text-xs leading-relaxed`,children:t})]})}function K({entry:e,roles:t,onClose:n}){return(0,N.jsx)(h,{open:!0,onOpenChange:e=>!e&&n(),children:(0,N.jsxs)(p,{className:`max-w-3xl`,children:[(0,N.jsxs)(f,{children:[(0,N.jsxs)(m,{className:`flex items-center gap-2`,children:[(0,N.jsx)(x,{workflow:e.name,className:`h-4 w-4`}),e.name,(0,N.jsx)(U,{source:e.source})]}),e.description&&(0,N.jsx)(u,{children:e.description})]}),(0,N.jsxs)(d,{className:`space-y-4`,children:[(0,N.jsx)(G,{label:e.source===`bundled`?`Bundled ${e.name}.yaml`:e.path,text:e.text}),e.bundledText!==void 0&&(0,N.jsx)(G,{label:`Bundled ${e.name}.yaml (overridden)`,text:e.bundledText}),t.map(e=>(0,N.jsxs)(`details`,{className:`rounded-md border border-border px-3 py-2`,children:[(0,N.jsxs)(`summary`,{className:`flex cursor-pointer flex-wrap items-center gap-2 text-sm`,children:[(0,N.jsxs)(`span`,{className:`font-medium`,children:[`Role `,e.name]}),(0,N.jsx)(U,{source:e.source}),e.description&&(0,N.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:e.description})]}),e.error&&(0,N.jsx)(`p`,{className:`mt-2 text-xs text-destructive`,children:e.error}),e.text!==void 0&&(0,N.jsx)(`div`,{className:`mt-2`,children:(0,N.jsx)(G,{label:e.source===`bundled`?`Bundled ${e.name}.md`:e.path,text:e.text})})]},e.name))]}),(0,N.jsx)(l,{children:(0,N.jsx)(C,{variant:`outline`,onClick:n,children:`Close`})})]})})}function q({entry:e,roles:t,project:n,onClose:r}){let a=i(e=>e.createWorkflowOverrideTask),o=t.filter(e=>e.source===`bundled`&&e.text!==void 0),[s,c]=(0,L.useState)(e.text),[g,_]=(0,L.useState)({}),[v,y]=(0,L.useState)(!1),[b,x]=(0,L.useState)(null);async function S(){y(!0);let t=[{path:e.path,text:s},...o.filter(e=>g[e.name]!==void 0).map(e=>({path:e.path,text:g[e.name]}))],r=await a(B({projectId:n.id,projectName:n.name,workflow:e.name,files:t}));y(!1),r!==null&&x(r)}return(0,N.jsx)(h,{open:!0,onOpenChange:e=>!e&&r(),children:(0,N.jsxs)(p,{className:`max-w-3xl`,children:[(0,N.jsxs)(f,{children:[(0,N.jsxs)(m,{children:[`Override `,e.name,` in `,n.name]}),(0,N.jsxs)(u,{children:[`Edit the copy of Relay's bundled workflow. The Task asks a builder to land it at `,(0,N.jsx)(`span`,{className:`font-mono`,children:e.path}),`; until it lands, runs keep using the bundled one.`]})]}),b===null?(0,N.jsxs)(d,{className:`space-y-4`,children:[(0,N.jsxs)(`label`,{className:`block space-y-1`,children:[(0,N.jsx)(`span`,{className:`font-mono text-xs text-muted-foreground`,children:e.path}),(0,N.jsx)(T,{"aria-label":e.path,spellCheck:!1,className:`max-h-[50vh] font-mono text-xs md:text-xs`,value:s,onChange:e=>c(e.target.value)})]}),o.map(e=>{let t=g[e.name];return(0,N.jsxs)(`div`,{className:`space-y-1`,children:[(0,N.jsxs)(`label`,{className:`flex items-center gap-2 text-sm`,children:[(0,N.jsx)(ee,{checked:t!==void 0,onCheckedChange:t=>_(n=>{let r={...n};return t?r[e.name]=e.text:delete r[e.name],r})}),`Also override role `,e.name,` `,(0,N.jsx)(`span`,{className:`font-mono text-xs text-muted-foreground`,children:e.path})]}),t!==void 0&&(0,N.jsx)(T,{"aria-label":e.path,spellCheck:!1,className:`max-h-[50vh] font-mono text-xs md:text-xs`,value:t,onChange:t=>_(n=>({...n,[e.name]:t.target.value}))})]},e.name)})]}):(0,N.jsxs)(d,{className:`space-y-2`,children:[(0,N.jsx)(`p`,{children:`Created the override Task. Dispatch it to land the files.`}),(0,N.jsx)(`div`,{className:`text-sm`,children:(0,N.jsx)(A,{taskId:b,title:`Override the bundled ${e.name} workflow in ${n.name}`})})]}),(0,N.jsx)(l,{children:b===null?(0,N.jsxs)(N.Fragment,{children:[(0,N.jsx)(w,{value:s,label:`Copy YAML`,showText:!0,variant:`outline`}),(0,N.jsx)(C,{disabled:v||!s.trim(),onClick:()=>void S(),children:`Create override Task`})]}):(0,N.jsx)(C,{variant:`outline`,onClick:r,children:`Close`})})]})})}function J({entry:e,roles:t,canOverride:n,onView:r,onOverride:i}){let a=new Map(t.map(e=>[e.name,e]));return(0,N.jsxs)(`article`,{"data-testid":`workflow-catalog-${e.name}`,"aria-label":`${e.name} workflow`,className:`wf-run min-w-0 space-y-2 rounded-lg p-3`,children:[(0,N.jsxs)(`header`,{className:`flex flex-wrap items-center gap-x-3 gap-y-1`,children:[(0,N.jsxs)(`h3`,{className:`flex min-w-0 max-w-full items-center gap-1.5 text-sm font-semibold`,children:[(0,N.jsx)(x,{workflow:e.name,className:`h-3.5 w-3.5 shrink-0`}),(0,N.jsx)(O,{text:e.name})]}),(0,N.jsx)(U,{source:e.source}),(0,N.jsxs)(`span`,{className:`flex min-w-0 items-center gap-1 text-xs text-muted-foreground`,title:e.source===`bundled`?`A project file at ${e.path} would override it`:e.path,children:[(0,N.jsx)(c,{className:`h-3.5 w-3.5 shrink-0`,"aria-hidden":!0}),(0,N.jsx)(`span`,{className:`truncate font-mono`,children:e.source===`bundled`?`shipped with Relay`:e.path})]})]}),e.description&&(0,N.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e.description}),e.steps&&(0,N.jsx)(`ol`,{"aria-label":`Steps`,className:`flex flex-wrap gap-x-4 gap-y-1 text-xs`,children:e.steps.map(e=>(0,N.jsxs)(`li`,{className:`flex items-center gap-1.5`,children:[(0,N.jsx)(`span`,{className:`font-medium`,children:e.name}),(0,N.jsx)(`span`,{className:`text-muted-foreground`,children:[`script`,`workflow`].includes(e.role)?e.role:`role ${e.role}`}),![`script`,`workflow`].includes(e.role)&&(0,N.jsx)(U,{source:a.get(e.role)?.source})]},e.name))}),e.error&&(0,N.jsxs)(`p`,{className:`text-xs text-destructive`,children:[`A run would not start: `,e.error]}),(0,N.jsxs)(`footer`,{className:`flex flex-wrap items-center gap-2 border-t border-border/60 pt-2`,children:[(0,N.jsx)(C,{size:`sm`,variant:`outline`,onClick:r,children:`View`}),e.source===`bundled`&&(0,N.jsx)(C,{size:`sm`,variant:`outline`,disabled:!n,title:n?void 0:`Pick a project to override it in`,onClick:i,children:`Override`})]})]})}function ae({projectName:e}){let t=i(e=>e.workflowCatalog),n=i(e=>e.workflowCatalogLoading),r=i(e=>e.workflowCatalogError),a=i(e=>e.workflowProjectId),[o,s]=(0,L.useState)(null),c=t?.project,l=o&&t?.workflows.find(e=>e.name===o.name),u=!!(a&&c&&!c.error);return(0,N.jsxs)(`div`,{className:`space-y-3`,children:[(0,N.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:a?(0,N.jsxs)(N.Fragment,{children:[`The workflows relay_workflow_start can run in `,e??`this project`,`: Relay's bundled ones and the repo's own `,(0,N.jsx)(`span`,{className:`font-mono`,children:`.agent-relay/workflows/*.yaml`}),` on its default branch. A repo file of the same name overrides the bundled one, and so does a repo role file.`]}):`The workflows Relay ships. Pick a project to see its own workflows and which bundled ones it overrides.`}),r&&(0,N.jsxs)(`div`,{className:`rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive`,children:[`Could not load the catalog: `,r]}),c?.error&&(0,N.jsxs)(`div`,{"data-testid":`catalog-project-error`,className:`rounded-md border border-tone-warning/40 bg-tone-warning/10 px-3 py-2 text-sm`,children:[`Could not read the project's workflow files: `,c.error,`. Only Relay's bundled workflows are shown.`]}),c?.sha&&(0,N.jsxs)(`p`,{className:`flex flex-wrap items-center gap-1 text-xs text-muted-foreground`,children:[(0,N.jsx)(b,{className:`h-3.5 w-3.5`,"aria-hidden":!0}),`Read at `,(0,N.jsxs)(`span`,{className:`font-mono`,children:[c.ref,` `,c.sha.slice(0,7)]}),c.host&&(0,N.jsxs)(N.Fragment,{children:[` on `,c.host]}),c.fetchError&&(0,N.jsxs)(`span`,{className:`text-tone-warning-fg`,children:[` as last fetched: refreshing failed (`,c.fetchError,`)`]})]}),!t&&n&&(0,N.jsx)(`div`,{className:`py-8 text-center text-sm text-muted-foreground`,children:`Loading the catalog…`}),t?.workflows.map(e=>(0,N.jsx)(J,{entry:e,roles:t.roles,canOverride:u,onView:()=>s({kind:`view`,name:e.name}),onOverride:()=>s({kind:`override`,name:e.name})},e.name)),l&&o.kind===`view`&&(0,N.jsx)(K,{entry:l,roles:W(l,t?.roles??[]),onClose:()=>s(null)}),l&&o.kind===`override`&&a&&(0,N.jsx)(q,{entry:l,roles:W(l,t?.roles??[]),project:{id:a,name:e??a},onClose:()=>s(null)},l.name)]})}var oe=new Set([`fail`,`failed`,`blocked`,`exited`,`escalated`,`cancelled`,`CI fail`]),Y=e=>e===void 0?`—`:D(e),X=(e,t)=>e?`median of ${e.count}; mean ${D(e.avgMs)}, longest ${D(e.maxMs)}`:t;function se({duration:e}){return(0,N.jsxs)(N.Fragment,{children:[(0,N.jsx)(`td`,{className:`whitespace-nowrap px-1.5 py-1 text-right tabular-nums`,children:Y(e?.p50Ms)}),(0,N.jsx)(`td`,{className:`whitespace-nowrap px-1.5 py-1 text-right tabular-nums text-muted-foreground`,children:Y(e?.avgMs)}),(0,N.jsx)(`td`,{className:`whitespace-nowrap py-1 pl-1.5 text-right tabular-nums text-muted-foreground`,children:Y(e?.maxMs)})]})}function ce({outcomes:e}){return(0,N.jsx)(`span`,{className:`flex flex-wrap gap-1`,children:Object.entries(e).sort((e,t)=>t[1]-e[1]).map(([e,n])=>(0,N.jsxs)(`span`,{className:t(`rounded px-1.5 text-[11px] tabular-nums`,oe.has(e)?`bg-destructive/10 text-destructive`:`bg-muted text-muted-foreground`),children:[e,` `,n]},e))})}function Z({stats:e}){let t=e.done+e.failed,n=Object.entries(e.failedAt).sort((e,t)=>t[1]-e[1]),r=e.steps.find(e=>e.step===te)?.duration;return(0,N.jsxs)(`article`,{"data-testid":`workflow-stats-${e.workflow}`,"aria-label":`${e.workflow} statistics`,className:`wf-run min-w-0 space-y-3 rounded-lg p-3`,children:[(0,N.jsxs)(`header`,{className:`flex flex-wrap items-baseline gap-x-3 gap-y-1`,children:[(0,N.jsxs)(`h3`,{className:`flex min-w-0 max-w-full items-center gap-1.5 text-sm font-semibold`,children:[(0,N.jsx)(x,{workflow:e.workflow,className:`h-3.5 w-3.5 shrink-0`}),(0,N.jsx)(O,{text:e.workflow})]}),(0,N.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[e.runs,` `,e.runs===1?`run`:`runs`,e.running?`, ${e.running} running`:``]})]}),(0,N.jsxs)(`div`,{className:`grid grid-cols-6 gap-2`,children:[(0,N.jsx)(M,{className:`col-span-2`,label:`Landed`,value:String(e.done),hint:t?`${E(e.done/t)} of finished runs`:void 0}),(0,N.jsx)(M,{className:`col-span-2`,label:`Failed`,value:String(e.failed),hint:`${e.escalated} escalated, ${e.cancelled} cancelled`}),(0,N.jsx)(M,{className:`col-span-2`,label:`Fix rounds`,value:String(e.fixRounds),hint:`Most rounds in one run: ${e.maxRound}`}),(0,N.jsx)(M,{className:`col-span-3`,label:`Time to merge`,value:Y(e.timeToMerge?.p50Ms),hint:X(e.timeToMerge,`No run merged in this window`)}),(0,N.jsx)(M,{className:`col-span-3`,label:`CI after merge`,value:Y(r?.p50Ms),hint:X(r,`No run waited for CI on main in this window`)})]}),e.steps.length>0&&(0,N.jsx)(`div`,{className:`overflow-x-auto`,children:(0,N.jsxs)(`table`,{className:`w-full text-sm`,"aria-label":`${e.workflow} steps`,children:[(0,N.jsx)(`thead`,{children:(0,N.jsxs)(`tr`,{className:`whitespace-nowrap text-[11px] text-muted-foreground`,children:[(0,N.jsx)(`th`,{className:`text-left font-normal`,children:`Step`}),(0,N.jsx)(`th`,{className:`px-1.5 text-left font-normal`,children:`Outcomes`}),(0,N.jsx)(`th`,{className:`px-1.5 text-right font-normal`,title:`Median time from the step's start to its result`,children:`p50`}),(0,N.jsx)(`th`,{className:`px-1.5 text-right font-normal`,children:`Mean`}),(0,N.jsx)(`th`,{className:`pl-1.5 text-right font-normal`,children:`Longest`})]})}),(0,N.jsx)(`tbody`,{children:e.steps.map(e=>(0,N.jsxs)(`tr`,{"data-testid":`workflow-step-stats-${e.step}`,className:`border-t border-border/60 first:border-t-0`,children:[(0,N.jsx)(`th`,{scope:`row`,className:`whitespace-nowrap py-1 pr-2 text-left font-medium`,children:e.step}),(0,N.jsx)(`td`,{className:`px-1.5 py-1`,children:(0,N.jsx)(ce,{outcomes:e.outcomes})}),(0,N.jsx)(se,{duration:e.duration})]},e.step))})]})}),n.length>0&&(0,N.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Failed runs stopped at `,n.map(([e,t])=>`${e} (${t})`).join(`, `),`.`]})]})}function le({failures:e,total:t,now:n,projectTitles:r}){return e.length?(0,N.jsxs)(N.Fragment,{children:[(0,N.jsx)(`ul`,{"aria-label":`Failed runs`,className:`divide-y divide-border rounded-lg border border-border bg-card`,children:e.map(e=>(0,N.jsxs)(`li`,{"data-testid":`workflow-failure-${e.runId}`,className:`wf-ledger flex flex-wrap items-center gap-x-3 gap-y-1 px-3 py-2 text-sm`,children:[(0,N.jsx)(`span`,{className:`ship-lamp h-2 w-2 shrink-0 rounded-full`,"data-status":e.status===`escalated`?`failing`:`unknown`,"aria-hidden":!0}),(0,N.jsx)(O,{text:e.workflow,className:`font-medium sm:w-28 sm:shrink-0`}),(0,N.jsx)(`div`,{className:`order-last w-full min-w-0 pl-5 sm:order-none sm:w-auto sm:flex-1 sm:pl-0`,children:(0,N.jsx)(A,{taskId:e.taskId,title:e.taskTitle})}),(0,N.jsxs)(`span`,{className:`ml-auto shrink-0 font-medium sm:ml-0`,children:[e.status===`escalated`?`Escalated`:`Cancelled`,` at `,e.step]}),(0,N.jsxs)(`span`,{className:`shrink-0 text-xs text-muted-foreground`,children:[`round `,e.round]}),(0,N.jsxs)(`span`,{className:`shrink-0 text-xs text-muted-foreground`,title:new Date(e.at).toLocaleString(),children:[a(n,e.at),` ago`]}),e.projectId&&r.get(e.projectId)&&(0,N.jsx)(`span`,{className:`shrink-0 text-xs text-muted-foreground`,children:r.get(e.projectId)}),e.reason&&(0,N.jsx)(O,{text:e.reason,className:`order-last w-full pl-5 text-xs text-muted-foreground`})]},e.runId))}),t>e.length&&(0,N.jsxs)(`p`,{className:`text-[11px] text-muted-foreground`,children:[`Showing the newest `,e.length,` of `,t,` failed runs.`]})]}):(0,N.jsx)(`p`,{className:`rounded-md border border-dashed border-border px-3 py-4 text-center text-sm text-muted-foreground`,children:`No workflow run failed in this window.`})}var Q=e=>E(e.share??null);function $({label:e,rows:t}){return(0,N.jsx)(`div`,{className:`min-w-0 overflow-x-auto`,children:(0,N.jsxs)(`table`,{className:`w-full text-sm`,"aria-label":`Adoption by ${e}`,children:[(0,N.jsx)(`thead`,{children:(0,N.jsxs)(`tr`,{className:`whitespace-nowrap text-[11px] text-muted-foreground`,children:[(0,N.jsx)(`th`,{className:`text-left font-normal`,children:e===`project`?`Project`:`Coordinator`}),(0,N.jsx)(`th`,{className:`px-1.5 text-right font-normal`,children:`Landed`}),(0,N.jsx)(`th`,{className:`px-1.5 text-right font-normal`,children:`Workflow`}),(0,N.jsx)(`th`,{className:`pl-1.5 text-left font-normal`,children:`Share`})]})}),(0,N.jsx)(`tbody`,{children:t.map(t=>(0,N.jsxs)(`tr`,{"data-testid":`workflow-adoption-${e}-${t.key||`none`}`,className:`border-t border-border/60 first:border-t-0`,children:[(0,N.jsx)(`th`,{scope:`row`,className:`max-w-0 py-1 pr-2 text-left font-medium`,title:t.title,children:(0,N.jsx)(O,{text:t.name})}),(0,N.jsx)(`td`,{className:`px-1.5 py-1 text-right tabular-nums`,children:t.landed}),(0,N.jsx)(`td`,{className:`px-1.5 py-1 text-right tabular-nums`,children:t.viaWorkflow}),(0,N.jsx)(`td`,{className:`w-28 py-1 pl-1.5`,children:(0,N.jsxs)(`span`,{className:`flex items-center gap-1.5`,children:[(0,N.jsx)(`span`,{className:`h-1.5 flex-1 overflow-hidden rounded-full bg-muted`,"aria-hidden":!0,children:(0,N.jsx)(`span`,{className:`block h-full rounded-full bg-primary`,style:{width:`${Math.round((t.share??0)*100)}%`}})}),(0,N.jsx)(`span`,{className:`w-9 text-right text-xs tabular-nums`,children:Q(t)})]})})]},t.key))})]})})}function ue({adoption:e,projectTitles:t}){let n=e.byProject.map(e=>({...e,key:e.projectId??``,name:e.projectId&&t.get(e.projectId)||e.repo||e.projectId||`No project`})),r=e.byCoordinator.map(e=>({...e,key:e.coordinator??``,name:e.label||e.coordinator||`Unattributed`,title:e.coordinator}));return(0,N.jsxs)(`section`,{"aria-labelledby":`wf-adoption`,"data-testid":`workflow-adoption`,className:`space-y-2`,children:[(0,N.jsx)(`h3`,{id:`wf-adoption`,className:`text-sm font-semibold`,children:`Adoption`}),(0,N.jsxs)(`div`,{className:`grid grid-cols-3 gap-2`,children:[(0,N.jsx)(M,{label:`Through a workflow`,value:Q(e),hint:`${e.viaWorkflow} of ${e.landed} landed Tasks that land code`}),(0,N.jsx)(M,{label:`Workflow lands`,value:String(e.viaWorkflow)}),(0,N.jsx)(M,{label:`By hand`,value:String(e.byHand)})]}),e.landed===0?(0,N.jsx)(`p`,{className:`rounded-md border border-dashed border-border px-3 py-4 text-center text-sm text-muted-foreground`,children:`No Task that lands code landed in this window.`}):(0,N.jsxs)(`div`,{className:`grid gap-3 lg:grid-cols-2`,children:[(0,N.jsx)($,{label:`project`,rows:n}),(0,N.jsx)($,{label:`coordinator`,rows:r})]}),e.truncated&&(0,N.jsx)(`p`,{className:`text-[11px] text-muted-foreground`,children:`More lands matched than one read takes; the share covers the newest ones.`}),(0,N.jsxs)(`p`,{className:`text-[11px] text-muted-foreground`,children:[`Tasks of type `,s.join(`, `),` that landed in this window, once each. A land counts as a workflow land when a workflow run on its Task started before it.`]})]})}function de({report:e,projectTitles:t}){let{totals:n}=e,r=Date.now();return(0,N.jsxs)(`div`,{className:`space-y-4`,children:[(0,N.jsxs)(`div`,{"data-testid":`workflow-stats-totals`,className:`grid grid-cols-2 gap-2 sm:grid-cols-5`,children:[(0,N.jsx)(M,{label:`Runs`,value:String(n.runs)}),(0,N.jsx)(M,{label:`Running`,value:String(n.running)}),(0,N.jsx)(M,{label:`Landed`,value:String(n.done)}),(0,N.jsx)(M,{label:`Failed`,value:String(n.failed),hint:`${n.escalated} escalated, ${n.cancelled} cancelled`}),(0,N.jsx)(M,{label:`Fix rounds`,value:String(n.fixRounds),hint:`Loops back to an earlier step, such as a NO-GO sent back to the builder`})]}),e.truncated&&(0,N.jsx)(`div`,{role:`status`,className:`rounded-md border border-tone-warning/40 bg-tone-warning/10 px-3 py-2 text-sm`,children:`More runs matched than one read takes; the figures cover the newest ones.`}),e.adoption&&(0,N.jsx)(ue,{adoption:e.adoption,projectTitles:t}),e.workflows.length===0?(0,N.jsx)(`p`,{className:`rounded-md border border-dashed border-border px-3 py-8 text-center text-sm text-muted-foreground`,children:`No workflow ran in this window.`}):(0,N.jsx)(`div`,{className:`grid gap-3 lg:grid-cols-2`,children:e.workflows.map(e=>(0,N.jsx)(Z,{stats:e},e.workflow))}),(0,N.jsxs)(`section`,{"aria-labelledby":`wf-failures`,className:`space-y-2`,children:[(0,N.jsxs)(`h3`,{id:`wf-failures`,className:`flex items-baseline gap-2 text-sm font-semibold`,children:[`Failed runs `,(0,N.jsx)(`span`,{className:`font-mono text-xs tabular-nums text-muted-foreground`,children:n.failed})]}),(0,N.jsx)(le,{failures:e.failures,total:n.failed,now:r,projectTitles:t})]}),(0,N.jsx)(`p`,{className:`text-[11px] text-muted-foreground`,children:`Running runs, and runs that finished in this window. Step times run from the step's start to its result; land runs from the last step's result to the merge. Time to merge runs from the run's start to the merge; CI after merge is the wait for CI on main that follows it. Runs routed before step times were recorded count in outcomes but show no step time.`})]})}function fe({projectTitles:e}){let t=i(e=>e.workflowStats),n=i(e=>e.workflowLoading),r=i(e=>e.workflowError);return(0,N.jsxs)(`div`,{className:`space-y-3`,children:[(0,N.jsx)(ne,{keys:o,active:i(e=>e.workflowStatsWindow),onChange:i(e=>e.setWorkflowStatsWindow)}),r&&(0,N.jsxs)(`div`,{className:`rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive`,children:[`Could not load the statistics: `,r]}),!t&&n&&(0,N.jsx)(`div`,{className:`py-8 text-center text-sm text-muted-foreground`,children:`Loading the statistics…`}),t&&(0,N.jsx)(de,{report:t,projectTitles:e})]})}function pe(){let e=i(e=>e.workflowRuns),t=i(e=>e.workflowFocusedRun),n=i(e=>e.workflowRecent),r=i(e=>e.workflowProjects),a=i(e=>e.workflowProjectId),o=i(e=>e.setWorkflowProject),s=i(e=>e.workflowLoading),c=i(e=>e.workflowError),l=i(e=>e.agentsById),u=i(e=>e.workflowTab),d=i(e=>e.setWorkflowTab),f=Date.now(),p=new Map(r.map(e=>[e.id,e.title||e.slug])),m=!a,h=m?p:new Map;return(0,N.jsxs)(`div`,{className:`space-y-4`,children:[(0,N.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,N.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,N.jsx)(S,{className:`h-5 w-5 text-muted-foreground`}),(0,N.jsx)(`h2`,{className:`text-lg font-semibold`,children:`Workflows`})]}),(0,N.jsx)(v,{value:u,onValueChange:e=>d(e),children:(0,N.jsxs)(_,{children:[(0,N.jsx)(g,{value:`runs`,className:`px-3`,children:`Live`}),(0,N.jsx)(g,{value:`stats`,className:`px-3`,children:`Statistics`}),(0,N.jsx)(g,{value:`definitions`,className:`px-3`,children:`Definitions`}),(0,N.jsx)(g,{value:`catalog`,className:`px-3`,children:`Catalog`})]})}),(0,N.jsxs)(`select`,{"aria-label":`Project`,className:`h-8 max-w-full min-w-0 rounded-md border border-border bg-background px-2 text-sm`,value:a,onChange:e=>o(e.target.value),children:[(0,N.jsx)(`option`,{value:``,children:`All projects`}),r.map(e=>(0,N.jsx)(`option`,{value:e.id,children:e.title||e.slug},e.id))]})]}),u===`stats`&&(0,N.jsx)(fe,{projectTitles:h}),u===`definitions`&&(0,N.jsx)(ie,{projectTitles:h}),u===`catalog`&&(0,N.jsx)(ae,{projectName:a?p.get(a):void 0}),u===`runs`&&t&&(0,N.jsx)(k,{run:t,agentsById:l,now:f}),u===`runs`&&c&&(0,N.jsxs)(`div`,{className:`rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive`,children:[`Could not load workflow runs: `,c]}),u===`runs`&&!e&&s&&(0,N.jsx)(`div`,{className:`py-8 text-center text-sm text-muted-foreground`,children:`Loading workflow runs…`}),e&&(0,N.jsxs)(`section`,{"aria-labelledby":`wf-running`,className:`space-y-2`,children:[(0,N.jsxs)(`h3`,{id:`wf-running`,className:`flex items-baseline gap-2 text-sm font-semibold`,children:[`Running `,(0,N.jsx)(`span`,{"data-testid":`workflow-running-count`,className:`font-mono text-xs tabular-nums text-muted-foreground`,children:e.length})]}),e.length===0?(0,N.jsx)(`p`,{className:`rounded-md border border-dashed border-border px-3 py-8 text-center text-sm text-muted-foreground`,children:`No workflow is running. A coordinator starts one with relay_workflow_start.`}):e.filter(e=>e.runId!==t?.runId).map(e=>(0,N.jsx)(k,{run:e,agentsById:l,now:f,project:m&&e.projectId?p.get(e.projectId):void 0},e.runId))]}),n&&(0,N.jsxs)(`section`,{"aria-labelledby":`wf-recent`,className:`space-y-2`,children:[(0,N.jsx)(`h3`,{id:`wf-recent`,className:`text-sm font-semibold`,children:`Recently finished`}),(0,N.jsx)(j,{runs:n,now:f,projectTitles:h})]})]})}export{pe as WorkflowsView};
6
- //# sourceMappingURL=workflows-o5YyMFW7.js.map
6
+ //# sourceMappingURL=workflows-DJilvmRM.js.map
@@ -1,3 +1,3 @@
1
- import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{p as t,u as n}from"./dist-DeW2Y1R5.js";import{t as r,wt as i}from"./store-DKPDIZBe.js";import{N as a}from"./provider-display-BEeLXC_D.js";import{et as o}from"./display-CDeH4I8T.js";import{t as s}from"./api-CIIVBtAV.js";import{i as c,n as l,r as u,t as d}from"./package-open-ckPgcjpv.js";import{t as f}from"./check-B3M9Ug1P.js";import{t as p}from"./chevron-down-BoG3JCZn.js";import{t as m}from"./chevron-right-iljytE0x.js";import{t as h}from"./clock-BWPPBh1_.js";import{t as g}from"./eye-BAP6fHrX.js";import{t as _}from"./file-pen-Crunre5f.js";import{t as v}from"./flag-CnEG9PH-.js";import{t as y}from"./folder-open-CBUCMSlu.js";import{t as b}from"./git-branch-yxhV0m8E.js";import{t as x}from"./git-commit-horizontal-DS1pJ_SS.js";import{t as S}from"./git-merge-C7eIG425.js";import{t as ee}from"./pause-DttnHD4c.js";import{t as te}from"./play-BbT8m7A0.js";import{t as C}from"./refresh-cw-CfpvQcUn.js";import{t as w}from"./trash-2-FbcSq927.js";import{t as T}from"./triangle-alert-BBNhfgMi.js";import{t as E}from"./x-Bge17hWJ.js";import{t as D}from"./button-Do6Z3vvn.js";import{t as O}from"./badge-DqJRtj_p.js";import{t as k}from"./copy-button-CjOj4HEf.js";import{t as A}from"./task-chip-CYj0mpoL.js";import{t as j}from"./agent-name-CcY3Aijy.js";import{o as M,r as N,s as P,t as F}from"./card-C4QJ4hCW.js";var I=[`cleaned`,`merged`,`landed`,`abandoned`],ne=new Set([`active`,`ready`,`conflict`,`review_requested`,`merge_planned`,`gate_running`,`gate_failed`,`merging`]),L=new Set([`active`,`ready`,`review_requested`,`merge_planned`,`gate_failed`,`conflict`]),R={active:`bg-tone-info/10 text-tone-info-fg border-tone-info/20`,ready:`bg-tone-success/10 text-tone-success-fg border-tone-success/20`,conflict:`bg-tone-danger/10 text-tone-danger-fg border-tone-danger/20`,review_requested:`bg-tone-yellow/10 text-tone-yellow-fg border-tone-yellow/20`,merge_planned:`bg-tone-indigo/10 text-tone-indigo-fg border-tone-indigo/20`,gate_running:`bg-tone-sky/10 text-tone-sky-fg border-tone-sky/20`,gate_failed:`bg-tone-danger/10 text-tone-danger-fg border-tone-danger/20`,merging:`bg-tone-indigo/10 text-tone-indigo-fg border-tone-indigo/20`,landed:`bg-tone-violet/10 text-tone-violet-fg border-tone-violet/20`,merged:`bg-tone-violet/10 text-tone-violet-fg border-tone-violet/20`,abandoned:`bg-tone-neutral/10 text-tone-neutral-fg border-tone-neutral/20`,cleanup_requested:`bg-tone-orange/10 text-tone-orange-fg border-tone-orange/20`,cleaned:`bg-tone-neutral/10 text-tone-neutral-fg border-tone-neutral/20`,stranded:`bg-tone-warning/10 text-tone-warning-fg border-tone-warning/20`},z={active:`active`,ready:`ready`,conflict:`conflict`,review_requested:`review`,merge_planned:`queued`,gate_running:`gate running`,gate_failed:`gate failed`,merging:`merging`,landed:`landed`,merged:`merged`,abandoned:`abandoned`,cleanup_requested:`cleanup`,cleaned:`cleaned`,stranded:`stranded`},B={conflict:0,ready:1,review_requested:2,merge_planned:3,gate_running:4,gate_failed:5,merging:6,active:7,cleanup_requested:8,landed:9,merged:10,abandoned:11,cleaned:12,stranded:13},V=n();function H({workspace:e,expanded:t,onToggleDetails:n}){let i=r(e=>e.workspaceAction),a=r(e=>e.purgeWorkspace),o=r(e=>e.fetchWorkspaceMergePreview),s=r(e=>e.openFilesAt),c=e.status===`cleaned`||e.status===`merged`||e.status===`landed`||e.status===`abandoned`,l=!!e.metadata.stewardCancellation&&![`completed`,`unproven-released`].includes(e.metadata.stewardCancellation.status),u=l||c||e.status===`cleanup_requested`,d=e.worktreePath||e.sourceCwd||e.repoRoot,h=r(t=>t.workspaceGitState[e.id]),_=!!h&&h.available!==!1&&h.landed===!0,b=!!e.metadata.mergeHold,x=e.mode===`isolated`&&!!e.worktreePath&&L.has(e.status)&&!_&&!l&&!b;async function C(){await o(e.id),await i(e.id,`merge`)}return(0,V.jsxs)(`div`,{className:`flex flex-wrap justify-end gap-1.5`,children:[(0,V.jsx)(D,{size:`icon-sm`,variant:`ghost`,title:t?`Hide details`:`Show diff & timeline`,onClick:n,children:t?(0,V.jsx)(p,{className:`h-3.5 w-3.5`}):(0,V.jsx)(m,{className:`h-3.5 w-3.5`})}),(0,V.jsx)(D,{size:`icon-sm`,variant:`ghost`,title:`Open workspace`,disabled:!d||e.status===`cleaned`,onClick:()=>void s({path:d}),children:(0,V.jsx)(y,{className:`h-3.5 w-3.5`})}),(0,V.jsx)(k,{value:d,label:`Copy path`,copiedLabel:`Copied path`,size:`icon-sm`,variant:`ghost`,disabled:!d}),e.mode===`isolated`&&!c&&(0,V.jsxs)(D,{size:`sm`,variant:`outline`,title:b?`Resume workspace merge`:`Hold workspace merge (does not cancel an admitted land)`,onClick:()=>void i(e.id,b?`resume-merge`:`hold-merge`),children:[b?(0,V.jsx)(te,{className:`mr-1 h-3.5 w-3.5`}):(0,V.jsx)(ee,{className:`mr-1 h-3.5 w-3.5`}),b?`Merge held — resume`:`Hold merge`]}),(0,V.jsx)(D,{size:`icon-sm`,variant:`outline`,title:`Mark ready`,disabled:u||e.status===`ready`,onClick:()=>void i(e.id,`ready`),children:(0,V.jsx)(f,{className:`h-3.5 w-3.5`})}),(0,V.jsx)(D,{size:`icon-sm`,variant:`outline`,title:`Request review`,disabled:u||e.status===`review_requested`,onClick:()=>void i(e.id,`request-review`),children:(0,V.jsx)(g,{className:`h-3.5 w-3.5`})}),(0,V.jsx)(D,{size:`icon-sm`,variant:`outline`,title:`Mark merge planned`,disabled:u||b||e.status===`merge_planned`,onClick:()=>void i(e.id,`merge-plan`),children:(0,V.jsx)(v,{className:`h-3.5 w-3.5`})}),(0,V.jsx)(D,{size:`icon-sm`,variant:`default`,title:_?`Already merged into base — nothing to land`:`Merge & land work`,disabled:!x,onClick:()=>void C(),children:(0,V.jsx)(S,{className:`h-3.5 w-3.5`})}),(0,V.jsx)(D,{size:`icon-sm`,variant:`outline`,title:`Request cleanup (removes the worktree on the host)`,disabled:u,onClick:()=>void i(e.id,`cleanup`),children:(0,V.jsx)(w,{className:`h-3.5 w-3.5`})}),c&&(0,V.jsx)(D,{size:`icon-sm`,variant:`ghost`,title:`Purge record (clears the row, does not touch disk)`,onClick:()=>void a(e.id),children:(0,V.jsx)(E,{className:`h-3.5 w-3.5`})})]})}var U=e(t(),1),W=new Set([`active`,`ready`,`conflict`,`review_requested`,`merge_planned`,`gate_running`,`gate_failed`,`merging`,`cleanup_requested`]),G=new Set(I),K=`__all__`,q=`__unassigned__`;function J(e,t){let n=new Map;for(let t of e){let e=t.repoRoot||t.sourceCwd||`unknown repo`;n.set(e,[...n.get(e)||[],t])}return[...n.entries()].map(([e,n])=>({repoRoot:e,workspaces:n.sort(t)})).sort((e,t)=>e.repoRoot.localeCompare(t.repoRoot))}function Y(e,t){let n=new Map;for(let t of e){let e=t.projectSlug||t.repoRoot||t.sourceCwd||`unassigned`;n.set(e,[...n.get(e)||[],t])}return[...n.entries()].map(([e,n])=>{let r=n[0],i=!r.projectId;return{key:e,title:i?r.repoRoot||r.sourceCwd||`unknown repo`:r.projectTitle||r.projectSlug||r.repoRoot,...r.projectId?{projectId:r.projectId}:{},...r.projectSlug?{projectSlug:r.projectSlug}:{},unassigned:i,repoGroups:J(n,t)}}).sort((e,t)=>{let n=e.repoGroups.some(e=>e.workspaces.some(e=>W.has(e.status)));return n===t.repoGroups.some(e=>e.workspaces.some(e=>W.has(e.status)))?e.title.localeCompare(t.title):n?-1:1})}function X(e,t,n){let r=t===`all`?e:t===`cleaned`?e.filter(e=>G.has(e.status)):e.filter(e=>!G.has(e.status));return n===`__all__`?r:n===`__unassigned__`?r.filter(e=>!e.projectId):r.filter(e=>e.projectId===n)}function Z({group:e,renderWorkspaceRow:t}){let n=e.repoGroups.flatMap(e=>e.workspaces),r=n.filter(e=>W.has(e.status)).length,i=n.filter(e=>e.status===`ready`||e.status===`review_requested`||e.status===`merge_planned`||e.status===`gate_running`||e.status===`gate_failed`||e.status===`merging`).length,a=n.filter(e=>e.status===`conflict`).length,o=e.repoGroups.length>1;return(0,V.jsxs)(F,{children:[(0,V.jsx)(M,{className:`px-4 py-3`,children:(0,V.jsx)(`div`,{className:`flex min-w-0 items-start gap-3`,children:(0,V.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,V.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,V.jsx)(P,{className:`truncate text-sm font-medium`,title:e.title,children:e.title}),e.unassigned&&(0,V.jsx)(O,{variant:`outline`,className:`text-[10px]`,children:`Unassigned`})]}),(0,V.jsxs)(`div`,{className:`mt-1 flex flex-wrap gap-1.5`,children:[(0,V.jsxs)(O,{variant:`outline`,className:`text-[10px]`,children:[n.length,` total`]}),(0,V.jsxs)(O,{variant:`outline`,className:`text-[10px]`,children:[r,` live`]}),i>0&&(0,V.jsxs)(O,{variant:`outline`,className:`border-tone-success/20 text-tone-success-fg text-[10px]`,children:[i,` merge signal`]}),a>0&&(0,V.jsxs)(O,{variant:`outline`,className:`border-tone-danger/20 text-tone-danger-fg text-[10px]`,children:[a,` conflict`]})]})]})})}),(0,V.jsx)(N,{className:`p-0`,children:e.repoGroups.map(e=>(0,V.jsxs)(`div`,{className:`border-t border-border first:border-t-0`,children:[o&&(0,V.jsxs)(`div`,{className:`flex items-center gap-2 border-b border-dashed border-border/80 px-3 py-2`,children:[(0,V.jsx)(y,{className:`h-3.5 w-3.5 shrink-0 text-muted-foreground`}),(0,V.jsx)(`span`,{className:`truncate font-mono text-[11px] text-muted-foreground`,title:e.repoRoot,children:e.repoRoot})]}),e.workspaces.map(e=>t(e))]},e.repoRoot))})]})}function re(e){let t=e.split(`/`).filter(Boolean);return t.length<=3?e||`-`:`/${t.slice(-3).join(`/`)}`}function ie(){let e=r(e=>e.workspaceOrphans),t=r(e=>e.fetchWorkspaceOrphans),n=r(e=>e.reclaimWorkspaceOrphan);return(0,U.useEffect)(()=>{t()},[t]),e.length?(0,V.jsxs)(F,{className:`border-tone-warning/30`,children:[(0,V.jsxs)(M,{className:`px-4 py-3`,children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,V.jsx)(d,{className:`h-4 w-4 text-tone-warning-fg`}),(0,V.jsx)(P,{className:`text-sm font-medium`,children:`Orphaned worktrees`}),(0,V.jsx)(O,{variant:`outline`,className:`border-tone-warning/30 text-tone-warning-fg text-[10px]`,children:e.length}),(0,V.jsx)(D,{size:`icon-sm`,variant:`ghost`,className:`ml-auto h-6 w-6`,title:`Rescan`,onClick:()=>void t(),children:(0,V.jsx)(C,{className:`h-3.5 w-3.5`})})]}),(0,V.jsx)(`p`,{className:`mt-1 text-xs text-muted-foreground`,children:`Agent worktrees on disk with no live workspace. Reclaim removes them from the host.`})]}),(0,V.jsx)(N,{className:`p-0`,children:e.map(e=>(0,V.jsxs)(`div`,{className:`flex items-center gap-3 border-t border-border px-4 py-2 text-xs`,children:[(0,V.jsx)(y,{className:`h-3.5 w-3.5 shrink-0 text-muted-foreground`}),(0,V.jsx)(`span`,{className:`truncate font-medium`,title:e.branch,children:e.branch||`(detached)`}),(0,V.jsx)(`span`,{className:`truncate font-mono text-muted-foreground`,title:e.worktreePath,children:re(e.worktreePath)}),e.hadTerminalRow&&(0,V.jsx)(O,{variant:`outline`,className:`text-[10px]`,children:`cleanup failed`}),(0,V.jsxs)(D,{size:`sm`,variant:`outline`,className:`ml-auto h-7 text-xs`,onClick:()=>void n(e),children:[(0,V.jsx)(d,{className:`mr-1 h-3.5 w-3.5`}),`Reclaim`]})]},e.worktreePath))})]}):null}function ae(e,t,n){if(n){let t=e.find(e=>e.branch&&e.branch===n);if(t)return t}if(!t)return null;let r=e.filter(e=>e.ownerAgentId===t);return r.length===0?null:r.length===1?r[0]:null}function oe({cancellation:e}){let t=e.status===`completed`,n=e.status===`unproven-released`,r=e.proof===`unavailable`;return(0,V.jsxs)(`div`,{className:`mx-3 mb-3 rounded-md border border-tone-warning/20 px-3 py-2 text-xs`,role:`status`,children:[(0,V.jsx)(`span`,{className:`font-medium`,children:n?`Workspace released · stop unproven`:t?`Steward stopped · workspace handed back`:`Steward cancellation · hand-back pending`}),(0,V.jsx)(`div`,{className:`mt-1 text-muted-foreground`,children:e.status===`stopped`?`Steward stopped; hand-back awaits withdrawal of remaining landing activity. Recovery retries automatically.`:n||r?`Process-tree proof unavailable. Claims released; the canceled generation remains fenced.`:t?`The host confirmed the conflict job and its children stopped.`:`Shutdown is settling. Retry in 2 seconds; deadline recovery starts after 60 seconds.`})]})}function se({workspace:e}){let t=typeof e.metadata.rekeyCommandId==`string`,n=typeof e.metadata.rekeyError==`string`?e.metadata.rekeyError:void 0,r=a(e.metadata.lastStewardRekey)?e.metadata.lastStewardRekey:void 0;return!t&&!n&&!r?null:(0,V.jsx)(`div`,{className:`text-xs text-muted-foreground`,role:`status`,children:t?`Steward rebase: synchronizing owner host`:n?`Steward rebase refused: ${n}`:`Steward rebase recorded: ${String(r?.oldHeadSha).slice(0,12)} → ${String(r?.newHeadSha).slice(0,12)}`})}function Q(e,t){return(0,V.jsx)(j,{agent:e,fallback:t||`-`})}function ce(e){let t=e.split(`/`).filter(Boolean);return t.length<=3?e||`-`:`/${t.slice(-3).join(`/`)}`}function le(e){return R[e]||`bg-tone-neutral/10 text-tone-neutral-fg border-tone-neutral/20`}function ue(e,t){let n=(B[e.status]??99)-(B[t.status]??99);return n===0?Number(t.updatedAt||0)-Number(e.updatedAt||0):n}function $({workspace:e,unmerged:t}){let n=r(t=>t.workspaceMergePreview[e.id]),i=r(e=>e.fetchWorkspaceMergePreview),a=t>0&&L.has(e.status);return(0,U.useEffect)(()=>{a&&n===void 0&&i(e.id)},[a,n,e.id,i]),!a||n===void 0||n.available===!1?null:n.conflict?(0,V.jsxs)(`span`,{className:`flex items-center gap-0.5 text-tone-warning-fg`,title:`Merging into ${n.baseRef||`base`} would conflict — resolve before merging`,children:[(0,V.jsx)(T,{className:`h-3 w-3`}),`conflict`]}):n.conflict===!1?(0,V.jsxs)(`span`,{className:`flex items-center gap-0.5 text-tone-success-fg`,title:`Clean to merge via ${n.strategy===`pr`?`PR`:`rebase + fast-forward`} into ${n.baseRef||`base`}`,children:[(0,V.jsx)(f,{className:`h-3 w-3`}),n.strategy===`pr`?`PR ready`:`clean`]}):null}function de({workspace:e}){let t=i(),n=r(t=>t.workspaceGitState[e.id]),a=r(e=>e.fetchWorkspaceGitState),s=e.mode===`isolated`&&!!e.worktreePath&&ne.has(e.status);if((0,U.useEffect)(()=>{s&&n===void 0&&a(e.id)},[s,n,e.id,a]),!s)return null;let l=(0,V.jsx)(D,{size:`icon-sm`,variant:`ghost`,className:`h-5 w-5`,title:`Refresh git state`,onClick:()=>void a(e.id),children:(0,V.jsx)(C,{className:`h-3 w-3`})});if(n===void 0)return(0,V.jsx)(`div`,{className:`flex items-center gap-1 text-[11px] text-muted-foreground`,children:`Loading git state…`});if(n.available===!1)return(0,V.jsxs)(`div`,{className:`flex items-center gap-1 text-[11px] text-muted-foreground`,title:n.reason,children:[(0,V.jsx)(`span`,{children:`git state unavailable`}),l]});if(n.missing)return(0,V.jsxs)(`div`,{className:`flex items-center gap-1 text-[11px] text-muted-foreground`,children:[`worktree gone `,l]});if(n.error)return(0,V.jsxs)(`div`,{className:`flex items-center gap-1 text-[11px] text-tone-danger-fg`,title:n.error,children:[(0,V.jsx)(`span`,{children:`git error`}),l]});let d=n.ahead??0,p=n.landed===!0,m=p?0:n.unmergedAhead??d,h=n.behind??0,g=n.dirtyCount??0,v=m===0&&g===0&&!p,y=n.lastCommit;return(0,V.jsxs)(`div`,{className:`space-y-0.5`,children:[(0,V.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-2 gap-y-0.5 text-[11px]`,children:[v?(0,V.jsx)(`span`,{className:`text-muted-foreground`,children:`no unmerged work`}):(0,V.jsxs)(V.Fragment,{children:[p?(0,V.jsxs)(`span`,{className:`flex items-center gap-0.5 text-tone-success-fg`,title:`Work already landed in ${n.baseRef||`base`} via squash/cherry-pick — safe to clean up`,children:[(0,V.jsx)(f,{className:`h-3 w-3`}),`landed`]}):(0,V.jsxs)(`span`,{className:m>0?`flex items-center text-tone-success-fg`:`flex items-center text-muted-foreground`,title:d===m?`${m} commit(s) ahead of base`:`${m} unmerged commit(s) (${d} ahead of base)`,children:[(0,V.jsx)(u,{className:`h-3 w-3`}),m]}),(0,V.jsxs)(`span`,{className:h>0?`flex items-center text-tone-warning-fg`:`flex items-center text-muted-foreground`,title:`${h} commit(s) behind base`,children:[(0,V.jsx)(c,{className:`h-3 w-3`}),h]}),g>0&&(0,V.jsxs)(`span`,{className:`flex items-center text-tone-orange-fg`,title:`${g} uncommitted change(s)`,children:[(0,V.jsx)(_,{className:`h-3 w-3`}),g]}),!p&&(0,V.jsx)($,{workspace:e,unmerged:m})]}),l]}),y&&(0,V.jsxs)(`div`,{className:`flex min-w-0 items-center gap-1 text-[11px] text-muted-foreground`,title:`${y.sha.slice(0,8)} — ${y.message}`,children:[(0,V.jsx)(x,{className:`h-3 w-3 shrink-0`}),(0,V.jsx)(`span`,{className:`truncate`,children:y.message||y.sha.slice(0,8)}),y.at?(0,V.jsxs)(`span`,{className:`shrink-0 opacity-70`,children:[`· `,o(t,y.at)]}):null]})]})}function fe({workspace:e}){let t=i(),n=typeof e.metadata?.mergedAt==`number`?e.metadata.mergedAt:void 0,r=[{label:`created`,at:e.createdAt},{label:`ready`,at:e.readyAt},{label:`merged`,at:n},{label:`cleaned`,at:e.cleanedAt}].filter(e=>typeof e.at==`number`&&e.at>0);return(0,V.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px] text-muted-foreground`,children:[(0,V.jsxs)(`span`,{className:`flex items-center gap-1 font-medium text-foreground`,children:[(0,V.jsx)(h,{className:`h-3 w-3`}),`Timeline`]}),r.map((e,n)=>(0,V.jsxs)(`span`,{className:`flex items-center gap-1`,children:[n>0&&(0,V.jsx)(`span`,{className:`opacity-40`,children:`→`}),(0,V.jsx)(`span`,{className:`text-foreground`,children:e.label}),(0,V.jsx)(`span`,{title:new Date(e.at).toLocaleString(),children:o(t,e.at)})]},e.label))]})}function pe(e){return e.startsWith(`+`)&&!e.startsWith(`+++`)?`text-tone-success-fg`:e.startsWith(`-`)&&!e.startsWith(`---`)?`text-tone-danger-fg`:e.startsWith(`@@`)?`text-tone-cyan-fg`:e.startsWith(`diff `)||e.startsWith(`index `)||e.startsWith(`+++`)||e.startsWith(`---`)?`text-muted-foreground`:``}function me({workspace:e}){let t=r(t=>t.workspaceDiff[e.id]),n=r(e=>e.fetchWorkspaceDiff),i=e.mode===`isolated`&&!!e.worktreePath;if((0,U.useEffect)(()=>{i&&t===void 0&&n(e.id)},[i,t,e.id,n]),!i)return null;if(t===void 0)return(0,V.jsx)(`div`,{className:`text-[11px] text-muted-foreground`,children:`Loading diff…`});if(t.available===!1)return(0,V.jsxs)(`div`,{className:`text-[11px] text-muted-foreground`,children:[`Diff unavailable`,t.reason?`: ${t.reason}`:``]});if(t.missing)return(0,V.jsx)(`div`,{className:`text-[11px] text-muted-foreground`,children:`Worktree no longer on disk`});if(t.error)return(0,V.jsxs)(`div`,{className:`text-[11px] text-tone-danger-fg`,children:[`Diff error: `,t.error]});if(!t.files.length)return(0,V.jsxs)(`div`,{className:`text-[11px] text-muted-foreground`,children:[`No committed changes against `,t.baseRef||`base`]});let a=(0,V.jsx)(D,{size:`icon-sm`,variant:`ghost`,className:`h-5 w-5`,title:`Refresh diff`,onClick:()=>void n(e.id),children:(0,V.jsx)(C,{className:`h-3 w-3`})});return(0,V.jsxs)(`div`,{className:`space-y-1`,children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-2 text-[11px] font-medium`,children:[(0,V.jsx)(l,{className:`h-3 w-3`}),(0,V.jsxs)(`span`,{children:[t.files.length,` file`,t.files.length===1?``:`s`,` vs `,t.baseRef||`base`]}),a]}),(0,V.jsx)(`ul`,{className:`space-y-0.5 text-[11px]`,children:t.files.map(e=>(0,V.jsxs)(`li`,{className:`flex items-center gap-2 font-mono`,children:[(0,V.jsx)(`span`,{className:`truncate`,title:e.path,children:e.path}),e.binary?(0,V.jsx)(`span`,{className:`shrink-0 text-muted-foreground`,children:`binary`}):(0,V.jsxs)(`span`,{className:`shrink-0`,children:[(0,V.jsxs)(`span`,{className:`text-tone-success-fg`,children:[`+`,e.additions??0]}),` `,(0,V.jsxs)(`span`,{className:`text-tone-danger-fg`,children:[`−`,e.deletions??0]})]})]},e.path))}),t.patch&&(0,V.jsxs)(`pre`,{className:`max-h-80 overflow-auto rounded border border-border bg-muted/30 p-2 text-[10.5px] leading-relaxed`,children:[t.patch.split(`
1
+ import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{p as t,u as n}from"./dist-DeW2Y1R5.js";import{t as r,wt as i}from"./store-BgDALGIX.js";import{N as a}from"./provider-display-bWwiuedV.js";import{et as o}from"./display-BemJG1f_.js";import{t as s}from"./api-CIIVBtAV.js";import{i as c,n as l,r as u,t as d}from"./package-open-ckPgcjpv.js";import{t as f}from"./check-B3M9Ug1P.js";import{t as p}from"./chevron-down-BoG3JCZn.js";import{t as m}from"./chevron-right-iljytE0x.js";import{t as h}from"./clock-BWPPBh1_.js";import{t as g}from"./eye-BAP6fHrX.js";import{t as _}from"./file-pen-Crunre5f.js";import{t as v}from"./flag-CnEG9PH-.js";import{t as y}from"./folder-open-CBUCMSlu.js";import{t as b}from"./git-branch-yxhV0m8E.js";import{t as x}from"./git-commit-horizontal-DS1pJ_SS.js";import{t as S}from"./git-merge-C7eIG425.js";import{t as ee}from"./pause-DttnHD4c.js";import{t as te}from"./play-BbT8m7A0.js";import{t as C}from"./refresh-cw-CfpvQcUn.js";import{t as w}from"./trash-2-FbcSq927.js";import{t as T}from"./triangle-alert-BBNhfgMi.js";import{t as E}from"./x-Bge17hWJ.js";import{t as D}from"./button-Do6Z3vvn.js";import{t as O}from"./badge-DqJRtj_p.js";import{t as k}from"./copy-button-CjOj4HEf.js";import{t as A}from"./task-chip-CYj0mpoL.js";import{t as j}from"./agent-name-C_7F4DFR.js";import{o as M,r as N,s as P,t as F}from"./card-C4QJ4hCW.js";var I=[`cleaned`,`merged`,`landed`,`abandoned`],ne=new Set([`active`,`ready`,`conflict`,`review_requested`,`merge_planned`,`gate_running`,`gate_failed`,`merging`]),L=new Set([`active`,`ready`,`review_requested`,`merge_planned`,`gate_failed`,`conflict`]),R={active:`bg-tone-info/10 text-tone-info-fg border-tone-info/20`,ready:`bg-tone-success/10 text-tone-success-fg border-tone-success/20`,conflict:`bg-tone-danger/10 text-tone-danger-fg border-tone-danger/20`,review_requested:`bg-tone-yellow/10 text-tone-yellow-fg border-tone-yellow/20`,merge_planned:`bg-tone-indigo/10 text-tone-indigo-fg border-tone-indigo/20`,gate_running:`bg-tone-sky/10 text-tone-sky-fg border-tone-sky/20`,gate_failed:`bg-tone-danger/10 text-tone-danger-fg border-tone-danger/20`,merging:`bg-tone-indigo/10 text-tone-indigo-fg border-tone-indigo/20`,landed:`bg-tone-violet/10 text-tone-violet-fg border-tone-violet/20`,merged:`bg-tone-violet/10 text-tone-violet-fg border-tone-violet/20`,abandoned:`bg-tone-neutral/10 text-tone-neutral-fg border-tone-neutral/20`,cleanup_requested:`bg-tone-orange/10 text-tone-orange-fg border-tone-orange/20`,cleaned:`bg-tone-neutral/10 text-tone-neutral-fg border-tone-neutral/20`,stranded:`bg-tone-warning/10 text-tone-warning-fg border-tone-warning/20`},z={active:`active`,ready:`ready`,conflict:`conflict`,review_requested:`review`,merge_planned:`queued`,gate_running:`gate running`,gate_failed:`gate failed`,merging:`merging`,landed:`landed`,merged:`merged`,abandoned:`abandoned`,cleanup_requested:`cleanup`,cleaned:`cleaned`,stranded:`stranded`},B={conflict:0,ready:1,review_requested:2,merge_planned:3,gate_running:4,gate_failed:5,merging:6,active:7,cleanup_requested:8,landed:9,merged:10,abandoned:11,cleaned:12,stranded:13},V=n();function H({workspace:e,expanded:t,onToggleDetails:n}){let i=r(e=>e.workspaceAction),a=r(e=>e.purgeWorkspace),o=r(e=>e.fetchWorkspaceMergePreview),s=r(e=>e.openFilesAt),c=e.status===`cleaned`||e.status===`merged`||e.status===`landed`||e.status===`abandoned`,l=!!e.metadata.stewardCancellation&&![`completed`,`unproven-released`].includes(e.metadata.stewardCancellation.status),u=l||c||e.status===`cleanup_requested`,d=e.worktreePath||e.sourceCwd||e.repoRoot,h=r(t=>t.workspaceGitState[e.id]),_=!!h&&h.available!==!1&&h.landed===!0,b=!!e.metadata.mergeHold,x=e.mode===`isolated`&&!!e.worktreePath&&L.has(e.status)&&!_&&!l&&!b;async function C(){await o(e.id),await i(e.id,`merge`)}return(0,V.jsxs)(`div`,{className:`flex flex-wrap justify-end gap-1.5`,children:[(0,V.jsx)(D,{size:`icon-sm`,variant:`ghost`,title:t?`Hide details`:`Show diff & timeline`,onClick:n,children:t?(0,V.jsx)(p,{className:`h-3.5 w-3.5`}):(0,V.jsx)(m,{className:`h-3.5 w-3.5`})}),(0,V.jsx)(D,{size:`icon-sm`,variant:`ghost`,title:`Open workspace`,disabled:!d||e.status===`cleaned`,onClick:()=>void s({path:d}),children:(0,V.jsx)(y,{className:`h-3.5 w-3.5`})}),(0,V.jsx)(k,{value:d,label:`Copy path`,copiedLabel:`Copied path`,size:`icon-sm`,variant:`ghost`,disabled:!d}),e.mode===`isolated`&&!c&&(0,V.jsxs)(D,{size:`sm`,variant:`outline`,title:b?`Resume workspace merge`:`Hold workspace merge (does not cancel an admitted land)`,onClick:()=>void i(e.id,b?`resume-merge`:`hold-merge`),children:[b?(0,V.jsx)(te,{className:`mr-1 h-3.5 w-3.5`}):(0,V.jsx)(ee,{className:`mr-1 h-3.5 w-3.5`}),b?`Merge held — resume`:`Hold merge`]}),(0,V.jsx)(D,{size:`icon-sm`,variant:`outline`,title:`Mark ready`,disabled:u||e.status===`ready`,onClick:()=>void i(e.id,`ready`),children:(0,V.jsx)(f,{className:`h-3.5 w-3.5`})}),(0,V.jsx)(D,{size:`icon-sm`,variant:`outline`,title:`Request review`,disabled:u||e.status===`review_requested`,onClick:()=>void i(e.id,`request-review`),children:(0,V.jsx)(g,{className:`h-3.5 w-3.5`})}),(0,V.jsx)(D,{size:`icon-sm`,variant:`outline`,title:`Mark merge planned`,disabled:u||b||e.status===`merge_planned`,onClick:()=>void i(e.id,`merge-plan`),children:(0,V.jsx)(v,{className:`h-3.5 w-3.5`})}),(0,V.jsx)(D,{size:`icon-sm`,variant:`default`,title:_?`Already merged into base — nothing to land`:`Merge & land work`,disabled:!x,onClick:()=>void C(),children:(0,V.jsx)(S,{className:`h-3.5 w-3.5`})}),(0,V.jsx)(D,{size:`icon-sm`,variant:`outline`,title:`Request cleanup (removes the worktree on the host)`,disabled:u,onClick:()=>void i(e.id,`cleanup`),children:(0,V.jsx)(w,{className:`h-3.5 w-3.5`})}),c&&(0,V.jsx)(D,{size:`icon-sm`,variant:`ghost`,title:`Purge record (clears the row, does not touch disk)`,onClick:()=>void a(e.id),children:(0,V.jsx)(E,{className:`h-3.5 w-3.5`})})]})}var U=e(t(),1),W=new Set([`active`,`ready`,`conflict`,`review_requested`,`merge_planned`,`gate_running`,`gate_failed`,`merging`,`cleanup_requested`]),G=new Set(I),K=`__all__`,q=`__unassigned__`;function J(e,t){let n=new Map;for(let t of e){let e=t.repoRoot||t.sourceCwd||`unknown repo`;n.set(e,[...n.get(e)||[],t])}return[...n.entries()].map(([e,n])=>({repoRoot:e,workspaces:n.sort(t)})).sort((e,t)=>e.repoRoot.localeCompare(t.repoRoot))}function Y(e,t){let n=new Map;for(let t of e){let e=t.projectSlug||t.repoRoot||t.sourceCwd||`unassigned`;n.set(e,[...n.get(e)||[],t])}return[...n.entries()].map(([e,n])=>{let r=n[0],i=!r.projectId;return{key:e,title:i?r.repoRoot||r.sourceCwd||`unknown repo`:r.projectTitle||r.projectSlug||r.repoRoot,...r.projectId?{projectId:r.projectId}:{},...r.projectSlug?{projectSlug:r.projectSlug}:{},unassigned:i,repoGroups:J(n,t)}}).sort((e,t)=>{let n=e.repoGroups.some(e=>e.workspaces.some(e=>W.has(e.status)));return n===t.repoGroups.some(e=>e.workspaces.some(e=>W.has(e.status)))?e.title.localeCompare(t.title):n?-1:1})}function X(e,t,n){let r=t===`all`?e:t===`cleaned`?e.filter(e=>G.has(e.status)):e.filter(e=>!G.has(e.status));return n===`__all__`?r:n===`__unassigned__`?r.filter(e=>!e.projectId):r.filter(e=>e.projectId===n)}function Z({group:e,renderWorkspaceRow:t}){let n=e.repoGroups.flatMap(e=>e.workspaces),r=n.filter(e=>W.has(e.status)).length,i=n.filter(e=>e.status===`ready`||e.status===`review_requested`||e.status===`merge_planned`||e.status===`gate_running`||e.status===`gate_failed`||e.status===`merging`).length,a=n.filter(e=>e.status===`conflict`).length,o=e.repoGroups.length>1;return(0,V.jsxs)(F,{children:[(0,V.jsx)(M,{className:`px-4 py-3`,children:(0,V.jsx)(`div`,{className:`flex min-w-0 items-start gap-3`,children:(0,V.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,V.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,V.jsx)(P,{className:`truncate text-sm font-medium`,title:e.title,children:e.title}),e.unassigned&&(0,V.jsx)(O,{variant:`outline`,className:`text-[10px]`,children:`Unassigned`})]}),(0,V.jsxs)(`div`,{className:`mt-1 flex flex-wrap gap-1.5`,children:[(0,V.jsxs)(O,{variant:`outline`,className:`text-[10px]`,children:[n.length,` total`]}),(0,V.jsxs)(O,{variant:`outline`,className:`text-[10px]`,children:[r,` live`]}),i>0&&(0,V.jsxs)(O,{variant:`outline`,className:`border-tone-success/20 text-tone-success-fg text-[10px]`,children:[i,` merge signal`]}),a>0&&(0,V.jsxs)(O,{variant:`outline`,className:`border-tone-danger/20 text-tone-danger-fg text-[10px]`,children:[a,` conflict`]})]})]})})}),(0,V.jsx)(N,{className:`p-0`,children:e.repoGroups.map(e=>(0,V.jsxs)(`div`,{className:`border-t border-border first:border-t-0`,children:[o&&(0,V.jsxs)(`div`,{className:`flex items-center gap-2 border-b border-dashed border-border/80 px-3 py-2`,children:[(0,V.jsx)(y,{className:`h-3.5 w-3.5 shrink-0 text-muted-foreground`}),(0,V.jsx)(`span`,{className:`truncate font-mono text-[11px] text-muted-foreground`,title:e.repoRoot,children:e.repoRoot})]}),e.workspaces.map(e=>t(e))]},e.repoRoot))})]})}function re(e){let t=e.split(`/`).filter(Boolean);return t.length<=3?e||`-`:`/${t.slice(-3).join(`/`)}`}function ie(){let e=r(e=>e.workspaceOrphans),t=r(e=>e.fetchWorkspaceOrphans),n=r(e=>e.reclaimWorkspaceOrphan);return(0,U.useEffect)(()=>{t()},[t]),e.length?(0,V.jsxs)(F,{className:`border-tone-warning/30`,children:[(0,V.jsxs)(M,{className:`px-4 py-3`,children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,V.jsx)(d,{className:`h-4 w-4 text-tone-warning-fg`}),(0,V.jsx)(P,{className:`text-sm font-medium`,children:`Orphaned worktrees`}),(0,V.jsx)(O,{variant:`outline`,className:`border-tone-warning/30 text-tone-warning-fg text-[10px]`,children:e.length}),(0,V.jsx)(D,{size:`icon-sm`,variant:`ghost`,className:`ml-auto h-6 w-6`,title:`Rescan`,onClick:()=>void t(),children:(0,V.jsx)(C,{className:`h-3.5 w-3.5`})})]}),(0,V.jsx)(`p`,{className:`mt-1 text-xs text-muted-foreground`,children:`Agent worktrees on disk with no live workspace. Reclaim removes them from the host.`})]}),(0,V.jsx)(N,{className:`p-0`,children:e.map(e=>(0,V.jsxs)(`div`,{className:`flex items-center gap-3 border-t border-border px-4 py-2 text-xs`,children:[(0,V.jsx)(y,{className:`h-3.5 w-3.5 shrink-0 text-muted-foreground`}),(0,V.jsx)(`span`,{className:`truncate font-medium`,title:e.branch,children:e.branch||`(detached)`}),(0,V.jsx)(`span`,{className:`truncate font-mono text-muted-foreground`,title:e.worktreePath,children:re(e.worktreePath)}),e.hadTerminalRow&&(0,V.jsx)(O,{variant:`outline`,className:`text-[10px]`,children:`cleanup failed`}),(0,V.jsxs)(D,{size:`sm`,variant:`outline`,className:`ml-auto h-7 text-xs`,onClick:()=>void n(e),children:[(0,V.jsx)(d,{className:`mr-1 h-3.5 w-3.5`}),`Reclaim`]})]},e.worktreePath))})]}):null}function ae(e,t,n){if(n){let t=e.find(e=>e.branch&&e.branch===n);if(t)return t}if(!t)return null;let r=e.filter(e=>e.ownerAgentId===t);return r.length===0?null:r.length===1?r[0]:null}function oe({cancellation:e}){let t=e.status===`completed`,n=e.status===`unproven-released`,r=e.proof===`unavailable`;return(0,V.jsxs)(`div`,{className:`mx-3 mb-3 rounded-md border border-tone-warning/20 px-3 py-2 text-xs`,role:`status`,children:[(0,V.jsx)(`span`,{className:`font-medium`,children:n?`Workspace released · stop unproven`:t?`Steward stopped · workspace handed back`:`Steward cancellation · hand-back pending`}),(0,V.jsx)(`div`,{className:`mt-1 text-muted-foreground`,children:e.status===`stopped`?`Steward stopped; hand-back awaits withdrawal of remaining landing activity. Recovery retries automatically.`:n||r?`Process-tree proof unavailable. Claims released; the canceled generation remains fenced.`:t?`The host confirmed the conflict job and its children stopped.`:`Shutdown is settling. Retry in 2 seconds; deadline recovery starts after 60 seconds.`})]})}function se({workspace:e}){let t=typeof e.metadata.rekeyCommandId==`string`,n=typeof e.metadata.rekeyError==`string`?e.metadata.rekeyError:void 0,r=a(e.metadata.lastStewardRekey)?e.metadata.lastStewardRekey:void 0;return!t&&!n&&!r?null:(0,V.jsx)(`div`,{className:`text-xs text-muted-foreground`,role:`status`,children:t?`Steward rebase: synchronizing owner host`:n?`Steward rebase refused: ${n}`:`Steward rebase recorded: ${String(r?.oldHeadSha).slice(0,12)} → ${String(r?.newHeadSha).slice(0,12)}`})}function Q(e,t){return(0,V.jsx)(j,{agent:e,fallback:t||`-`})}function ce(e){let t=e.split(`/`).filter(Boolean);return t.length<=3?e||`-`:`/${t.slice(-3).join(`/`)}`}function le(e){return R[e]||`bg-tone-neutral/10 text-tone-neutral-fg border-tone-neutral/20`}function ue(e,t){let n=(B[e.status]??99)-(B[t.status]??99);return n===0?Number(t.updatedAt||0)-Number(e.updatedAt||0):n}function $({workspace:e,unmerged:t}){let n=r(t=>t.workspaceMergePreview[e.id]),i=r(e=>e.fetchWorkspaceMergePreview),a=t>0&&L.has(e.status);return(0,U.useEffect)(()=>{a&&n===void 0&&i(e.id)},[a,n,e.id,i]),!a||n===void 0||n.available===!1?null:n.conflict?(0,V.jsxs)(`span`,{className:`flex items-center gap-0.5 text-tone-warning-fg`,title:`Merging into ${n.baseRef||`base`} would conflict — resolve before merging`,children:[(0,V.jsx)(T,{className:`h-3 w-3`}),`conflict`]}):n.conflict===!1?(0,V.jsxs)(`span`,{className:`flex items-center gap-0.5 text-tone-success-fg`,title:`Clean to merge via ${n.strategy===`pr`?`PR`:`rebase + fast-forward`} into ${n.baseRef||`base`}`,children:[(0,V.jsx)(f,{className:`h-3 w-3`}),n.strategy===`pr`?`PR ready`:`clean`]}):null}function de({workspace:e}){let t=i(),n=r(t=>t.workspaceGitState[e.id]),a=r(e=>e.fetchWorkspaceGitState),s=e.mode===`isolated`&&!!e.worktreePath&&ne.has(e.status);if((0,U.useEffect)(()=>{s&&n===void 0&&a(e.id)},[s,n,e.id,a]),!s)return null;let l=(0,V.jsx)(D,{size:`icon-sm`,variant:`ghost`,className:`h-5 w-5`,title:`Refresh git state`,onClick:()=>void a(e.id),children:(0,V.jsx)(C,{className:`h-3 w-3`})});if(n===void 0)return(0,V.jsx)(`div`,{className:`flex items-center gap-1 text-[11px] text-muted-foreground`,children:`Loading git state…`});if(n.available===!1)return(0,V.jsxs)(`div`,{className:`flex items-center gap-1 text-[11px] text-muted-foreground`,title:n.reason,children:[(0,V.jsx)(`span`,{children:`git state unavailable`}),l]});if(n.missing)return(0,V.jsxs)(`div`,{className:`flex items-center gap-1 text-[11px] text-muted-foreground`,children:[`worktree gone `,l]});if(n.error)return(0,V.jsxs)(`div`,{className:`flex items-center gap-1 text-[11px] text-tone-danger-fg`,title:n.error,children:[(0,V.jsx)(`span`,{children:`git error`}),l]});let d=n.ahead??0,p=n.landed===!0,m=p?0:n.unmergedAhead??d,h=n.behind??0,g=n.dirtyCount??0,v=m===0&&g===0&&!p,y=n.lastCommit;return(0,V.jsxs)(`div`,{className:`space-y-0.5`,children:[(0,V.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-2 gap-y-0.5 text-[11px]`,children:[v?(0,V.jsx)(`span`,{className:`text-muted-foreground`,children:`no unmerged work`}):(0,V.jsxs)(V.Fragment,{children:[p?(0,V.jsxs)(`span`,{className:`flex items-center gap-0.5 text-tone-success-fg`,title:`Work already landed in ${n.baseRef||`base`} via squash/cherry-pick — safe to clean up`,children:[(0,V.jsx)(f,{className:`h-3 w-3`}),`landed`]}):(0,V.jsxs)(`span`,{className:m>0?`flex items-center text-tone-success-fg`:`flex items-center text-muted-foreground`,title:d===m?`${m} commit(s) ahead of base`:`${m} unmerged commit(s) (${d} ahead of base)`,children:[(0,V.jsx)(u,{className:`h-3 w-3`}),m]}),(0,V.jsxs)(`span`,{className:h>0?`flex items-center text-tone-warning-fg`:`flex items-center text-muted-foreground`,title:`${h} commit(s) behind base`,children:[(0,V.jsx)(c,{className:`h-3 w-3`}),h]}),g>0&&(0,V.jsxs)(`span`,{className:`flex items-center text-tone-orange-fg`,title:`${g} uncommitted change(s)`,children:[(0,V.jsx)(_,{className:`h-3 w-3`}),g]}),!p&&(0,V.jsx)($,{workspace:e,unmerged:m})]}),l]}),y&&(0,V.jsxs)(`div`,{className:`flex min-w-0 items-center gap-1 text-[11px] text-muted-foreground`,title:`${y.sha.slice(0,8)} — ${y.message}`,children:[(0,V.jsx)(x,{className:`h-3 w-3 shrink-0`}),(0,V.jsx)(`span`,{className:`truncate`,children:y.message||y.sha.slice(0,8)}),y.at?(0,V.jsxs)(`span`,{className:`shrink-0 opacity-70`,children:[`· `,o(t,y.at)]}):null]})]})}function fe({workspace:e}){let t=i(),n=typeof e.metadata?.mergedAt==`number`?e.metadata.mergedAt:void 0,r=[{label:`created`,at:e.createdAt},{label:`ready`,at:e.readyAt},{label:`merged`,at:n},{label:`cleaned`,at:e.cleanedAt}].filter(e=>typeof e.at==`number`&&e.at>0);return(0,V.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px] text-muted-foreground`,children:[(0,V.jsxs)(`span`,{className:`flex items-center gap-1 font-medium text-foreground`,children:[(0,V.jsx)(h,{className:`h-3 w-3`}),`Timeline`]}),r.map((e,n)=>(0,V.jsxs)(`span`,{className:`flex items-center gap-1`,children:[n>0&&(0,V.jsx)(`span`,{className:`opacity-40`,children:`→`}),(0,V.jsx)(`span`,{className:`text-foreground`,children:e.label}),(0,V.jsx)(`span`,{title:new Date(e.at).toLocaleString(),children:o(t,e.at)})]},e.label))]})}function pe(e){return e.startsWith(`+`)&&!e.startsWith(`+++`)?`text-tone-success-fg`:e.startsWith(`-`)&&!e.startsWith(`---`)?`text-tone-danger-fg`:e.startsWith(`@@`)?`text-tone-cyan-fg`:e.startsWith(`diff `)||e.startsWith(`index `)||e.startsWith(`+++`)||e.startsWith(`---`)?`text-muted-foreground`:``}function me({workspace:e}){let t=r(t=>t.workspaceDiff[e.id]),n=r(e=>e.fetchWorkspaceDiff),i=e.mode===`isolated`&&!!e.worktreePath;if((0,U.useEffect)(()=>{i&&t===void 0&&n(e.id)},[i,t,e.id,n]),!i)return null;if(t===void 0)return(0,V.jsx)(`div`,{className:`text-[11px] text-muted-foreground`,children:`Loading diff…`});if(t.available===!1)return(0,V.jsxs)(`div`,{className:`text-[11px] text-muted-foreground`,children:[`Diff unavailable`,t.reason?`: ${t.reason}`:``]});if(t.missing)return(0,V.jsx)(`div`,{className:`text-[11px] text-muted-foreground`,children:`Worktree no longer on disk`});if(t.error)return(0,V.jsxs)(`div`,{className:`text-[11px] text-tone-danger-fg`,children:[`Diff error: `,t.error]});if(!t.files.length)return(0,V.jsxs)(`div`,{className:`text-[11px] text-muted-foreground`,children:[`No committed changes against `,t.baseRef||`base`]});let a=(0,V.jsx)(D,{size:`icon-sm`,variant:`ghost`,className:`h-5 w-5`,title:`Refresh diff`,onClick:()=>void n(e.id),children:(0,V.jsx)(C,{className:`h-3 w-3`})});return(0,V.jsxs)(`div`,{className:`space-y-1`,children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-2 text-[11px] font-medium`,children:[(0,V.jsx)(l,{className:`h-3 w-3`}),(0,V.jsxs)(`span`,{children:[t.files.length,` file`,t.files.length===1?``:`s`,` vs `,t.baseRef||`base`]}),a]}),(0,V.jsx)(`ul`,{className:`space-y-0.5 text-[11px]`,children:t.files.map(e=>(0,V.jsxs)(`li`,{className:`flex items-center gap-2 font-mono`,children:[(0,V.jsx)(`span`,{className:`truncate`,title:e.path,children:e.path}),e.binary?(0,V.jsx)(`span`,{className:`shrink-0 text-muted-foreground`,children:`binary`}):(0,V.jsxs)(`span`,{className:`shrink-0`,children:[(0,V.jsxs)(`span`,{className:`text-tone-success-fg`,children:[`+`,e.additions??0]}),` `,(0,V.jsxs)(`span`,{className:`text-tone-danger-fg`,children:[`−`,e.deletions??0]})]})]},e.path))}),t.patch&&(0,V.jsxs)(`pre`,{className:`max-h-80 overflow-auto rounded border border-border bg-muted/30 p-2 text-[10.5px] leading-relaxed`,children:[t.patch.split(`
2
2
  `).map((e,t)=>(0,V.jsx)(`div`,{className:pe(e),children:e||` `},t)),t.truncated&&(0,V.jsx)(`div`,{className:`mt-1 text-muted-foreground`,children:`… patch truncated`})]})]})}function he({workspace:e}){return(0,V.jsxs)(`div`,{className:`space-y-3 border-t border-dashed border-border bg-muted/20 px-3 py-3`,children:[(0,V.jsx)(fe,{workspace:e}),(0,V.jsx)(se,{workspace:e}),(0,V.jsx)(me,{workspace:e})]})}function ge(e){let t=e.match(/\/pull\/(\d+)/);return t?`PR #${t[1]}`:`View PR`}function _e({workspace:e}){let t=e.metadata?.mergeResult,n=t?.prUrl,r=t?.error||e.metadata?.mergeError;return!n&&!r?null:(0,V.jsxs)(V.Fragment,{children:[n&&(0,V.jsxs)(`a`,{href:n,target:`_blank`,rel:`noreferrer`,title:n,className:`inline-flex items-center gap-0.5 rounded border border-tone-violet/30 px-1.5 py-0 text-[10px] text-tone-violet-fg hover:text-tone-violet-fg`,children:[(0,V.jsx)(S,{className:`h-2.5 w-2.5`}),ge(n)]}),r&&(0,V.jsxs)(O,{variant:`outline`,className:`max-w-[16rem] border-tone-warning/30 text-tone-warning-fg text-[10px]`,title:r,children:[(0,V.jsx)(T,{className:`mr-0.5 h-2.5 w-2.5 shrink-0`}),(0,V.jsxs)(`span`,{className:`truncate`,children:[`merge: `,r]})]})]})}function ve({workspace:e}){let t=i(),[n,a]=(0,U.useState)(!1),s=r(e=>e.agentsById),c=r(t=>t.workspaceFocusId===e.id),l=r(e=>e.deliverableTasks),u=r(e=>e.openTaskDetail),d=e.ownerAgentId?s[e.ownerAgentId]:void 0,f=ae(l,e.ownerAgentId,e.branch),p=r(t=>t.workspaceGitState[e.id]),m=!!p&&p.available!==!1&&p.landed===!0,h=f!=null&&(e.status===`merged`||e.status===`landed`||e.status===`cleaned`||e.status===`abandoned`||m),g=e.stewardAgentId?s[e.stewardAgentId]:void 0,_=e.worktreePath||e.sourceCwd||e.repoRoot,v=(0,U.useRef)(null);return(0,U.useEffect)(()=>{c&&v.current?.scrollIntoView({behavior:`smooth`,block:`center`})},[c]),(0,V.jsxs)(`div`,{ref:v,className:`border-t border-border ${c?`bg-primary/5 ring-1 ring-inset ring-primary/40`:``}`,children:[(0,V.jsxs)(`div`,{className:`grid gap-3 px-3 py-3 text-sm lg:grid-cols-[minmax(180px,1.2fr)_minmax(220px,1.5fr)_minmax(160px,1fr)_minmax(170px,auto)]`,children:[(0,V.jsxs)(`div`,{className:`min-w-0 space-y-1`,children:[(0,V.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,V.jsx)(b,{className:`h-3.5 w-3.5 shrink-0 text-muted-foreground`}),(0,V.jsx)(`span`,{className:`truncate font-medium`,title:e.branch||e.id,children:e.branch||e.id})]}),(0,V.jsxs)(`div`,{className:`flex flex-wrap gap-1`,children:[(0,V.jsx)(O,{variant:`outline`,className:`text-[10px] ${e.mode===`isolated`?`border-tone-sky/30 text-tone-sky-fg`:`border-tone-neutral/30 text-tone-neutral-fg`}`,children:e.mode}),e.requestedMode&&e.requestedMode!==e.mode&&(0,V.jsxs)(O,{variant:`outline`,className:`text-[10px]`,children:[`requested `,e.requestedMode]}),(0,V.jsx)(O,{variant:`outline`,className:`text-[10px] ${le(e.status)}`,children:z[e.status]||e.status}),e.landState&&(0,V.jsxs)(O,{variant:`outline`,className:`text-[10px] border-tone-violet/30 text-tone-violet-fg`,title:`Lifecycle state since ${e.landStateAt?o(t,e.landStateAt):`unknown`}`,children:[e.landState,e.landWaitReason?` · ${e.landWaitReason}`:``,e.landStateAt?` (${o(t,e.landStateAt)})`:``]}),(0,V.jsx)(_e,{workspace:e}),h&&f&&(0,V.jsx)(A,{id:f.id,title:f.title,status:f.status,onClick:()=>u(f)})]})]}),(0,V.jsxs)(`div`,{className:`min-w-0 space-y-1`,children:[(0,V.jsx)(`div`,{className:`truncate font-mono text-xs`,title:_,children:ce(_)}),(0,V.jsx)(`div`,{className:`truncate text-xs text-muted-foreground`,title:e.sourceCwd,children:e.sourceCwd}),(0,V.jsx)(de,{workspace:e})]}),(0,V.jsxs)(`div`,{className:`grid grid-cols-[4.5rem_minmax(0,1fr)] gap-x-2 gap-y-1 text-xs`,children:[typeof e.metadata.gateHost==`string`&&(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(`span`,{className:`text-muted-foreground`,children:`Gate host`}),(0,V.jsx)(`span`,{className:`truncate`,title:String(e.metadata.gateOrchestratorId??``),children:e.metadata.gateHost})]}),(0,V.jsx)(`span`,{className:`text-muted-foreground`,children:`Owner`}),(0,V.jsx)(`span`,{className:`truncate`,title:e.ownerAgentId,children:Q(d,e.ownerPolicyName||e.ownerAgentId)}),(0,V.jsx)(`span`,{className:`text-muted-foreground`,children:`Steward`}),(0,V.jsx)(`span`,{className:`truncate`,title:e.stewardAgentId,children:Q(g,e.stewardAgentId)}),(0,V.jsx)(`span`,{className:`text-muted-foreground`,children:`Updated`}),(0,V.jsx)(`span`,{children:o(t,e.updatedAt)}),e.baseRef&&(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(`span`,{className:`text-muted-foreground`,children:`Base`}),(0,V.jsx)(`span`,{className:`truncate`,title:e.baseSha,children:e.baseRef})]})]}),(0,V.jsx)(H,{workspace:e,expanded:n,onToggleDetails:()=>a(!n)})]}),!!e.metadata.stewardCancellation&&(0,V.jsx)(oe,{cancellation:e.metadata.stewardCancellation}),n&&(0,V.jsx)(he,{workspace:e})]})}function ye(){let[e,t]=(0,U.useState)(`active`),[n,i]=(0,U.useState)(K),[a,o]=(0,U.useState)([]),c=r(e=>e.workspaces),l=r(e=>e.set),u=r(e=>e.workspaceFocusId);(0,U.useEffect)(()=>{u&&(t(`all`),i(K))},[u]),(0,U.useEffect)(()=>()=>{l({workspaceFocusId:null})},[l]),(0,U.useEffect)(()=>{let e=!1;return s(`GET`,`/projects`).then(t=>{e||o(t.projects??[])}).catch(()=>{e||o([])}),()=>{e=!0}},[]);let d=(0,U.useMemo)(()=>X(c,e,n),[c,e,n]),f=(0,U.useMemo)(()=>Y(d,ue),[d]),p=c.filter(e=>W.has(e.status)).length,m=c.filter(e=>e.mode===`isolated`).length,h=c.filter(e=>e.status===`ready`||e.status===`review_requested`||e.status===`merge_planned`||e.status===`gate_running`||e.status===`gate_failed`||e.status===`merging`).length,g=c.filter(e=>e.status===`conflict`).length,_=c.filter(e=>e.status===`merged`||e.status===`landed`||e.status===`abandoned`||e.status===`cleaned`).length,v=[{key:`active`,label:`Active`,count:c.length-_},{key:`cleaned`,label:`Done`,count:_},{key:`all`,label:`All`,count:c.length}],y=(0,U.useMemo)(()=>{let e=[{value:K,label:`All Projects`}];for(let t of a)e.push({value:t.id,label:t.title||t.slug});return e.push({value:q,label:`Unassigned`}),e},[a]);return(0,V.jsxs)(`div`,{className:`space-y-4`,children:[(0,V.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,V.jsxs)(`div`,{children:[(0,V.jsx)(`h1`,{className:`text-2xl font-semibold`,children:`Workspaces`}),(0,V.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Agent worktrees, ownership, and merge readiness.`})]}),(0,V.jsxs)(`div`,{className:`ml-auto flex flex-wrap gap-1.5`,children:[(0,V.jsxs)(O,{variant:`outline`,children:[m,` isolated`]}),(0,V.jsxs)(O,{variant:`outline`,children:[p,` live`]}),(0,V.jsxs)(O,{variant:`outline`,children:[h,` ready`]}),g>0&&(0,V.jsxs)(O,{variant:`outline`,className:`border-tone-danger/20 text-tone-danger-fg`,children:[g,` conflict`]})]})]}),(0,V.jsx)(ie,{}),(0,V.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,V.jsx)(`div`,{className:`flex rounded-md border border-border bg-card p-1`,children:v.map(n=>(0,V.jsxs)(D,{size:`sm`,variant:e===n.key?`secondary`:`ghost`,className:`h-7 text-xs`,onClick:()=>t(n.key),children:[n.label,(0,V.jsx)(`span`,{className:`ml-1 text-muted-foreground`,children:n.count})]},n.key))}),(0,V.jsx)(`select`,{className:`h-8 min-w-[12rem] rounded-md border border-border bg-card px-2.5 text-sm text-foreground`,value:n,onChange:e=>i(e.target.value),children:y.map(e=>(0,V.jsx)(`option`,{value:e.value,children:e.label},e.value))})]}),f.length===0?(0,V.jsxs)(`div`,{className:`rounded-md border border-border px-3 py-12 text-center text-sm text-muted-foreground`,children:[`No `,e===`all`?``:e,` workspaces`,n===`__all__`?``:` in this project filter`]}):(0,V.jsx)(`div`,{className:`space-y-3`,children:f.map(e=>(0,V.jsx)(Z,{group:e,renderWorkspaceRow:e=>(0,V.jsx)(ve,{workspace:e},e.id)},e.key))})]})}export{ye as WorkspacesView};
3
- //# sourceMappingURL=workspaces-CzEGoAng.js.map
3
+ //# sourceMappingURL=workspaces-CHcfbLR3.js.map
@@ -18,12 +18,12 @@
18
18
  touch-action: none;
19
19
  }
20
20
  </style>
21
- <script type="module" crossorigin src="./assets/cosmos-BpebFLK2.js"></script>
21
+ <script type="module" crossorigin src="./assets/cosmos-BuVoq1aw.js"></script>
22
22
  <link rel="modulepreload" crossorigin href="./assets/legacy-storage-carry-C-tBSxRA.js">
23
- <link rel="modulepreload" crossorigin href="./assets/provider-display-BEeLXC_D.js">
24
- <link rel="modulepreload" crossorigin href="./assets/display-CDeH4I8T.js">
23
+ <link rel="modulepreload" crossorigin href="./assets/provider-display-bWwiuedV.js">
24
+ <link rel="modulepreload" crossorigin href="./assets/display-BemJG1f_.js">
25
25
  <link rel="modulepreload" crossorigin href="./assets/api-CIIVBtAV.js">
26
- <link rel="modulepreload" crossorigin href="./assets/agent-liveness-Bq-s73jW.js">
26
+ <link rel="modulepreload" crossorigin href="./assets/agent-liveness-DSQY1Aa_.js">
27
27
  <link rel="stylesheet" crossorigin href="./assets/cosmos-Dn8XrlnS.css">
28
28
  </head>
29
29
  <body>
package/public/index.html CHANGED
@@ -13,17 +13,17 @@
13
13
  <link rel="icon" href="favicon.svg" type="image/svg+xml">
14
14
  <link rel="manifest" href="manifest.webmanifest">
15
15
  <link rel="apple-touch-icon" href="icons/apple-touch-icon.png">
16
- <script type="module" crossorigin src="./assets/index-CqqgOI5R.js"></script>
16
+ <script type="module" crossorigin src="./assets/index-BC5XZc0z.js"></script>
17
17
  <link rel="modulepreload" crossorigin href="./assets/rolldown-runtime-QTnfLwEv.js">
18
18
  <link rel="modulepreload" crossorigin href="./assets/legacy-storage-carry-C-tBSxRA.js">
19
19
  <link rel="modulepreload" crossorigin href="./assets/dist-DeW2Y1R5.js">
20
20
  <link rel="modulepreload" crossorigin href="./assets/react-dom-DSFxiC7T.js">
21
- <link rel="modulepreload" crossorigin href="./assets/provider-display-BEeLXC_D.js">
22
- <link rel="modulepreload" crossorigin href="./assets/display-CDeH4I8T.js">
21
+ <link rel="modulepreload" crossorigin href="./assets/provider-display-bWwiuedV.js">
22
+ <link rel="modulepreload" crossorigin href="./assets/display-BemJG1f_.js">
23
23
  <link rel="modulepreload" crossorigin href="./assets/api-CIIVBtAV.js">
24
- <link rel="modulepreload" crossorigin href="./assets/agent-liveness-Bq-s73jW.js">
25
- <link rel="modulepreload" crossorigin href="./assets/store-DKPDIZBe.js">
26
- <link rel="modulepreload" crossorigin href="./assets/artifacts-DT-HkI5O.js">
24
+ <link rel="modulepreload" crossorigin href="./assets/agent-liveness-DSQY1Aa_.js">
25
+ <link rel="modulepreload" crossorigin href="./assets/store-BgDALGIX.js">
26
+ <link rel="modulepreload" crossorigin href="./assets/artifacts-Bjq-ZyBA.js">
27
27
  <link rel="modulepreload" crossorigin href="./assets/tasks-BIyeAaPC.js">
28
28
  <link rel="modulepreload" crossorigin href="./assets/host-mTgRw7xh.js">
29
29
  <link rel="modulepreload" crossorigin href="./assets/file-code-corner-CXhIR1vB.js">
@@ -54,7 +54,7 @@
54
54
  <link rel="modulepreload" crossorigin href="./assets/archive-CIuPSvmx.js">
55
55
  <link rel="modulepreload" crossorigin href="./assets/arrow-up-a-z-CKC2RCjD.js">
56
56
  <link rel="modulepreload" crossorigin href="./assets/preload-helper-HclGiUj8.js">
57
- <link rel="modulepreload" crossorigin href="./assets/markdown-preview-W4VQQPAv.js">
57
+ <link rel="modulepreload" crossorigin href="./assets/markdown-preview-DNT4OUwQ.js">
58
58
  <link rel="modulepreload" crossorigin href="./assets/folder-tree-BG3Y9nqH.js">
59
59
  <link rel="modulepreload" crossorigin href="./assets/git-branch-yxhV0m8E.js">
60
60
  <link rel="modulepreload" crossorigin href="./assets/loader-circle-BfPd4kOD.js">
@@ -67,15 +67,15 @@
67
67
  <link rel="modulepreload" crossorigin href="./assets/copy-DFxhHRtV.js">
68
68
  <link rel="modulepreload" crossorigin href="./assets/copy-button-CjOj4HEf.js">
69
69
  <link rel="modulepreload" crossorigin href="./assets/input-CsTB6jIx.js">
70
- <link rel="modulepreload" crossorigin href="./assets/code-preview-CzrZfr9U.js">
71
- <link rel="modulepreload" crossorigin href="./assets/files-BTeGVmTg.js">
70
+ <link rel="modulepreload" crossorigin href="./assets/code-preview-KIRZA6cz.js">
71
+ <link rel="modulepreload" crossorigin href="./assets/files-DXWcrxOz.js">
72
72
  <link rel="modulepreload" crossorigin href="./assets/cpu-Dndy84IU.js">
73
73
  <link rel="modulepreload" crossorigin href="./assets/eye-BAP6fHrX.js">
74
74
  <link rel="modulepreload" crossorigin href="./assets/layers-DEfClY-v.js">
75
75
  <link rel="modulepreload" crossorigin href="./assets/lock-BW8MPKw_.js">
76
76
  <link rel="modulepreload" crossorigin href="./assets/rocket-BmO1qSu-.js">
77
77
  <link rel="modulepreload" crossorigin href="./assets/terminal-Bl2u7KxT.js">
78
- <link rel="modulepreload" crossorigin href="./assets/agent-lineage-SgDt9i3T.js">
78
+ <link rel="modulepreload" crossorigin href="./assets/agent-lineage-kq9TPYFw.js">
79
79
  <link rel="modulepreload" crossorigin href="./assets/package-open-ckPgcjpv.js">
80
80
  <link rel="modulepreload" crossorigin href="./assets/bell-_Yzbxxrt.js">
81
81
  <link rel="modulepreload" crossorigin href="./assets/radio-Bn0_qc0G.js">
@@ -98,29 +98,29 @@
98
98
  <link rel="modulepreload" crossorigin href="./assets/sparkles-CzwR10ZU.js">
99
99
  <link rel="modulepreload" crossorigin href="./assets/bot-B0NpDNhr.js">
100
100
  <link rel="modulepreload" crossorigin href="./assets/messages-square-DVM1ZtcI.js">
101
- <link rel="modulepreload" crossorigin href="./assets/workflow-marker-X8wxyhzC.js">
101
+ <link rel="modulepreload" crossorigin href="./assets/workflow-marker-CzOsB8BM.js">
102
102
  <link rel="modulepreload" crossorigin href="./assets/server-CZIRjFyY.js">
103
103
  <link rel="modulepreload" crossorigin href="./assets/provider-brand-icon-_67JR7Zh.js">
104
- <link rel="modulepreload" crossorigin href="./assets/agent-type-icon-CY113sp-.js">
104
+ <link rel="modulepreload" crossorigin href="./assets/agent-type-icon-CXSLrKiq.js">
105
105
  <link rel="modulepreload" crossorigin href="./assets/users-C7B3u9jv.js">
106
106
  <link rel="modulepreload" crossorigin href="./assets/wrench-C7-4CgnY.js">
107
- <link rel="modulepreload" crossorigin href="./assets/agent-name-CcY3Aijy.js">
108
- <link rel="modulepreload" crossorigin href="./assets/formatted-body-MLtodyPp.js">
109
- <link rel="modulepreload" crossorigin href="./assets/TraceView-DYU962-H.js">
107
+ <link rel="modulepreload" crossorigin href="./assets/agent-name-C_7F4DFR.js">
108
+ <link rel="modulepreload" crossorigin href="./assets/formatted-body-qy2nTD_1.js">
109
+ <link rel="modulepreload" crossorigin href="./assets/TraceView-B99Uu2yT.js">
110
110
  <link rel="modulepreload" crossorigin href="./assets/boxes-Cv7Wq3h4.js">
111
111
  <link rel="modulepreload" crossorigin href="./assets/braces-BOks9SsY.js">
112
112
  <link rel="modulepreload" crossorigin href="./assets/brain-circuit-CpQeSmp3.js">
113
113
  <link rel="modulepreload" crossorigin href="./assets/calendar-clock-CDG_KBhx.js">
114
114
  <link rel="modulepreload" crossorigin href="./assets/calendar-QJjoZ1JU.js">
115
115
  <link rel="modulepreload" crossorigin href="./assets/textarea-hs6Mpyfl.js">
116
- <link rel="modulepreload" crossorigin href="./assets/service-access-settings-Crq-6a-B.js">
116
+ <link rel="modulepreload" crossorigin href="./assets/service-access-settings-D3Xxqb9w.js">
117
117
  <link rel="modulepreload" crossorigin href="./assets/chart-column-S02ZGfTR.js">
118
118
  <link rel="modulepreload" crossorigin href="./assets/circle-arrow-up-B432r0Kk.js">
119
119
  <link rel="modulepreload" crossorigin href="./assets/package-plus-C1AKMjsl.js">
120
120
  <link rel="modulepreload" crossorigin href="./assets/octagon-x-B5lnUY-8.js">
121
121
  <link rel="modulepreload" crossorigin href="./assets/external-link-BRfu-fHG.js">
122
122
  <link rel="modulepreload" crossorigin href="./assets/task-chip-CYj0mpoL.js">
123
- <link rel="modulepreload" crossorigin href="./assets/issue-ref-chip-CeWBNWn7.js">
123
+ <link rel="modulepreload" crossorigin href="./assets/issue-ref-chip-DbH8J9Ak.js">
124
124
  <link rel="modulepreload" crossorigin href="./assets/circle-x-CZ0erS7Q.js">
125
125
  <link rel="modulepreload" crossorigin href="./assets/zap-DGuDTw4w.js">
126
126
  <link rel="modulepreload" crossorigin href="./assets/clipboard-list-W2YeUsxT.js">
@@ -131,7 +131,7 @@
131
131
  <link rel="modulepreload" crossorigin href="./assets/flame-CxBuz46L.js">
132
132
  <link rel="modulepreload" crossorigin href="./assets/minimize-2-BkK6XoMP.js">
133
133
  <link rel="modulepreload" crossorigin href="./assets/pin-DcsKeXxr.js">
134
- <link rel="modulepreload" crossorigin href="./assets/artifact-viewer-KRvSc7sl.js">
134
+ <link rel="modulepreload" crossorigin href="./assets/artifact-viewer-tBpTrEPb.js">
135
135
  <link rel="modulepreload" crossorigin href="./assets/flag-CnEG9PH-.js">
136
136
  <link rel="modulepreload" crossorigin href="./assets/folder-git-2-CJOmTT06.js">
137
137
  <link rel="modulepreload" crossorigin href="./assets/folder-open-CBUCMSlu.js">
@@ -154,7 +154,7 @@
154
154
  <link rel="modulepreload" crossorigin href="./assets/message-square-C-1G8dMM.js">
155
155
  <link rel="modulepreload" crossorigin href="./assets/paperclip-CNpKZKum.js">
156
156
  <link rel="modulepreload" crossorigin href="./assets/pause-DttnHD4c.js">
157
- <link rel="modulepreload" crossorigin href="./assets/agent-project-badge-DGYbIhaI.js">
157
+ <link rel="modulepreload" crossorigin href="./assets/agent-project-badge-B6yAh70a.js">
158
158
  <link rel="modulepreload" crossorigin href="./assets/pencil-B1Hf2V_J.js">
159
159
  <link rel="modulepreload" crossorigin href="./assets/play-BbT8m7A0.js">
160
160
  <link rel="modulepreload" crossorigin href="./assets/plug-zap-V0wMDJ-G.js">
@@ -172,17 +172,17 @@
172
172
  <link rel="modulepreload" crossorigin href="./assets/user-plus-D9749q73.js">
173
173
  <link rel="modulepreload" crossorigin href="./assets/volume-2-XrcRKD9Z.js">
174
174
  <link rel="modulepreload" crossorigin href="./assets/waypoints-CIzINtLT.js">
175
- <link rel="modulepreload" crossorigin href="./assets/use-selectors-BdxBW8mL.js">
176
- <link rel="modulepreload" crossorigin href="./assets/status-dot-BcHyw1Vw.js">
177
- <link rel="modulepreload" crossorigin href="./assets/terminal-viewer-CpY5_m7W.js">
178
- <link rel="modulepreload" crossorigin href="./assets/log-viewer-Cib8nqdE.js">
179
- <link rel="modulepreload" crossorigin href="./assets/fleet-metrics-BHEt5yc_.js">
180
- <link rel="modulepreload" crossorigin href="./assets/busy-health-D3hwvYb4.js">
181
- <link rel="modulepreload" crossorigin href="./assets/profile-icon-BsRyBMea.js">
175
+ <link rel="modulepreload" crossorigin href="./assets/use-selectors-0X_UZkk-.js">
176
+ <link rel="modulepreload" crossorigin href="./assets/status-dot-C703YIy1.js">
177
+ <link rel="modulepreload" crossorigin href="./assets/terminal-viewer-Dh8dSC7e.js">
178
+ <link rel="modulepreload" crossorigin href="./assets/log-viewer-PH4zVn24.js">
179
+ <link rel="modulepreload" crossorigin href="./assets/fleet-metrics-BGoDAFI-.js">
180
+ <link rel="modulepreload" crossorigin href="./assets/busy-health-BvNQ9g5x.js">
181
+ <link rel="modulepreload" crossorigin href="./assets/profile-icon-_SMuSbYF.js">
182
182
  <link rel="modulepreload" crossorigin href="./assets/token-estimate-Co-Jdphh.js">
183
- <link rel="modulepreload" crossorigin href="./assets/versioned-prompt-editor-CIVg7XB1.js">
184
- <link rel="modulepreload" crossorigin href="./assets/host-providers-dialog-mapF4Fj9.js">
185
- <link rel="stylesheet" crossorigin href="./assets/index-MYAIwYTX.css">
183
+ <link rel="modulepreload" crossorigin href="./assets/versioned-prompt-editor-BkTi7eim.js">
184
+ <link rel="modulepreload" crossorigin href="./assets/host-providers-dialog-BGPHxuwT.js">
185
+ <link rel="stylesheet" crossorigin href="./assets/index-D8Rp9pz2.css">
186
186
  </head>
187
187
  <body class="bg-background text-foreground antialiased">
188
188
  <div id="root"></div>
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "agent-relay-runner",
3
3
  "description": "Thin Humwick runner bridge for Claude Code",
4
- "version": "0.130.3",
4
+ "version": "0.130.4",
5
5
  "agentRelayContracts": {
6
6
  "providerPluginProtocol": 1
7
7
  }
@@ -49,7 +49,7 @@ export class ClaudeApiAdapter extends ClaudeHeadlessAdapter {
49
49
  env: resolveProviderApiAuth(this.provider, built.env, {
50
50
  ANTHROPIC_API_KEY_FILE: providerConfig.env.ANTHROPIC_API_KEY_FILE ?? process.env.ANTHROPIC_API_KEY_FILE
51
51
  ?? "~/.config/agent-relay/secrets/anthropic-api.key",
52
- }) };
52
+ }, config.env) };
53
53
  }
54
54
 
55
55
  override async spawn(config: RunnerSpawnConfig): Promise<ManagedProcess> {
@@ -11,7 +11,7 @@ export function withProviderSetup(adapter: ProviderAdapter): ProviderAdapter {
11
11
  const spawn = adapter.spawn.bind(adapter);
12
12
  adapter.spawn = async (config) => {
13
13
  const env = selectProviderConfigEnv(config.providerConfig.env, hostSourcesFor(config).settings);
14
- const auth = await checkProviderAuth(config.provider, undefined, env, resolveLaunchCommand(config.providerConfig.command));
14
+ const auth = await checkProviderAuth(config.provider, undefined, env, resolveLaunchCommand(config.providerConfig.command), config.env);
15
15
  if (!auth.ok) throw new Error(auth.reason);
16
16
  return spawn(config);
17
17
  };
@@ -22,7 +22,7 @@ export function providerStartupFailure(error: unknown): ProviderStatusEvent {
22
22
  const message = `Provider startup failed: ${errMessage(error)}`;
23
23
  return { status: "error", reason: "provider-turn", providerState: {
24
24
  state: "blocked", terminal: true, reason: "providerSetupRequired", label: "Provider setup required", message,
25
- recommendedAction: "Complete the provider login and first-run setup on this host, then restart the runner.",
25
+ recommendedAction: "Resolve the provider startup failure shown above, then restart the runner.",
26
26
  } };
27
27
  }
28
28
 
@@ -0,0 +1,35 @@
1
+ // One-time dashboard login links (#2680): `humwick init` hands the first user a signed-in dashboard
2
+ // without an env-file edit or a copied admin token. A link carries a short-lived token whose only
3
+ // scope matches no route, so it cannot act as an access token; redeeming revokes it (single use)
4
+ // and mints a normal user session.
5
+ import { userSinkId, isHumanAgentId, userIdFromAddress, type User } from "@humwick/sdk";
6
+ import { createTokenAsync, revokeTokenAsync } from "../token-db-write.ts";
7
+ import { verifyComponentToken } from "../security.ts";
8
+ import { getUser } from "../db/users.ts";
9
+ import { USER_TOKEN_ROLE } from "./admin-routes.ts";
10
+
11
+ export const LOGIN_LINK_SCOPE = "auth:login-link";
12
+ export const LOGIN_LINK_TTL_SECONDS = 15 * 60;
13
+
14
+ /** Mint a single-use login link for `user`. The path opens the dashboard signed in as them. */
15
+ export async function mintLoginLink(user: User, createdBy: string): Promise<{ path: string; expiresAt: number }> {
16
+ const { token, record } = await createTokenAsync({
17
+ sub: userSinkId(user.id),
18
+ role: USER_TOKEN_ROLE,
19
+ scope: [LOGIN_LINK_SCOPE],
20
+ ttlSeconds: LOGIN_LINK_TTL_SECONDS,
21
+ createdBy,
22
+ });
23
+ return { path: `/login/${token}`, expiresAt: record.expiresAt! };
24
+ }
25
+
26
+ /** The active user a valid, unused login link names, consuming the link; null otherwise. */
27
+ export async function redeemLoginLink(code: string): Promise<User | null> {
28
+ const payload = verifyComponentToken(code);
29
+ if (!payload?.jti || !payload.scope.includes(LOGIN_LINK_SCOPE) || !isHumanAgentId(payload.sub)) return null;
30
+ const userId = userIdFromAddress(payload.sub);
31
+ const user = userId ? getUser(userId) : undefined;
32
+ if (!user || user.status !== "active") return null;
33
+ // The revoke is the single-use gate: only the first redeemer flips the row.
34
+ return (await revokeTokenAsync(payload.jti, "rotation")) ? user : null;
35
+ }
package/src/cli/index.ts CHANGED
@@ -22,6 +22,7 @@ import { handleUpgradeCommand } from "./upgrade";
22
22
  import { handleProviderCommand } from "./provider";
23
23
  import { handleContextProbeCommand } from "./context-probe";
24
24
  import { handleSetupCommand } from "./setup";
25
+ import { handleInitCommand } from "./init";
25
26
  import { handleDaemonCommand } from "./daemon";
26
27
  import { handleOrchestratorCommand } from "./orchestrator";
27
28
  import { handleDevCommand } from "./dev";
@@ -68,6 +69,7 @@ Usage:
68
69
  humwick run --status <runId>
69
70
  ${CHANNEL_OUTPUT_USAGE}
70
71
  humwick [start]
72
+ humwick init [--yes] [--json] [--tarball-dir DIR] [--env-file PATH] [--runtime-prefix DIR] [--host HOST] [--port PORT] [--db-path PATH] (install or repair the server as a user service)
71
73
  humwick setup [--yes] [--dry-run] [--force] [--env-file PATH] [--runtime-prefix DIR] [--host HOST] [--port PORT] [--db-path PATH] [--token TOKEN|--no-token]
72
74
  humwick upgrade [--dry-run] [--version VERSION] [--runtime-prefix DIR] [--providers auto|all|codex|claude|opencode|orchestrator] [--no-restart] [--yes]
73
75
  humwick upgrade --host ID [--host ID2 ...] [--version VERSION] [--providers ...] (upgrade remote orchestrator hosts over the relay)
@@ -281,10 +283,14 @@ export async function handleCli(args: string[]): Promise<"start" | "handled"> {
281
283
  await handleUpgradeCommand(command === "setup" ? args.slice(2) : args.slice(1));
282
284
  return "handled";
283
285
  }
284
- if (command === "setup" || command === "init") {
286
+ if (command === "setup") {
285
287
  await handleSetupCommand(args.slice(1));
286
288
  return "handled";
287
289
  }
290
+ if (command === "init") {
291
+ await handleInitCommand(args.slice(1));
292
+ return "handled";
293
+ }
288
294
  if (command === "channels-host") {
289
295
  const { handleChannelsHostCommand } = await import("./channels-host");
290
296
  await handleChannelsHostCommand(args.slice(1));
@@ -0,0 +1,53 @@
1
+ // `humwick init` (#2680): install or repair a persistent server; the same code serves --yes/--json.
2
+ import { InitStepError, runInit, type InitOptions } from "../init";
3
+ import { errMessage } from "@humwick/sdk";
4
+ import { confirm } from "./_shared";
5
+
6
+ export async function handleInitCommand(args: string[]): Promise<void> {
7
+ const options: InitOptions = {};
8
+ let yes = false;
9
+ let json = false;
10
+ for (let i = 0; i < args.length; i++) {
11
+ const arg = args[i];
12
+ const value = () => {
13
+ const next = args[++i];
14
+ if (!next) throw new Error(`${arg} needs a value`);
15
+ return next;
16
+ };
17
+ if (arg === "--tarball-dir") options.tarballDir = value();
18
+ else if (arg === "--runtime-prefix") options.runtimePrefix = value();
19
+ else if (arg === "--env-file") options.envFile = value();
20
+ else if (arg === "--host") options.host = value();
21
+ else if (arg === "--port") options.port = parseInt(value(), 10);
22
+ else if (arg === "--db-path") options.dbPath = value();
23
+ else if (arg === "--yes" || arg === "-y") yes = true;
24
+ else if (arg === "--json") json = true;
25
+ else throw new Error(`Unknown init option "${arg}"`);
26
+ }
27
+
28
+ if (!yes && !json && !(await confirm("Install the Humwick server as a user service on this machine?"))) {
29
+ console.log("Init cancelled.");
30
+ return;
31
+ }
32
+ // With --json, stdout carries only the result object; progress goes to stderr.
33
+ const log = (line: string) => (json ? console.error : console.log)(`✓ ${line}`);
34
+ try {
35
+ const result = await runInit(options, log);
36
+ if (json) {
37
+ console.log(JSON.stringify(result, null, 2));
38
+ return;
39
+ }
40
+ for (const warning of result.warnings) console.log(`! ${warning}`);
41
+ console.log(`\nHumwick ${result.version} is running as ${result.service.unit}.`);
42
+ console.log(`Dashboard: ${result.dashboardUrl}`);
43
+ console.log(`Login link: ${result.loginUrl}`);
44
+ console.log("\nNext:");
45
+ for (const step of result.next) console.log(`- ${step}`);
46
+ } catch (e) {
47
+ const step = e instanceof InitStepError ? e.step : "init";
48
+ const repair = e instanceof InitStepError ? e.repair : "Rerun init; it resumes where it stopped.";
49
+ if (json) console.log(JSON.stringify({ ok: false, step, error: errMessage(e), repair }, null, 2));
50
+ else console.error(`init failed at ${step}: ${errMessage(e)}\nRepair: ${repair}`);
51
+ process.exitCode = 1;
52
+ }
53
+ }
@@ -20,7 +20,7 @@ import { createUserPathPlan, executeUserPathPlan, purgeUserPath } from "../user-
20
20
  import { VERSION } from "../config";
21
21
  import { shellQuote } from "@humwick/sdk/shell-utils";
22
22
  import { RELAY_TOKEN_HEADER } from "@humwick/sdk";
23
- import { expandTilde } from "../utils";
23
+ import { expandTilde, sanitizeOrchestratorId } from "../utils";
24
24
  import { confirm } from "./_shared";
25
25
 
26
26
  const ORCHESTRATOR_USAGE =
@@ -310,12 +310,6 @@ async function exchangeOrchestratorBootstrapToken(relayUrl: string, bootstrapTok
310
310
  return payload.token;
311
311
  }
312
312
 
313
- function sanitizeOrchestratorId(value: string): string {
314
- const clean = value.trim().replace(/\./g, "-").replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "");
315
- if (!clean) throw new Error("--id must contain at least one letter or number");
316
- return clean.slice(0, 120);
317
- }
318
-
319
313
  function detectProviderPathPrefixes(providers: string[]): string[] {
320
314
  const prefixes: string[] = [];
321
315
  for (const provider of providers) {
package/src/cli/setup.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  // Setup command — auto-split from cli.ts (#294). Generates the relay env file.
2
- import { createSetupPlan, executeSetupPlan, formatSetupPlan, pathExists } from "../setup";
2
+ import { executeSetupPlan, formatSetupPlan, pathExists, redactSetupPlan, resolveSetupPlan } from "../setup";
3
3
  import { confirm } from "./_shared";
4
4
 
5
5
  export async function handleSetupCommand(args: string[]): Promise<void> {
@@ -32,7 +32,7 @@ export async function handleSetupCommand(args: string[]): Promise<void> {
32
32
  else throw new Error(`Unknown setup option "${arg}"`);
33
33
  }
34
34
 
35
- const plan = createSetupPlan({
35
+ const plan = await resolveSetupPlan({
36
36
  ...(envFile ? { envFile } : {}),
37
37
  ...(host ? { host } : {}),
38
38
  ...(port !== undefined ? { port } : {}),
@@ -43,7 +43,8 @@ export async function handleSetupCommand(args: string[]): Promise<void> {
43
43
  force,
44
44
  });
45
45
 
46
- if (!dryRun && !yes && await pathExists(plan.envFile)) {
46
+ // A managed env file is reused (same token), so only a foreign file needs consent.
47
+ if (!dryRun && !yes && !plan.reused && await pathExists(plan.envFile)) {
47
48
  const ok = await confirm(`Overwrite ${plan.envFile}?`);
48
49
  if (!ok) {
49
50
  console.log("Setup cancelled.");
@@ -52,6 +53,7 @@ export async function handleSetupCommand(args: string[]): Promise<void> {
52
53
  }
53
54
 
54
55
  const result = await executeSetupPlan(plan, { dryRun, force });
55
- if (json) console.log(JSON.stringify({ plan, output: result }, null, 2));
56
+ // The admin token never goes to stdout; it stays in the 0600 env file (#2680).
57
+ if (json) console.log(JSON.stringify({ plan: redactSetupPlan(plan), output: result }, null, 2));
56
58
  else console.log(dryRun ? formatSetupPlan(plan) : result);
57
59
  }
@@ -9,6 +9,7 @@ import { stringValue } from "@humwick/sdk";
9
9
  import type { CreateCommandInput } from "../types";
10
10
  import { getLaunchFact } from "./launch-facts";
11
11
  import { spawnProcessGoneSql } from "./spawn-process-evidence";
12
+ import { WORKFLOW_EXECUTIONS_SQL } from "./workflow-execution";
12
13
 
13
14
  /** Read-only preflight runs before project or Task creation; the writer repeats it. */
14
15
  export function assertDelegatedSpawnTarget(input: CreateCommandInput) {
@@ -53,7 +54,7 @@ export function assertDelegatedSpawnAdmission(input: CreateCommandInput, now: nu
53
54
  if (input.type !== "agent.spawn") return;
54
55
  const workflowRunId = stringValue(input.params?.workflowRunId);
55
56
  const run = workflowRunId && getDb().query("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'kernel_entity__workflow__run'").get()
56
- ? getDb().query("SELECT callerAgentId, coordinator FROM kernel_entity__workflow__run WHERE scope = 'local' AND id = ?")
57
+ ? getDb().query(`SELECT callerAgentId, coordinator FROM ${WORKFLOW_EXECUTIONS_SQL} WHERE scope = 'local' AND id = ?`)
57
58
  .get(workflowRunId) as { callerAgentId: string | null; coordinator: string } | null : null;
58
59
  const origin = run?.callerAgentId ?? run?.coordinator;
59
60
  if (origin && participatesInSpawnDelegation(origin) && input.params?.spawnedBy !== origin) {