loomrail 0.1.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +4 -0
  3. package/README.md +266 -0
  4. package/apps/cli/dist/index.js +11154 -0
  5. package/apps/cli/migrations/0001_initial.sql +99 -0
  6. package/apps/cli/migrations/0002_mock_workflow.sql +169 -0
  7. package/apps/cli/migrations/0003_budget_pause_recovery.sql +154 -0
  8. package/apps/cli/migrations/0004_pipeline_started_budget_backfill.sql +72 -0
  9. package/apps/cli/migrations/0005_acceptance_evidence.sql +129 -0
  10. package/apps/cli/migrations/0006_session_handoff.sql +166 -0
  11. package/apps/cli/migrations/0007_pack_share_backoff.sql +11 -0
  12. package/apps/cli/migrations/0008_stage_attempt_counter_backfill.sql +169 -0
  13. package/apps/cli/migrations/0009_session_window_occupancy.sql +44 -0
  14. package/apps/cli/migrations/0010_provider_session_pid.sql +5 -0
  15. package/apps/cli/migrations/0011_work_item_workspaces.sql +94 -0
  16. package/apps/cli/migrations/0012_registered_repository_projects.sql +54 -0
  17. package/apps/cli/migrations/0013_stage_attempt_result_tree.sql +166 -0
  18. package/apps/cli/migrations/0014_live_evidence_provider.sql +49 -0
  19. package/apps/web/dist/assets/index-DjwvCSSY.js +5 -0
  20. package/apps/web/dist/assets/index-DjwvCSSY.js.map +1 -0
  21. package/apps/web/dist/assets/index-Z88TqCIf.css +1 -0
  22. package/apps/web/dist/assets/radix-vendor-CRdHXIPR.js +42 -0
  23. package/apps/web/dist/assets/radix-vendor-CRdHXIPR.js.map +1 -0
  24. package/apps/web/dist/assets/react-vendor-BicOiEU0.js +10 -0
  25. package/apps/web/dist/assets/react-vendor-BicOiEU0.js.map +1 -0
  26. package/apps/web/dist/assets/rolldown-runtime-CbXtAM7H.js +1 -0
  27. package/apps/web/dist/assets/tanstack-vendor-ec08LVZ_.js +2 -0
  28. package/apps/web/dist/assets/tanstack-vendor-ec08LVZ_.js.map +1 -0
  29. package/apps/web/dist/assets/validation-vendor-CGrOSWd3.js +65 -0
  30. package/apps/web/dist/assets/validation-vendor-CGrOSWd3.js.map +1 -0
  31. package/apps/web/dist/favicon.svg +5 -0
  32. package/apps/web/dist/index.html +60 -0
  33. package/apps/web/dist/theme-bootstrap.js +46 -0
  34. package/fixtures/projects/api-service-b/README.md +3 -0
  35. package/fixtures/projects/api-service-b/loomrail-fixture.json +6 -0
  36. package/fixtures/projects/web-app-a/README.md +3 -0
  37. package/fixtures/projects/web-app-a/loomrail-fixture.json +6 -0
  38. package/package.json +46 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-DjwvCSSY.js","names":[],"sources":["../../../../packages/ui/src/styles.css","../../src/boardView.ts","../../../../packages/contracts/dist/shared.js","../../../../packages/contracts/dist/event-stream.js","../../../../packages/contracts/dist/session.js","../../../../packages/contracts/dist/workspace.js","../../../../packages/contracts/dist/workflow.js","../../../../packages/contracts/dist/work-management.js","../../../../packages/ui/dist/icons.js","../../../../packages/ui/dist/foundation.js","../../../../packages/ui/dist/forms.js","../../../../packages/ui/dist/filter-search.js","../../../../packages/ui/dist/overlays.js","../../../../packages/ui/dist/filters.js","../../../../packages/ui/dist/patterns.js","../../src/components/BrandMark.tsx","../../src/i18n.tsx","../../src/layout.ts","../../src/components/PanelResizer.tsx","../../src/api.ts","../../src/components/LocalConnectionRecovery.tsx","../../src/density.ts","../../src/theme.ts","../../src/session.ts","../../src/changesView.ts","../../src/eventStream.ts","../../src/useEventStream.ts","../../src/workspace.tsx","../../src/shell/AppFrame.tsx","../../src/views/ChangesSection.tsx","../../src/taskMoves.ts","../../src/views/WorkbenchPage.tsx","../../src/router.tsx","../../src/App.tsx","../../src/main.tsx"],"sourcesContent":["@import \"./tokens.css\";\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n* {\n scrollbar-color: var(--lr-scrollbar-thumb) var(--lr-scrollbar-track);\n scrollbar-width: thin;\n}\n\n*::-webkit-scrollbar {\n height: 6px;\n width: 6px;\n}\n\n*::-webkit-scrollbar-track {\n background: var(--lr-scrollbar-track);\n}\n\n*::-webkit-scrollbar-thumb {\n background: var(--lr-scrollbar-thumb);\n border: 1px solid transparent;\n border-radius: var(--lr-radius-full);\n background-clip: padding-box;\n}\n\n*::-webkit-scrollbar-thumb:hover {\n background: var(--lr-scrollbar-thumb-hover);\n background-clip: padding-box;\n}\n\n.lr-icon {\n display: block;\n flex: 0 0 auto;\n pointer-events: none;\n}\n\n.lr-icon--spinner {\n animation: lr-spin 700ms linear infinite;\n}\n\n.lr-control--sm {\n height: var(--lr-size-control-sm);\n}\n\n.lr-control--md {\n height: var(--lr-size-control);\n}\n\n.lr-control--lg {\n height: var(--lr-size-control-lg);\n}\n\n.lr-button,\n.lr-icon-button {\n align-items: center;\n border: 1px solid transparent;\n color: var(--lr-control-text);\n cursor: pointer;\n display: inline-flex;\n font: inherit;\n font-size: var(--lr-font-sm);\n font-weight: var(--lr-weight-medium);\n justify-content: center;\n line-height: 1;\n outline: none;\n position: relative;\n transition:\n background-color var(--lr-duration-fast) var(--lr-ease-standard),\n border-color var(--lr-duration-fast) var(--lr-ease-standard),\n color var(--lr-duration-fast) var(--lr-ease-standard),\n box-shadow var(--lr-duration-fast) var(--lr-ease-standard);\n user-select: none;\n white-space: nowrap;\n}\n\n.lr-button {\n gap: var(--lr-space-1-5);\n padding: 0 var(--lr-space-2-5);\n}\n\n.lr-button__content {\n align-items: center;\n display: inline-flex;\n gap: var(--lr-space-1-5);\n justify-content: center;\n line-height: 1;\n min-width: 0;\n}\n\n.lr-button--rounded {\n border-radius: var(--lr-button-radius);\n}\n\n.lr-button--pill {\n border-radius: var(--lr-button-pill-radius);\n}\n\n.lr-button--ghost {\n background: transparent;\n}\n\n.lr-button--ghost:hover:not(:disabled),\n.lr-button--ghost[data-state=\"open\"] {\n background: var(--lr-surface-hover);\n color: var(--lr-text);\n}\n\n.lr-button--ghost:active:not(:disabled) {\n background: var(--lr-surface-active);\n}\n\n.lr-button--secondary {\n background: var(--lr-button-secondary-bg);\n border-color: var(--lr-button-secondary-border);\n box-shadow: var(--lr-button-overlay-shadow);\n}\n\n.lr-button--secondary:hover:not(:disabled) {\n background: var(--lr-button-secondary-bg-hover);\n border-color: transparent;\n box-shadow: var(--lr-button-overlay-shadow-hover);\n color: var(--lr-text);\n}\n\n.lr-button--secondary:active:not(:disabled),\n.lr-button--secondary[data-state=\"open\"]:not(:disabled) {\n background: var(--lr-surface-active);\n border-color: transparent;\n box-shadow: var(--lr-button-overlay-shadow-active);\n color: var(--lr-text);\n}\n\n.lr-button--surface {\n background: var(--lr-button-surface-bg);\n border-color: var(--lr-button-surface-border);\n border-width: 0.5px;\n box-shadow: var(--lr-button-overlay-shadow);\n}\n\n.lr-button--surface:hover:not(:disabled) {\n background: var(--lr-button-surface-bg-hover);\n box-shadow: var(--lr-button-overlay-shadow-hover);\n color: var(--lr-text);\n}\n\n.lr-button--surface:active:not(:disabled),\n.lr-button--surface[data-state=\"open\"]:not(:disabled) {\n background: var(--lr-button-surface-bg-active);\n box-shadow: var(--lr-button-overlay-shadow-active);\n color: var(--lr-text);\n}\n\n.lr-button--primary {\n background: var(--lr-button-primary-bg);\n border-color: color-mix(in srgb, var(--lr-button-primary-bg) 88%, black);\n box-shadow:\n inset 0 1px rgb(255 255 255 / 15%),\n 0 1px 2px rgb(0 0 0 / 8%);\n color: var(--lr-button-primary-text);\n}\n\n.lr-button--primary:hover:not(:disabled) {\n background: var(--lr-button-primary-bg-hover);\n}\n\n.lr-button--destructive {\n background: transparent;\n color: var(--lr-danger);\n}\n\n.lr-button--destructive:hover:not(:disabled) {\n background: var(--lr-danger-soft);\n}\n\n.lr-button:focus-visible,\n.lr-icon-button:focus-visible {\n box-shadow:\n 0 0 0 2px var(--lr-canvas),\n 0 0 0 4px var(--lr-focus);\n}\n\n.lr-button:disabled,\n.lr-icon-button:disabled {\n cursor: not-allowed;\n opacity: 0.48;\n}\n\n.lr-button.is-loading > .lr-icon:last-child {\n left: 50%;\n position: absolute;\n top: 50%;\n transform: translate(-50%, -50%);\n}\n\n.lr-button .is-visually-loading {\n visibility: hidden;\n}\n\n.lr-icon-button {\n aspect-ratio: 1;\n border-radius: var(--lr-radius-full);\n padding: 0;\n}\n\n.lr-icon-button > .lr-icon {\n height: 14px;\n width: 14px;\n}\n\n.lr-icon-button.lr-control--lg > .lr-icon {\n height: 16px;\n width: 16px;\n}\n\n.lr-badge,\n.lr-status {\n align-items: center;\n border-radius: var(--lr-radius-full);\n display: inline-flex;\n line-height: 1;\n white-space: nowrap;\n}\n\n.lr-badge {\n background: var(--lr-surface-inset);\n color: var(--lr-text-muted);\n font-size: var(--lr-font-xs);\n font-weight: var(--lr-weight-medium);\n min-height: 20px;\n padding: 0 var(--lr-space-2);\n}\n\n.lr-badge--accent {\n background: var(--lr-accent-soft);\n color: var(--lr-accent);\n}\n\n.lr-badge--success {\n background: var(--lr-success-soft);\n color: var(--lr-success);\n}\n\n.lr-badge--warning {\n background: var(--lr-warning-soft);\n color: var(--lr-warning);\n}\n\n.lr-badge--danger {\n background: var(--lr-danger-soft);\n color: var(--lr-danger);\n}\n\n.lr-badge--info {\n background: var(--lr-info-soft);\n color: var(--lr-info);\n}\n\n.lr-status {\n color: var(--lr-text-secondary);\n font-size: var(--lr-font-sm);\n font-weight: var(--lr-weight-semibold);\n gap: var(--lr-space-2);\n}\n\n.lr-status__icon {\n border: 1.5px solid currentColor;\n border-radius: var(--lr-radius-full);\n height: 9px;\n width: 9px;\n}\n\n.lr-status--ready {\n color: var(--lr-ready);\n}\n\n.lr-status--running {\n color: var(--lr-running);\n}\n\n.lr-status--running .lr-status__icon,\n.lr-status--complete .lr-status__icon {\n background: currentColor;\n box-shadow: inset 0 0 0 2px var(--lr-surface);\n}\n\n.lr-status--review {\n color: var(--lr-review);\n}\n\n.lr-status--waiting {\n color: var(--lr-waiting);\n}\n\n.lr-status--paused {\n color: var(--lr-paused);\n}\n\n.lr-status--complete {\n color: var(--lr-complete);\n}\n\n.lr-status--queued {\n color: var(--lr-queued);\n}\n\n.lr-avatar {\n align-items: center;\n background: var(--lr-surface-active);\n border-radius: var(--lr-radius-xs);\n color: var(--lr-text-muted);\n display: inline-flex;\n font-size: 9px;\n font-weight: var(--lr-weight-semibold);\n height: 20px;\n justify-content: center;\n line-height: 1;\n width: 20px;\n}\n\n.lr-avatar--accent {\n background: var(--lr-accent-soft);\n color: var(--lr-accent);\n}\n\n.lr-avatar--success {\n background: var(--lr-success-soft);\n color: var(--lr-success);\n}\n\n.lr-avatar--warning {\n background: var(--lr-warning-soft);\n color: var(--lr-warning);\n}\n\n.lr-skeleton {\n animation: lr-pulse 1.5s ease-in-out infinite;\n background: var(--lr-surface-active);\n border-radius: var(--lr-radius-xs);\n display: inline-block;\n height: 12px;\n max-width: 100%;\n}\n\n.lr-feedback {\n align-items: flex-start;\n color: var(--lr-text-secondary);\n display: flex;\n gap: var(--lr-space-3);\n padding: var(--lr-space-4);\n}\n\n.lr-feedback__icon {\n align-items: center;\n background: var(--lr-surface-inset);\n border-radius: var(--lr-radius-control);\n color: var(--lr-text-muted);\n display: inline-flex;\n height: 32px;\n justify-content: center;\n width: 32px;\n}\n\n.lr-feedback strong {\n color: var(--lr-text);\n display: block;\n font-size: var(--lr-font-base);\n}\n\n.lr-feedback p {\n color: var(--lr-text-muted);\n font-size: var(--lr-font-sm);\n line-height: 1.45;\n margin: var(--lr-space-1) 0 0;\n}\n\n.lr-feedback__action {\n margin-left: auto;\n}\n\n.lr-feedback--error .lr-feedback__icon {\n background: var(--lr-danger-soft);\n color: var(--lr-danger);\n}\n\n.lr-feedback--offline .lr-feedback__icon {\n background: var(--lr-warning-soft);\n color: var(--lr-warning);\n}\n\n.lr-feedback--success .lr-feedback__icon {\n background: var(--lr-success-soft);\n color: var(--lr-success);\n}\n\n.lr-kbd {\n align-items: center;\n background: color-mix(in srgb, var(--lr-surface-inset) 70%, transparent);\n border: 1px solid var(--lr-border-subtle);\n border-radius: 4px;\n color: var(--lr-text-faint);\n display: inline-flex;\n font-family: var(--lr-font-sans);\n font-size: 10px;\n font-weight: var(--lr-weight-normal);\n height: 18px;\n justify-content: center;\n line-height: 1;\n min-width: 18px;\n padding: 0 4px;\n}\n\n/* Forms */\n\n.lr-field {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.lr-field__label {\n color: var(--lr-text-secondary);\n font-size: var(--lr-font-sm);\n font-weight: var(--lr-weight-medium);\n line-height: 16px;\n margin-bottom: var(--lr-space-1-5);\n}\n\n.lr-field__description,\n.lr-field__error {\n align-items: center;\n align-self: flex-start;\n color: var(--lr-text-muted);\n display: flex;\n font-size: var(--lr-font-xs);\n gap: var(--lr-space-1);\n line-height: 14px;\n margin-top: 3px;\n min-height: 14px;\n}\n\n.lr-field__error {\n color: var(--lr-danger);\n}\n\n.lr-field__error .lr-icon {\n flex: 0 0 auto;\n}\n\n.lr-text-field {\n align-items: center;\n background: var(--lr-input-bg);\n border: 1px solid var(--lr-input-border);\n border-radius: var(--lr-control-radius);\n color: var(--lr-text-muted);\n display: flex;\n gap: var(--lr-space-2);\n padding: 0 var(--lr-space-2-5);\n transition:\n border-color var(--lr-duration-fast) var(--lr-ease-standard),\n box-shadow var(--lr-duration-fast) var(--lr-ease-standard);\n}\n\n.lr-text-field:hover:not(:focus-within) {\n border-color: var(--lr-border-strong);\n}\n\n.lr-text-field:focus-within,\n.lr-textarea:focus-visible {\n border-color: var(--lr-focus);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--lr-focus) 18%, transparent);\n outline: none;\n}\n\n.lr-text-field.has-error,\n.lr-textarea.has-error {\n border-color: var(--lr-danger);\n}\n\n.lr-text-field input {\n background: transparent;\n border: 0;\n color: var(--lr-text);\n font: inherit;\n font-size: var(--lr-font-base);\n height: 100%;\n min-width: 0;\n outline: 0;\n padding: 0;\n width: 100%;\n}\n\n.lr-text-field input::placeholder,\n.lr-textarea::placeholder {\n color: var(--lr-input-placeholder);\n}\n\n.lr-textarea {\n background: var(--lr-input-bg);\n border: 1px solid var(--lr-input-border);\n border-radius: var(--lr-control-radius);\n color: var(--lr-text);\n font: inherit;\n font-size: var(--lr-font-base);\n line-height: 1.5;\n min-height: 88px;\n padding: var(--lr-space-2-5) var(--lr-space-3);\n resize: vertical;\n transition:\n border-color var(--lr-duration-fast) var(--lr-ease-standard),\n box-shadow var(--lr-duration-fast) var(--lr-ease-standard);\n width: 100%;\n}\n\n.lr-check-row,\n.lr-radio-row,\n.lr-switch-row {\n color: var(--lr-text-secondary);\n cursor: pointer;\n display: flex;\n font-size: var(--lr-font-sm);\n gap: var(--lr-space-2);\n}\n\n.lr-check-row,\n.lr-radio-row {\n align-items: flex-start;\n}\n\n.lr-switch-row {\n align-items: center;\n justify-content: space-between;\n}\n\n.lr-check-row strong,\n.lr-radio-row strong,\n.lr-switch-row strong {\n display: block;\n font-size: var(--lr-font-sm);\n font-weight: var(--lr-weight-medium);\n line-height: 18px;\n}\n\n.lr-check-row small,\n.lr-radio-row small,\n.lr-switch-row small {\n color: var(--lr-text-muted);\n display: block;\n font-size: var(--lr-font-xs);\n line-height: 1.4;\n margin-top: 1px;\n}\n\n.lr-checkbox,\n.lr-radio {\n align-items: center;\n background: var(--lr-control-bg);\n border: 1px solid var(--lr-control-border);\n color: var(--lr-text-inverse);\n display: inline-flex;\n flex: 0 0 auto;\n height: 16px;\n justify-content: center;\n margin-top: 1px;\n outline: 0;\n padding: 0;\n transition:\n background-color var(--lr-duration-fast) var(--lr-ease-standard),\n border-color var(--lr-duration-fast) var(--lr-ease-standard),\n transform var(--lr-duration-fast) var(--lr-ease-standard);\n width: 16px;\n}\n\n.lr-checkbox {\n border-radius: 5px;\n}\n\n.lr-radio {\n border-radius: var(--lr-radius-full);\n}\n\n.lr-checkbox[data-state=\"checked\"] {\n background: var(--lr-accent);\n border-color: var(--lr-accent);\n}\n\n.lr-checkbox[data-state=\"checked\"] > span {\n animation: lr-check-in var(--lr-duration-fast) var(--lr-ease-standard);\n}\n\n.lr-radio__indicator {\n background: var(--lr-accent);\n border-radius: var(--lr-radius-full);\n display: block;\n height: 8px;\n transform: scale(0);\n transition: transform var(--lr-duration-fast) var(--lr-ease-standard);\n width: 8px;\n}\n\n.lr-radio[data-state=\"checked\"] {\n border-color: var(--lr-accent);\n}\n\n.lr-radio[data-state=\"checked\"] .lr-radio__indicator {\n transform: scale(1);\n}\n\n.lr-checkbox:focus-visible,\n.lr-radio:focus-visible,\n.lr-switch:focus-visible {\n box-shadow:\n 0 0 0 2px var(--lr-canvas),\n 0 0 0 4px var(--lr-focus);\n}\n\n.lr-radio-group {\n display: grid;\n gap: var(--lr-space-2-5);\n}\n\n.lr-switch {\n background: var(--lr-surface-active);\n border: 0;\n border-radius: var(--lr-radius-full);\n cursor: pointer;\n height: 18px;\n outline: 0;\n padding: 2px;\n transition: background-color var(--lr-duration-fast) var(--lr-ease-standard);\n width: 30px;\n}\n\n.lr-switch[data-state=\"checked\"] {\n background: var(--lr-accent);\n}\n\n.lr-switch__thumb {\n background: #fff;\n border-radius: var(--lr-radius-full);\n box-shadow: 0 1px 2px rgb(0 0 0 / 18%);\n display: block;\n height: 14px;\n transform: translateX(0);\n transition: transform 160ms var(--lr-ease-standard);\n width: 14px;\n}\n\n.lr-switch[data-state=\"checked\"] .lr-switch__thumb {\n transform: translateX(12px);\n}\n\n.lr-select-trigger {\n align-items: center;\n background: var(--lr-control-bg);\n border: 1px solid var(--lr-control-border);\n border-radius: var(--lr-control-radius);\n color: var(--lr-text-secondary);\n display: inline-flex;\n font: inherit;\n font-size: var(--lr-font-sm);\n gap: var(--lr-space-2);\n justify-content: space-between;\n min-width: 124px;\n outline: 0;\n padding: 0 var(--lr-space-2-5);\n transition:\n background-color var(--lr-duration-fast) var(--lr-ease-standard),\n border-color var(--lr-duration-fast) var(--lr-ease-standard),\n box-shadow var(--lr-duration-fast) var(--lr-ease-standard);\n}\n\n.lr-select-trigger:hover {\n background: var(--lr-control-bg-hover);\n border-color: var(--lr-border-strong);\n}\n\n.lr-select-trigger:focus-visible {\n border-color: var(--lr-focus);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--lr-focus) 18%, transparent);\n}\n\n.lr-select-trigger > span:last-child {\n align-items: center;\n display: inline-flex;\n justify-content: center;\n}\n\n.lr-select-trigger--compact {\n border: 0.5px solid transparent;\n box-shadow: var(--lr-compact-control-shadow);\n font-size: var(--lr-font-sm);\n justify-content: flex-start;\n min-width: 100px;\n padding: 1px 18px 1px 8px;\n position: relative;\n width: 100px;\n}\n\n.lr-select-trigger--compact > span:first-child {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.lr-select-trigger--compact > span:last-child {\n position: absolute;\n right: 5px;\n top: 50%;\n transform: translateY(-50%);\n}\n\n.lr-select-trigger--compact[data-state=\"open\"] {\n background: var(--lr-control-bg-hover);\n border-color: transparent;\n}\n\n.lr-select-trigger--compact:focus-visible {\n border-color: transparent;\n box-shadow:\n 0 0 0 2px var(--lr-popover-bg),\n 0 0 0 4px var(--lr-focus);\n}\n\n.lr-select-content {\n animation: lr-popover-in var(--lr-duration-fast) var(--lr-ease-standard);\n background: var(--lr-popover-bg);\n border: 0.5px solid var(--lr-popover-border);\n border-radius: var(--lr-popover-radius);\n box-shadow: var(--lr-shadow-popover);\n overflow: hidden;\n padding: var(--lr-space-1);\n z-index: 110;\n}\n\n.lr-select-content {\n max-height: var(--radix-select-content-available-height);\n max-width: calc(100vw - var(--lr-space-6));\n min-width: var(--radix-select-trigger-width);\n width: var(--radix-select-trigger-width);\n}\n\n.lr-select-content--compact {\n min-width: 136px;\n padding: var(--lr-space-1) 0;\n width: 136px;\n}\n\n.lr-select-content--compact .lr-select-item {\n border-radius: 0;\n font-size: var(--lr-font-sm);\n gap: var(--lr-space-2);\n min-height: var(--lr-size-control-sm);\n padding: 0 8px 0 12px;\n}\n\n.lr-select-viewport {\n width: 100%;\n}\n\n.lr-select-content[data-state=\"closed\"] {\n animation: lr-popover-out var(--lr-duration-instant) var(--lr-ease-standard);\n}\n\n.lr-select-item {\n align-items: center;\n background: transparent;\n border: 0;\n border-radius: 7px;\n color: var(--lr-text-secondary);\n cursor: default;\n display: grid;\n font: inherit;\n font-size: var(--lr-font-sm);\n gap: var(--lr-space-2);\n grid-template-columns: minmax(0, 1fr) 16px;\n min-height: var(--lr-size-row);\n outline: 0;\n padding: 0 var(--lr-space-2);\n position: relative;\n text-align: left;\n user-select: none;\n width: 100%;\n}\n\n.lr-select-item[data-highlighted] {\n background: var(--lr-popover-item-hover);\n color: var(--lr-text);\n}\n\n.lr-select-item[data-disabled] {\n opacity: 0.45;\n}\n\n.lr-select-item__copy {\n display: grid;\n min-width: 0;\n}\n\n.lr-select-item__copy > span {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.lr-select-item:has(.lr-select-item__copy small) {\n min-height: 44px;\n padding-bottom: var(--lr-space-1-5);\n padding-top: var(--lr-space-1-5);\n}\n\n.lr-select-item__copy > span {\n color: var(--lr-text);\n font-weight: var(--lr-weight-normal);\n line-height: 1.35;\n}\n\n.lr-select-item[data-state=\"checked\"] .lr-select-item__copy > span {\n font-weight: var(--lr-weight-medium);\n}\n\n.lr-select-item__indicator {\n align-items: center;\n display: inline-flex;\n justify-content: center;\n justify-self: end;\n}\n\n.lr-select-item small {\n color: var(--lr-text-muted);\n font-size: var(--lr-font-xs);\n font-weight: var(--lr-weight-normal);\n line-height: 1.35;\n margin-top: 1px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Menus, popovers, dialogs and navigation controls */\n\n.lr-tooltip {\n animation: lr-tooltip-in var(--lr-duration-fast) var(--lr-ease-standard);\n background: var(--lr-text);\n border-radius: 6px;\n color: var(--lr-canvas);\n font-size: var(--lr-font-xs);\n line-height: 1;\n padding: 6px 8px;\n /* A tooltip is a label, never a target: it must not swallow clicks on the control beneath it. */\n pointer-events: none;\n z-index: 120;\n}\n\n/* The positioning wrapper is generated by the overlay primitive and is opaque to pointer events by\n default, so it has to be neutralised alongside the tooltip it carries. */\n[data-radix-popper-content-wrapper]:has(> .lr-tooltip) {\n pointer-events: none;\n}\n\n.lr-tooltip__arrow {\n fill: var(--lr-text);\n}\n\n.lr-menu,\n.lr-popover {\n animation: lr-popover-in var(--lr-duration-fast) var(--lr-ease-standard);\n background: var(--lr-popover-bg);\n border: 0.5px solid var(--lr-popover-border);\n border-radius: var(--lr-popover-radius);\n box-shadow: var(--lr-shadow-popover);\n color: var(--lr-text-secondary);\n outline: 0;\n padding: var(--lr-space-1);\n z-index: 90;\n}\n\n.lr-menu[data-state=\"closed\"],\n.lr-popover[data-state=\"closed\"] {\n animation: lr-popover-out var(--lr-duration-instant) var(--lr-ease-standard);\n}\n\n.lr-menu {\n min-width: 216px;\n}\n\n.lr-menu__group {\n display: grid;\n}\n\n.lr-menu__item {\n align-items: center;\n border-radius: 7px;\n cursor: default;\n display: grid;\n font-size: var(--lr-font-sm);\n gap: var(--lr-space-2);\n grid-template-columns: minmax(0, 1fr) auto;\n min-height: var(--lr-size-row);\n outline: none;\n padding: 0 var(--lr-space-2);\n user-select: none;\n}\n\n.lr-menu__item.has-icon {\n grid-template-columns: 16px minmax(0, 1fr) auto;\n}\n\n.lr-menu__item[data-highlighted] {\n background: var(--lr-popover-item-hover);\n color: var(--lr-text);\n}\n\n.lr-menu__item.is-danger {\n color: var(--lr-danger);\n}\n\n.lr-menu__item.is-danger[data-highlighted] {\n background: var(--lr-danger-soft);\n color: var(--lr-danger);\n}\n\n.lr-menu__item[data-disabled] {\n opacity: 0.42;\n}\n\n.lr-menu__item-icon {\n align-items: center;\n display: inline-flex;\n height: 16px;\n justify-content: center;\n width: 16px;\n}\n\n.lr-menu__separator {\n background: var(--lr-border-subtle);\n height: 1px;\n margin: var(--lr-space-1) calc(var(--lr-space-1) * -1);\n}\n\n.lr-popover {\n min-width: 280px;\n}\n\n.lr-dialog-overlay {\n animation: lr-overlay-in 160ms var(--lr-ease-standard);\n background: var(--lr-overlay-bg);\n inset: 0;\n position: fixed;\n z-index: 100;\n}\n\n.lr-dialog-overlay[data-state=\"closed\"] {\n animation: lr-overlay-out 110ms var(--lr-ease-standard);\n}\n\n.lr-dialog {\n animation: lr-dialog-in 180ms var(--lr-ease-standard);\n background: var(--lr-surface-raised);\n border: 1px solid var(--lr-border);\n border-radius: var(--lr-dialog-radius);\n box-shadow: var(--lr-shadow-dialog);\n color: var(--lr-text);\n display: flex;\n flex-direction: column;\n left: 50%;\n max-height: min(760px, calc(100vh - 48px));\n max-width: calc(100vw - 32px);\n outline: none;\n overflow: hidden;\n position: fixed;\n top: 50%;\n transform: translate(-50%, -50%);\n width: min(100%, 620px);\n z-index: 101;\n}\n\n.lr-dialog[data-state=\"closed\"] {\n animation: lr-dialog-out 110ms var(--lr-ease-standard);\n}\n\n.lr-dialog--sm {\n width: min(100%, 440px);\n}\n\n.lr-dialog--lg {\n width: min(100%, 920px);\n}\n\n.lr-dialog__header {\n align-items: flex-start;\n border-bottom: 1px solid var(--lr-border-subtle);\n display: flex;\n gap: var(--lr-space-4);\n justify-content: space-between;\n min-height: 62px;\n padding: var(--lr-space-4) var(--lr-space-5);\n}\n\n.lr-dialog__header h2 {\n font-size: var(--lr-font-md);\n font-weight: var(--lr-weight-semibold);\n line-height: 1.35;\n margin: 0;\n}\n\n.lr-dialog__header p {\n color: var(--lr-text-muted);\n font-size: var(--lr-font-sm);\n line-height: 1.45;\n margin: var(--lr-space-1) 0 0;\n}\n\n.lr-dialog__body {\n flex: 1;\n overflow: auto;\n padding: var(--lr-space-5);\n}\n\n.lr-dialog__footer {\n align-items: center;\n border-top: 1px solid var(--lr-border-subtle);\n display: flex;\n gap: var(--lr-space-2);\n justify-content: flex-end;\n min-height: 58px;\n padding: var(--lr-space-3) var(--lr-space-5);\n}\n\n/* Cascading task filters */\n\n.lr-visually-hidden {\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n height: 1px;\n overflow: hidden;\n position: absolute;\n white-space: nowrap;\n width: 1px;\n}\n\n.lr-filter-popover {\n animation: lr-popover-in var(--lr-duration-fast) var(--lr-ease-standard);\n background: var(--lr-popover-bg);\n border: 0.5px solid var(--lr-popover-border);\n border-radius: var(--lr-popover-radius);\n box-shadow: var(--lr-shadow-popover);\n color: var(--lr-text-secondary);\n max-width: calc(100vw - 16px);\n outline: 0;\n overflow: visible;\n position: relative;\n transform-origin: var(--radix-popover-content-transform-origin);\n width: 191px;\n z-index: 95;\n}\n\n.lr-filter-popover[data-state=\"closed\"] {\n animation: lr-popover-out var(--lr-duration-instant) var(--lr-ease-standard);\n}\n\n.lr-filter-main-panel {\n border-radius: inherit;\n overflow: hidden;\n}\n\n.lr-filter-main-panel .lr-filter-level {\n width: 190px;\n}\n\n.lr-filter-submenus {\n inset: 0;\n pointer-events: none;\n position: absolute;\n z-index: 0;\n}\n\n.lr-filter-level {\n display: flex;\n flex-direction: column;\n max-height: min(707px, calc(100vh - 112px));\n min-height: 0;\n min-width: 0;\n width: 200px;\n}\n\n.lr-filter-submenus .lr-filter-level {\n animation: lr-filter-panel-in var(--lr-duration-fast) var(--lr-ease-standard);\n background: var(--lr-popover-bg);\n border: 0.5px solid var(--lr-popover-border);\n border-radius: var(--lr-popover-radius);\n box-shadow:\n 0 9px 48px rgb(0 0 0 / 8%),\n 0 6px 24px rgb(0 0 0 / 10%),\n 0 1px 1px rgb(0 0 0 / 4%);\n overflow: hidden;\n pointer-events: auto;\n position: absolute;\n transition:\n height var(--lr-duration-fast) var(--lr-ease-standard),\n top var(--lr-duration-fast) var(--lr-ease-standard);\n width: 200px;\n}\n\n.lr-filter-search {\n border-bottom: 0.5px solid var(--lr-popover-border);\n color: var(--lr-text-faint);\n display: block;\n flex: 0 0 auto;\n min-height: 37px;\n padding: 0 12px 0 14px;\n}\n\n.lr-filter-search:focus-within {\n color: var(--lr-text-muted);\n}\n\n.lr-filter-search input {\n appearance: none;\n background: transparent;\n border: 0;\n color: var(--lr-text);\n font: inherit;\n font-size: var(--lr-font-base);\n height: 36px;\n line-height: 18px;\n min-width: 0;\n outline: 0;\n padding: 10px 0 9px;\n width: 100%;\n}\n\n.lr-filter-search input::placeholder {\n color: var(--lr-text-faint);\n}\n\n.lr-filter-search input::-webkit-search-cancel-button {\n appearance: none;\n}\n\n.lr-filter-list {\n display: grid;\n flex: 0 1 auto;\n grid-auto-rows: max-content;\n max-height: 668px;\n overflow-y: auto;\n overscroll-behavior: contain;\n padding: 6px 0;\n}\n\n.lr-filter-separator {\n height: 12px;\n position: relative;\n}\n\n.lr-filter-separator::after {\n background: var(--lr-popover-border);\n content: \"\";\n height: 0.5px;\n inset: 5.75px 0 auto;\n position: absolute;\n}\n\n.lr-filter-item {\n align-items: center;\n background: transparent;\n border: 0;\n border-radius: 0;\n color: var(--lr-text-secondary);\n display: grid;\n font: inherit;\n font-size: var(--lr-font-base);\n gap: var(--lr-space-2);\n grid-template-columns: 17px minmax(0, 1fr) auto;\n line-height: 19.5px;\n min-height: 32px;\n outline: 0;\n padding: 0 18px 0 14px;\n text-align: left;\n transition:\n background-color var(--lr-duration-instant) var(--lr-ease-standard),\n color var(--lr-duration-instant) var(--lr-ease-standard);\n width: 100%;\n}\n\n.lr-filter-choice {\n border-radius: 0;\n display: grid;\n grid-template-columns: 22px minmax(0, 1fr);\n min-height: 32px;\n padding: 0 18px 0 14px;\n transition:\n background-color var(--lr-duration-fast) var(--lr-ease-standard),\n color var(--lr-duration-fast) var(--lr-ease-standard);\n}\n\n.lr-filter-choice:hover,\n.lr-filter-choice:has(.lr-filter-choice__checkbox:focus-visible) {\n background: var(--lr-popover-item-hover);\n color: var(--lr-text);\n}\n\n.lr-filter-choice:has(.lr-filter-choice__checkbox[aria-pressed=\"true\"]):hover,\n.lr-filter-choice:has(.lr-filter-choice__checkbox[aria-pressed=\"true\"]):has(\n .lr-filter-choice__checkbox:focus-visible\n ) {\n background: transparent;\n}\n\n.lr-filter-choice__checkbox {\n align-items: center;\n align-self: center;\n background: transparent;\n border: 1px solid var(--lr-border);\n border-radius: 3px;\n color: var(--lr-text-inverse);\n display: inline-flex;\n height: 12px;\n justify-content: center;\n justify-self: start;\n margin-left: 2px;\n outline: 0;\n padding: 0;\n transition:\n background-color var(--lr-duration-fast) var(--lr-ease-standard),\n border-color var(--lr-duration-fast) var(--lr-ease-standard),\n box-shadow var(--lr-duration-fast) var(--lr-ease-standard);\n width: 12px;\n}\n\n.lr-filter-choice__checkbox:hover {\n border-color: var(--lr-text-faint);\n}\n\n.lr-filter-choice__checkbox[aria-pressed=\"true\"] {\n background: var(--lr-accent);\n border-color: var(--lr-accent);\n color: var(--lr-text-inverse);\n}\n\n.lr-filter-choice__checkbox[aria-pressed=\"true\"] svg {\n color: var(--lr-text-inverse);\n stroke: currentColor;\n}\n\n.lr-filter-choice__checkbox:focus-visible {\n box-shadow:\n 0 0 0 2px var(--lr-popover-bg),\n 0 0 0 4px var(--lr-focus);\n}\n\n.lr-filter-item--choice {\n background: transparent !important;\n grid-template-columns: minmax(0, 1fr) auto;\n padding: 0;\n}\n\n.lr-filter-item:has(.lr-filter-item__copy small),\n.lr-filter-choice:has(.lr-filter-item__copy small) {\n min-height: 46px;\n}\n\n.lr-filter-item:hover,\n.lr-filter-item[data-active=\"true\"],\n.lr-filter-item:focus-visible {\n background: var(--lr-popover-item-hover);\n color: var(--lr-text);\n}\n\n.lr-filter-item:focus-visible {\n box-shadow: inset 0 0 0 2px var(--lr-focus);\n}\n\n.lr-filter-item__icon,\n.lr-filter-item__meta {\n align-items: center;\n color: var(--lr-text-faint);\n display: inline-flex;\n justify-content: center;\n}\n\n.lr-filter-item__copy {\n display: grid;\n gap: 1px;\n min-width: 0;\n}\n\n.lr-filter-item__copy > span,\n.lr-filter-item__copy small {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.lr-filter-item__context {\n color: var(--lr-text-faint);\n}\n\n.lr-filter-item__context::after {\n content: \"\\2009\\203A\\2009\";\n}\n\n.lr-filter-item__copy small,\n.lr-filter-item__meta small {\n color: var(--lr-text-faint);\n font-size: var(--lr-font-xs);\n font-weight: var(--lr-weight-regular);\n}\n\n.lr-filter-item__meta {\n gap: var(--lr-space-1-5);\n min-width: 16px;\n}\n\n.lr-filter-empty {\n color: var(--lr-text-faint);\n font-size: var(--lr-font-sm);\n line-height: 1.45;\n margin: 0;\n padding: var(--lr-space-4) var(--lr-space-3);\n text-align: center;\n}\n\n.lr-filter-dialog {\n animation: lr-filter-fade-in 100ms ease-out;\n background: var(--lr-canvas);\n color: var(--lr-text);\n display: flex;\n flex-direction: column;\n height: 100dvh;\n inset: 0;\n outline: 0;\n position: fixed;\n width: 100vw;\n z-index: 101;\n}\n\n.lr-filter-dialog[data-state=\"closed\"] {\n animation: lr-filter-fade-out 70ms ease-in;\n}\n\n.lr-filter-dialog__header {\n align-items: center;\n background: var(--lr-surface);\n border-bottom: 1px solid var(--lr-border-subtle);\n display: flex;\n flex: 0 0 auto;\n justify-content: space-between;\n min-height: calc(52px + env(safe-area-inset-top));\n padding: env(safe-area-inset-top) var(--lr-space-3) 0;\n}\n\n.lr-filter-dialog__heading {\n align-items: center;\n display: flex;\n gap: var(--lr-space-2);\n min-width: 0;\n}\n\n.lr-filter-dialog__heading h2 {\n font-size: 16px;\n font-weight: var(--lr-weight-semibold);\n margin: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.lr-filter-dialog__body {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n.lr-filter-level--mobile {\n flex: 1;\n max-height: none;\n min-height: 0;\n width: 100%;\n}\n\n.lr-filter-level--mobile .lr-filter-search {\n background: var(--lr-surface-inset);\n border: 1px solid var(--lr-border);\n border-radius: var(--lr-radius-control);\n margin: var(--lr-space-3);\n min-height: 42px;\n padding: 0 var(--lr-space-3);\n}\n\n.lr-filter-level--mobile .lr-filter-search input {\n height: 40px;\n font-size: 16px;\n padding: 0;\n}\n\n.lr-filter-level--mobile .lr-filter-list {\n flex: 1;\n max-height: none;\n padding: 0 var(--lr-space-2) var(--lr-space-4);\n}\n\n.lr-filter-level--mobile .lr-filter-item {\n border-radius: var(--lr-radius-control);\n font-size: 15px;\n min-height: 46px;\n padding: var(--lr-space-2) var(--lr-space-3);\n}\n\n.lr-filter-level--mobile .lr-filter-choice {\n border-radius: var(--lr-radius-control);\n grid-template-columns: 42px minmax(0, 1fr);\n min-height: 46px;\n padding: 0 var(--lr-space-3);\n}\n\n.lr-filter-level--mobile .lr-filter-choice__checkbox {\n height: 18px;\n justify-self: center;\n margin-left: 0;\n width: 18px;\n}\n\n.lr-filter-level--mobile .lr-filter-choice .lr-filter-item,\n.lr-filter-level--mobile .lr-filter-item--choice {\n padding: 0;\n}\n\n.lr-filter-level--mobile .lr-filter-item__copy small,\n.lr-filter-level--mobile .lr-filter-item__meta small {\n font-size: 12px;\n}\n\n/* Applied filter conditions */\n\n.lr-applied-filter-bar {\n align-items: center;\n display: flex;\n gap: 10px;\n justify-content: space-between;\n min-width: 0;\n}\n\n.lr-applied-filter-bar__conditions {\n align-items: center;\n display: flex;\n flex: 1;\n gap: var(--lr-space-1);\n min-width: 0;\n overflow-x: auto;\n scrollbar-width: none;\n}\n\n.lr-applied-filter-bar__conditions::-webkit-scrollbar {\n display: none;\n}\n\n.lr-applied-filter {\n align-items: stretch;\n background: var(--lr-surface);\n border: 0.5px solid var(--lr-border);\n border-radius: 8px;\n display: inline-flex;\n flex: 0 0 auto;\n height: 24px;\n min-height: 24px;\n overflow: hidden;\n}\n\n.lr-applied-filter__editor,\n.lr-applied-filter__remove {\n background: transparent;\n border: 0;\n color: var(--lr-text-secondary);\n font: inherit;\n outline: 0;\n}\n\n.lr-applied-filter__editor {\n align-items: stretch;\n display: inline-flex;\n padding: 0;\n}\n\n.lr-applied-filter__editor:hover,\n.lr-applied-filter__editor:focus-visible,\n.lr-applied-filter__remove:hover,\n.lr-applied-filter__remove:focus-visible {\n background: var(--lr-surface-hover);\n color: var(--lr-text);\n}\n\n.lr-applied-filter__editor:focus-visible,\n.lr-applied-filter__remove:focus-visible {\n box-shadow: inset 0 0 0 2px var(--lr-focus);\n}\n\n.lr-applied-filter__property,\n.lr-applied-filter__operator,\n.lr-applied-filter__value {\n align-items: center;\n border-right: 0.5px solid var(--lr-border);\n display: inline-flex;\n font-size: var(--lr-font-sm);\n gap: var(--lr-space-1);\n padding: 0 6px;\n white-space: nowrap;\n}\n\n.lr-applied-filter__property {\n color: var(--lr-text-secondary);\n font-weight: var(--lr-weight-normal);\n}\n\n.lr-applied-filter__operator {\n color: var(--lr-text-muted);\n}\n\n.lr-applied-filter__value {\n color: var(--lr-text-secondary);\n}\n\n.lr-applied-filter__remove {\n align-items: center;\n display: inline-flex;\n justify-content: center;\n padding: 0;\n width: 24px;\n}\n\n.lr-applied-filter-bar__add {\n align-items: center;\n display: inline-flex;\n flex: 0 0 auto;\n}\n\n.lr-applied-filter-bar__clear {\n flex: 0 0 auto;\n}\n\n.lr-applied-filter-popover {\n animation: lr-filter-fade-in 90ms ease-out;\n background: var(--lr-popover-bg);\n border: 0.5px solid var(--lr-popover-border);\n border-radius: var(--lr-popover-radius);\n box-shadow: var(--lr-shadow-popover);\n color: var(--lr-text-secondary);\n max-height: min(360px, calc(100vh - 24px));\n outline: 0;\n overflow: hidden;\n transform-origin: var(--radix-popover-content-transform-origin);\n width: 200px;\n z-index: 96;\n}\n\n.lr-applied-filter-popover[data-state=\"closed\"] {\n animation: lr-filter-fade-out 60ms ease-in;\n}\n\n.lr-applied-filter-popover__search {\n border-bottom-color: var(--lr-border-subtle);\n}\n\n@media (max-width: 760px) {\n .lr-applied-filter-popover {\n max-width: calc(100vw - 24px);\n width: 300px;\n }\n}\n\n/* Workflow patterns */\n\n.lr-task-card {\n background: var(--lr-card-bg);\n border: 1px solid var(--lr-card-border);\n border-radius: var(--lr-card-radius);\n color: var(--lr-text-secondary);\n cursor: default;\n display: grid;\n gap: var(--lr-density-card-gap);\n padding: var(--lr-density-card-padding);\n transition:\n background-color var(--lr-duration-fast) var(--lr-ease-standard),\n border-color var(--lr-duration-fast) var(--lr-ease-standard),\n box-shadow var(--lr-duration-fast) var(--lr-ease-standard);\n}\n\n.lr-task-card:hover {\n border-color: var(--lr-border);\n box-shadow: 0 2px 8px rgb(0 0 0 / 5%);\n}\n\n.lr-task-card.is-selected {\n border-color: color-mix(in srgb, var(--lr-accent) 65%, var(--lr-border));\n box-shadow: 0 0 0 1px color-mix(in srgb, var(--lr-accent) 22%, transparent);\n}\n\n.lr-task-card.is-selected {\n background: color-mix(in srgb, var(--lr-accent-soft) 36%, var(--lr-surface));\n}\n\n.lr-task-card__header,\n.lr-task-card footer {\n align-items: center;\n display: flex;\n justify-content: space-between;\n}\n\n.lr-task-card__header > span:first-child {\n color: var(--lr-text-faint);\n font-family: var(--lr-font-mono);\n font-size: var(--lr-font-xs);\n}\n\n.lr-task-card__title {\n color: var(--lr-text);\n font-size: var(--lr-font-base);\n font-weight: var(--lr-weight-semibold);\n line-height: 1.35;\n}\n\n.lr-task-card p {\n color: var(--lr-text-muted);\n font-size: var(--lr-font-sm);\n line-height: 1.4;\n margin: -2px 0 0;\n}\n\n.lr-task-card footer {\n color: var(--lr-text-faint);\n font-size: var(--lr-font-xs);\n min-height: 20px;\n}\n\n.lr-task-card__agent {\n align-items: center;\n display: inline-flex;\n gap: var(--lr-space-2);\n}\n\n.lr-task-card__live {\n color: var(--lr-accent);\n}\n\n.lr-kanban-column {\n min-width: 0;\n}\n\n.lr-kanban-column > header {\n align-items: center;\n display: grid;\n gap: var(--lr-space-2);\n grid-template-columns: auto auto 1fr;\n min-height: 34px;\n padding: 0 var(--lr-space-1);\n}\n\n.lr-kanban-column__count {\n color: var(--lr-text-faint);\n font-size: var(--lr-font-xs);\n}\n\n.lr-kanban-column__add {\n justify-self: end;\n min-width: var(--lr-size-control-sm);\n padding: 0;\n}\n\n.lr-kanban-column__stack {\n display: grid;\n gap: var(--lr-density-stack-gap);\n}\n\n.lr-timeline-event {\n align-items: center;\n display: grid;\n gap: var(--lr-space-2);\n grid-template-columns: auto minmax(0, 1fr) auto;\n min-height: 30px;\n}\n\n.lr-timeline-event__icon {\n align-items: center;\n background: var(--lr-surface-inset);\n border-radius: var(--lr-radius-full);\n color: var(--lr-text-muted);\n display: inline-flex;\n height: 20px;\n justify-content: center;\n width: 20px;\n}\n\n.lr-timeline-event--accent .lr-timeline-event__icon {\n background: var(--lr-accent-soft);\n color: var(--lr-accent);\n}\n\n.lr-timeline-event--success .lr-timeline-event__icon {\n background: var(--lr-success-soft);\n color: var(--lr-success);\n}\n\n.lr-timeline-event--warning .lr-timeline-event__icon {\n background: var(--lr-warning-soft);\n color: var(--lr-warning);\n}\n\n.lr-timeline-event > div {\n display: grid;\n gap: 2px;\n min-width: 0;\n}\n\n.lr-timeline-event strong {\n color: var(--lr-text-secondary);\n font-size: var(--lr-font-sm);\n font-weight: var(--lr-weight-medium);\n}\n\n.lr-timeline-event > div span,\n.lr-timeline-event time {\n color: var(--lr-text-faint);\n font-size: var(--lr-font-xs);\n}\n\n.lr-timeline-event time {\n align-self: center;\n}\n\n.lr-inspector-section {\n padding: var(--lr-space-4);\n position: relative;\n}\n\n/* The rule is drawn inset so that it lines up with the content rather than running past it, and the\n last section drops it because there is nothing below to separate from. */\n.lr-inspector-section::after {\n background: var(--lr-border-subtle);\n bottom: 0;\n content: \"\";\n height: 1px;\n left: var(--lr-space-4);\n position: absolute;\n right: var(--lr-space-4);\n}\n\n.lr-inspector-section:last-of-type::after {\n content: none;\n}\n\n.lr-inspector-section > header {\n align-items: center;\n display: flex;\n justify-content: space-between;\n margin-bottom: var(--lr-space-3);\n}\n\n.lr-inspector-section > header > strong {\n color: var(--lr-text);\n font-size: var(--lr-font-sm);\n font-weight: var(--lr-weight-semibold);\n}\n\n.lr-inspector-section__body {\n display: grid;\n gap: var(--lr-space-3);\n}\n\n.lr-run-summary {\n display: grid;\n /* Rows sit closer than columns so each label reads as attached to its own value. */\n gap: var(--lr-space-2-5) var(--lr-space-3);\n grid-template-columns: repeat(2, minmax(0, 1fr));\n margin: 0;\n}\n\n.lr-run-summary div {\n display: grid;\n gap: 4px;\n}\n\n.lr-run-summary dt {\n color: var(--lr-text-faint);\n font-size: var(--lr-font-xs);\n}\n\n.lr-run-summary dd {\n color: var(--lr-text-secondary);\n font-size: var(--lr-font-sm);\n font-weight: var(--lr-weight-medium);\n margin: 0;\n}\n\n.lr-session-timeline-panel {\n display: grid;\n gap: var(--lr-space-2-5);\n}\n\n.lr-session-timeline-panel__title {\n color: var(--lr-text);\n font-size: var(--lr-font-sm);\n font-weight: var(--lr-weight-semibold);\n}\n\n.lr-session-timeline-panel__subtitle {\n color: var(--lr-text-muted);\n font-size: var(--lr-font-xs);\n font-weight: var(--lr-weight-medium);\n}\n\n.lr-session-timeline-panel__note {\n color: var(--lr-text-muted);\n font-size: var(--lr-font-xs);\n margin: 0;\n}\n\n.lr-session-timeline {\n display: grid;\n gap: var(--lr-space-3);\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n.lr-session-timeline__item {\n display: grid;\n gap: var(--lr-space-2);\n grid-template-columns: auto minmax(0, 1fr);\n}\n\n.lr-session-timeline__ordinal {\n align-items: center;\n background: var(--lr-surface-inset);\n border-radius: var(--lr-radius-full);\n color: var(--lr-text-muted);\n display: inline-flex;\n font-size: var(--lr-font-xs);\n font-weight: var(--lr-weight-medium);\n height: 20px;\n justify-content: center;\n width: 20px;\n}\n\n.lr-session-timeline__body {\n display: grid;\n gap: var(--lr-space-2);\n min-width: 0;\n}\n\n.lr-session-timeline__row {\n align-items: center;\n display: flex;\n flex-wrap: wrap;\n gap: var(--lr-space-2);\n}\n\n.lr-session-timeline__occupancy {\n align-items: center;\n display: grid;\n gap: var(--lr-space-1);\n grid-template-columns: minmax(80px, 160px) auto;\n}\n\n.lr-session-timeline__occupancy progress {\n appearance: none;\n block-size: 5px;\n border: none;\n border-radius: var(--lr-radius-full);\n inline-size: 100%;\n}\n\n.lr-session-timeline__occupancy progress::-webkit-progress-bar {\n background: var(--lr-surface-inset);\n border-radius: var(--lr-radius-full);\n}\n\n.lr-session-timeline__occupancy progress::-webkit-progress-value,\n.lr-session-timeline__occupancy progress::-moz-progress-bar {\n background: var(--lr-warning);\n border-radius: var(--lr-radius-full);\n}\n\n.lr-session-timeline__occupancy span {\n color: var(--lr-text-faint);\n font-size: var(--lr-font-xs);\n}\n\n.lr-session-timeline__occupancy-text {\n display: flex;\n flex-wrap: wrap;\n gap: var(--lr-space-1);\n margin: 0;\n}\n\n/* Spec §4.3/§5.2: the occupancy figure means different things measured and estimated, so the\n qualifier travels with the number rather than being dropped. Not colour-coded -- it is a\n provenance note, not a status. */\n.lr-session-timeline__occupancy .lr-session-timeline__occupancy-quality {\n color: var(--lr-text-muted);\n font-size: var(--lr-font-xs);\n}\n\n.lr-session-timeline__checkpoints {\n display: grid;\n gap: var(--lr-space-2);\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n.lr-session-timeline__empty {\n color: var(--lr-text-faint);\n font-size: var(--lr-font-xs);\n margin: 0;\n}\n\n.lr-checkpoint-card {\n background: var(--lr-surface-inset);\n border-radius: var(--lr-radius-control);\n padding: var(--lr-space-2) var(--lr-space-2-5);\n}\n\n.lr-checkpoint-card > summary {\n align-items: center;\n cursor: pointer;\n display: flex;\n gap: var(--lr-space-2);\n list-style: none;\n}\n\n.lr-checkpoint-card > summary::-webkit-details-marker {\n display: none;\n}\n\n/* The only persistent (non-hover) sign a collapsed checkpoint is openable: without it a closed\n card reads as a plain line of grey text. Rotates via the native [open] attribute -- no JS. */\n.lr-checkpoint-card__chevron {\n color: var(--lr-text-faint);\n flex-shrink: 0;\n transform: rotate(0deg);\n transition: transform var(--lr-duration-fast) var(--lr-ease-standard);\n}\n\n.lr-checkpoint-card[open] > summary > .lr-checkpoint-card__chevron {\n transform: rotate(90deg);\n}\n\n.lr-checkpoint-card > summary > span {\n color: var(--lr-text-secondary);\n flex: 1;\n font-size: var(--lr-font-sm);\n font-weight: var(--lr-weight-medium);\n}\n\n.lr-checkpoint-card > summary > time {\n color: var(--lr-text-faint);\n flex-shrink: 0;\n font-size: var(--lr-font-xs);\n}\n\n/* The card's only focusable descendant is its <summary>, which already draws a ring. `:focus-within`\n put a second one around the whole card, and fired on a mouse click as well -- unlike every\n comparable rule in this file, which uses `:focus-visible`. One ring, on the focused element, for\n keyboard focus. */\n.lr-checkpoint-card > summary:focus-visible {\n outline: 2px solid var(--lr-focus);\n outline-offset: 2px;\n}\n\n.lr-checkpoint-card__body {\n display: grid;\n gap: var(--lr-space-2);\n margin-top: var(--lr-space-2);\n}\n\n.lr-checkpoint-card__body strong {\n color: var(--lr-text-muted);\n font-size: var(--lr-font-xs);\n font-weight: var(--lr-weight-medium);\n}\n\n.lr-checkpoint-card__body ul {\n color: var(--lr-text-secondary);\n display: grid;\n font-size: var(--lr-font-xs);\n gap: 2px;\n margin: 2px 0 0;\n padding-left: var(--lr-space-4);\n}\n\n@keyframes lr-spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n@keyframes lr-pulse {\n 50% {\n opacity: 0.55;\n }\n}\n\n@keyframes lr-check-in {\n from {\n opacity: 0;\n transform: scale(0.7);\n }\n}\n\n@keyframes lr-tooltip-in {\n from {\n opacity: 0;\n transform: translateY(2px) scale(0.98);\n }\n}\n\n@keyframes lr-popover-in {\n from {\n opacity: 0;\n transform: translateY(-3px) scale(0.985);\n }\n}\n\n@keyframes lr-popover-out {\n to {\n opacity: 0;\n transform: translateY(-2px) scale(0.99);\n }\n}\n\n@keyframes lr-filter-fade-in {\n from {\n opacity: 0;\n }\n}\n\n@keyframes lr-filter-fade-out {\n to {\n opacity: 0;\n }\n}\n\n@keyframes lr-filter-panel-in {\n from {\n opacity: 0.72;\n transform: translateX(4px) scale(0.99);\n }\n}\n\n@keyframes lr-overlay-in {\n from {\n opacity: 0;\n }\n}\n\n@keyframes lr-overlay-out {\n to {\n opacity: 0;\n }\n}\n\n@keyframes lr-dialog-in {\n from {\n opacity: 0;\n transform: translate(-50%, calc(-50% + 8px)) scale(0.985);\n }\n}\n\n@keyframes lr-dialog-out {\n to {\n opacity: 0;\n transform: translate(-50%, calc(-50% + 4px)) scale(0.99);\n }\n}\n\n@keyframes lr-filter-dialog-in {\n from {\n opacity: 0;\n transform: translateX(12px);\n }\n}\n\n@keyframes lr-filter-dialog-out {\n to {\n opacity: 0;\n transform: translateX(8px);\n }\n}\n\n@media (max-width: 680px) {\n .lr-dialog {\n border-radius: var(--lr-radius-shell) var(--lr-radius-shell) 0 0;\n bottom: 0;\n left: 0;\n max-height: calc(100vh - 20px);\n max-width: none;\n top: auto;\n transform: none;\n width: 100%;\n }\n\n .lr-filter-dialog {\n border-radius: 0;\n }\n\n .lr-dialog__header,\n .lr-dialog__body,\n .lr-dialog__footer {\n padding-left: var(--lr-space-4);\n padding-right: var(--lr-space-4);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .lr-icon--spinner,\n .lr-skeleton,\n .lr-select-content,\n .lr-tooltip,\n .lr-menu,\n .lr-popover,\n .lr-filter-popover,\n .lr-filter-submenus .lr-filter-level,\n .lr-filter-dialog,\n .lr-applied-filter-popover,\n .lr-dialog-overlay,\n .lr-dialog {\n animation-duration: 1ms !important;\n animation-iteration-count: 1 !important;\n }\n\n .lr-button,\n .lr-icon-button,\n .lr-select-trigger,\n .lr-checkbox,\n .lr-radio__indicator,\n .lr-switch,\n .lr-switch__thumb,\n .lr-task-card,\n .lr-filter-item,\n .lr-filter-choice,\n .lr-filter-submenus .lr-filter-level {\n transition-duration: 1ms !important;\n }\n}\n","import type { WorkItem, WorkItemState } from \"@loomrail/contracts\";\n\n/**\n * How cards are ordered inside a delivery column.\n *\n * The board itself is always grouped by delivery state: the columns are the accountable route a\n * WorkItem travels, not an arbitrary axis. Only the order within a column is a view preference.\n */\nexport type BoardOrdering = \"priority\" | \"created\" | \"updated\" | \"title\";\nexport type BoardDirection = \"asc\" | \"desc\";\n\nexport type BoardView = {\n direction: BoardDirection;\n ordering: BoardOrdering;\n /** When false, columns with no matching card are hidden instead of shown empty. */\n showEmptyColumns: boolean;\n};\n\nexport const defaultBoardView: BoardView = {\n direction: \"desc\",\n ordering: \"priority\",\n showEmptyColumns: true,\n};\n\nexport const boardOrderings: readonly BoardOrdering[] = [\"priority\", \"created\", \"updated\", \"title\"];\n\nexport const isBoardOrdering = (value: unknown): value is BoardOrdering =>\n typeof value === \"string\" && boardOrderings.some((ordering) => ordering === value);\n\nexport const isBoardDirection = (value: unknown): value is BoardDirection =>\n value === \"asc\" || value === \"desc\";\n\nconst priorityRank: Record<WorkItem[\"priority\"], number> = {\n LOW: 0,\n MEDIUM: 1,\n HIGH: 2,\n URGENT: 3,\n};\n\nconst compareBy = (ordering: BoardOrdering, left: WorkItem, right: WorkItem): number => {\n if (ordering === \"priority\") return priorityRank[left.priority] - priorityRank[right.priority];\n if (ordering === \"created\") return left.createdAt.localeCompare(right.createdAt);\n if (ordering === \"updated\") return left.updatedAt.localeCompare(right.updatedAt);\n return left.title.localeCompare(right.title);\n};\n\n/**\n * Orders cards for display. The comparison is total — ties fall back to creation time and then to\n * the opaque ID — so the same data always renders in the same order.\n */\nexport const orderWorkItems = (\n items: readonly WorkItem[],\n { direction, ordering }: Pick<BoardView, \"direction\" | \"ordering\">,\n): readonly WorkItem[] => {\n const sign = direction === \"asc\" ? 1 : -1;\n return [...items].sort((left, right) => {\n const primary = compareBy(ordering, left, right);\n if (primary !== 0) return primary * sign;\n const created = left.createdAt.localeCompare(right.createdAt);\n if (created !== 0) return created * sign;\n return left.id.localeCompare(right.id);\n });\n};\n\n/**\n * Which slice of a project's delivery the board shows. `active` hides finished work, `backlog`\n * narrows to unstarted work, and `all` is the only place a DONE or CANCELLED task stays visible.\n */\nexport type BoardScope = \"active\" | \"backlog\" | \"all\";\n\nexport const scopeStates: Record<BoardScope, readonly WorkItemState[]> = {\n active: [\"BACKLOG\", \"READY\", \"IN_PROGRESS\", \"BLOCKED\"],\n backlog: [\"BACKLOG\"],\n all: [\"BACKLOG\", \"READY\", \"IN_PROGRESS\", \"BLOCKED\", \"DONE\", \"CANCELLED\"],\n};\n\nexport const isBoardScope = (value: unknown): value is BoardScope =>\n value === \"active\" || value === \"backlog\" || value === \"all\";\n\nexport const scopeShows = (scope: BoardScope, state: WorkItemState): boolean =>\n scopeStates[scope].includes(state);\n","import { z } from \"zod\";\nexport const schemaVersionSchema = z.literal(1);\nexport const apiVersionSchema = z.literal(\"v1\");\nexport const opaqueIdSchema = z\n .string()\n .trim()\n .min(1)\n .max(128)\n .regex(/^[a-zA-Z0-9][a-zA-Z0-9._:-]*$/);\nexport const correlationIdSchema = opaqueIdSchema;\nexport const utcTimestampSchema = z.iso.datetime({ offset: true });\nexport const actorSchema = z\n .object({\n type: z.enum([\"HUMAN\", \"SYSTEM\"]),\n id: opaqueIdSchema,\n})\n .strict();\n//# sourceMappingURL=shared.js.map","import { z } from \"zod\";\nimport { opaqueIdSchema } from \"./shared.js\";\n/**\n * One frame of the event channel.\n *\n * Spec §5.2: three opaque identifiers, nothing else. The client learns *that* something changed at\n * a scope, never *what* changed -- so the channel carries no WorkItem text and no provider output,\n * and therefore cannot widen the untrusted-checkpoint threat A1 §8 records. `.strict()` is what\n * keeps that true over time: a field added later fails to parse instead of riding along.\n */\nexport const eventSignalSchema = z\n .object({\n projectId: opaqueIdSchema,\n aggregateType: z.enum([\"PROJECT\", \"WORK_ITEM\"]),\n aggregateId: opaqueIdSchema,\n})\n .strict();\n//# sourceMappingURL=event-stream.js.map","import { z } from \"zod\";\nimport { apiVersionSchema, correlationIdSchema, utcTimestampSchema } from \"./shared.js\";\nexport const healthResponseSchema = z\n .object({\n status: z.enum([\"live\", \"ready\"]),\n apiVersion: apiVersionSchema,\n timestamp: utcTimestampSchema,\n})\n .strict();\nexport const sessionExchangeRequestSchema = z\n .object({\n bootstrapToken: z.string().min(43).max(128),\n})\n .strict();\nexport const sessionExchangeResponseSchema = z\n .object({\n authenticated: z.literal(true),\n csrfToken: z.string().min(43).max(128),\n expiresAt: utcTimestampSchema,\n})\n .strict();\nexport const daemonStatusResponseSchema = z\n .object({\n apiVersion: apiVersionSchema,\n authenticated: z.literal(true),\n daemon: z\n .object({\n status: z.literal(\"online\"),\n version: z.string(),\n mode: z.literal(\"local\"),\n startedAt: utcTimestampSchema,\n platform: z.enum([\"darwin\", \"win32\", \"linux\", \"other\"]),\n })\n .strict(),\n foundation: z\n .object({\n phase: z.literal(\"phase-0\"),\n milestone: z.enum([\"M1\", \"M2\", \"M3\", \"M4\", \"M5\", \"M6\"]),\n providers: z.literal(\"mock-only\"),\n persistence: z.enum([\"not-enabled\", \"sqlite\"]),\n })\n .strict(),\n})\n .strict();\nexport const apiErrorResponseSchema = z\n .object({\n error: z\n .object({\n code: z.string(),\n message: z.string(),\n correlationId: correlationIdSchema,\n details: z.record(z.string(), z.unknown()).optional(),\n })\n .strict(),\n})\n .strict();\n//# sourceMappingURL=session.js.map","import { z } from \"zod\";\nimport { actorSchema, correlationIdSchema, opaqueIdSchema, schemaVersionSchema, utcTimestampSchema, } from \"./shared.js\";\n// A Git object id (spec §2.9). Not a general opaqueIdSchema: an object id has a shape of its own,\n// unrelated to Loomrail's id shape, and validating it here catches a caller that passes a truncated\n// or garbled sha before it is ever handed to `git`.\n//\n// Lowercase 40 hex is SHA-1, and that is a statement about THIS codebase rather than about git: git\n// also supports SHA-256 repositories, whose object ids are 64 hex characters, and a schema claiming\n// git's format is fixed would simply be wrong. Every sha reaching this contract comes from\n// `@loomrail/workspace` running plumbing against a repository Loomrail itself cut a worktree from,\n// and nothing in this project creates or accepts a SHA-256 repository. Widening this regex is\n// therefore part of adding that support, not a bug fix -- and until then the narrow bound is what\n// catches a caller passing something that is not an object id at all.\nconst commitShaSchema = z.string().regex(/^[0-9a-f]{40}$/);\nconst branchSchema = z.string().trim().min(1).max(255);\nconst worktreePathSchema = z.string().trim().min(1).max(4_000);\n// The cap on how many paths one WORK_ITEM_WORKSPACE_CREATED event may list. Exported alongside the\n// schema that uses it (like maxContextPackRecipeSources in workflow.ts) so a caller building the\n// carry-in list can check it against the same bound the schema will enforce, rather than\n// discovering the limit only when `.parse` rejects it.\nexport const maxCarriedPaths = 500;\n// Relative repository paths, one per file the carry-in snapshot (packages/workspace's\n// createCarryInSnapshot) actually moved -- see docs/plans/14-e1-workspace-execution-implementation-\n// plan.ru.md Задача 4. Not opaqueIdSchema: these are filesystem paths, not Loomrail ids, and can\n// contain characters (slashes, dots) opaqueIdSchema's pattern forbids.\nconst carriedPathsSchema = z.array(z.string().trim().min(1).max(4_096)).max(maxCarriedPaths);\nexport const workItemWorkspaceStatusSchema = z.enum([\"READY\", \"ORPHANED\", \"REMOVED\"]);\nexport const workItemWorkspaceSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n id: opaqueIdSchema,\n projectId: opaqueIdSchema,\n workItemId: opaqueIdSchema,\n branch: branchSchema,\n worktreePath: worktreePathSchema,\n // Nullable, not optional: an empty repository genuinely has no HEAD (spec §2.12). Absent would\n // read as \"not recorded\"; null records the fact that there was nothing to record.\n baseCommit: commitShaSchema.nullable(),\n // Nullable, not optional: a workspace cut from a clean working copy genuinely carried nothing\n // forward, so there is no snapshot commit to name (spec §2.9's \"переносить нечего\" path).\n snapshotCommit: commitShaSchema.nullable(),\n status: workItemWorkspaceStatusSchema,\n // Nullable: names the StageAttempt currently allowed to write, or no one (spec D6). The\n // workspace belongs to the WorkItem and outlives any single attempt, so this is a lease held\n // for the attempt's duration, not an owner.\n leaseHolder: opaqueIdSchema.nullable(),\n createdAt: utcTimestampSchema,\n version: z.number().int().positive(),\n})\n .strict();\nconst eventBaseSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n sequence: z.number().int().positive(),\n id: opaqueIdSchema,\n aggregateId: opaqueIdSchema,\n projectId: opaqueIdSchema,\n actor: actorSchema,\n occurredAt: utcTimestampSchema,\n correlationId: correlationIdSchema,\n})\n .strict();\n// Carries the workspace plus the files the carry-in snapshot moved into it (spec §4): the\n// workspace's own worktreePath/branch/baseCommit/snapshotCommit tell a reader *that* something was\n// carried in, but not *what* -- and that is exactly what an owner reviewing the work item's history\n// needs to see without re-deriving a `git diff` against a commit that may since have moved on.\nexport const workItemWorkspaceCreatedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"WORK_ITEM_WORKSPACE_CREATED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z\n .object({\n workspace: workItemWorkspaceSchema,\n carriedPaths: carriedPathsSchema,\n })\n .strict(),\n});\n// Recorded when a workspace is found orphaned -- its worktree directory prunable, or gone outside\n// Loomrail's control -- at daemon startup (spec §6, \"Восстановление\"). previousStatus is carried\n// because the only status this transition is ever taken from is READY, and recording that fact\n// (rather than assuming it) keeps the audit trail honest if that ever stops being true.\nexport const workItemWorkspaceOrphanedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"WORK_ITEM_WORKSPACE_ORPHANED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z\n .object({\n workspace: workItemWorkspaceSchema,\n previousStatus: workItemWorkspaceStatusSchema,\n })\n .strict(),\n});\nconst commandBaseSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n commandId: opaqueIdSchema,\n correlationId: correlationIdSchema,\n actor: actorSchema,\n})\n .strict();\n// The workspace's own `id` is not part of the payload -- it is assigned by the persistence layer\n// that writes it, the same way CREATE_WORK_ITEM never takes the WorkItem's own id (work-\n// management.ts). `workItemId` is enough to identify which entity this workspace belongs to, and\n// the 0011 migration's UNIQUE constraint on work_item_id (spec Задача 7) makes a second one for the\n// same WorkItem a storage-level refusal, not something this contract has to guard against.\nexport const createWorkItemWorkspaceCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"CREATE_WORK_ITEM_WORKSPACE\"),\n payload: z\n .object({\n workItemId: opaqueIdSchema,\n projectId: opaqueIdSchema,\n branch: branchSchema,\n worktreePath: worktreePathSchema,\n baseCommit: commitShaSchema.nullable(),\n snapshotCommit: commitShaSchema.nullable(),\n carriedPaths: carriedPathsSchema,\n })\n .strict(),\n});\n// expectedVersion follows the same optimistic-concurrency convention as every other mutation of an\n// existing entity in this package (UPDATE_WORK_ITEM, PAUSE_PIPELINE, RESOLVE_ACCEPTANCE, …): the\n// caller names the version it read, so a lease raced against a concurrent writer is rejected rather\n// than silently overwritten.\nexport const acquireWorkspaceLeaseCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"ACQUIRE_WORKSPACE_LEASE\"),\n payload: z\n .object({\n workspaceId: opaqueIdSchema,\n stageAttemptId: opaqueIdSchema,\n expectedVersion: z.number().int().positive(),\n })\n .strict(),\n});\n// Names the releasing StageAttempt, not just the workspace: a release is only ever valid from the\n// attempt that currently holds the lease (spec D6), and carrying that id lets the handler refuse a\n// release from anyone else instead of trusting the caller's say-so.\nexport const releaseWorkspaceLeaseCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"RELEASE_WORKSPACE_LEASE\"),\n payload: z\n .object({\n workspaceId: opaqueIdSchema,\n stageAttemptId: opaqueIdSchema,\n expectedVersion: z.number().int().positive(),\n })\n .strict(),\n});\n// System-driven, not a StageAttempt action: this is the reconciliation path (spec §6,\n// \"Восстановление\") that notices a worktree directory is gone or prunable and records the fact.\n// Nothing is resurrected (AD-008) -- this command only ever moves a workspace toward ORPHANED.\nexport const markWorkspaceOrphanedCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"MARK_WORKSPACE_ORPHANED\"),\n payload: z\n .object({\n workspaceId: opaqueIdSchema,\n expectedVersion: z.number().int().positive(),\n })\n .strict(),\n});\n// Command results, in the shape stateCommandResultSchema (work-management.ts) expects of every\n// member: schemaVersion/type/replayed plus whatever the caller needs back. `workItemId` is carried\n// even though every payload already lets a caller re-derive it, the same convenience\n// providerSessionStartedResultSchema (workflow.ts) offers -- a caller acting on the result should\n// not have to also hold the command payload just to route the outcome to the right WorkItem.\nexport const workItemWorkspaceCreatedResultSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n type: z.literal(\"WORK_ITEM_WORKSPACE_CREATED\"),\n replayed: z.boolean(),\n workItemId: opaqueIdSchema,\n workspace: workItemWorkspaceSchema,\n event: workItemWorkspaceCreatedEventSchema,\n})\n .strict();\n// No event: a lease is current state for a StageAttempt to act on, not something the audit log or\n// the owner needs to see -- the same reasoning providerSessionProcessRecordedResultSchema\n// (workflow.ts) gives for a pid. `events` stays in the shape for uniformity across every command\n// result, typed so only `[]` can satisfy it.\nexport const workspaceLeaseAcquiredResultSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n type: z.literal(\"WORKSPACE_LEASE_ACQUIRED\"),\n replayed: z.boolean(),\n workItemId: opaqueIdSchema,\n workspace: workItemWorkspaceSchema,\n events: z.array(z.never()),\n})\n .strict();\nexport const workspaceLeaseReleasedResultSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n type: z.literal(\"WORKSPACE_LEASE_RELEASED\"),\n replayed: z.boolean(),\n workItemId: opaqueIdSchema,\n workspace: workItemWorkspaceSchema,\n events: z.array(z.never()),\n})\n .strict();\nexport const workItemWorkspaceOrphanedResultSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n type: z.literal(\"WORK_ITEM_WORKSPACE_ORPHANED\"),\n replayed: z.boolean(),\n workItemId: opaqueIdSchema,\n workspace: workItemWorkspaceSchema,\n event: workItemWorkspaceOrphanedEventSchema,\n})\n .strict();\n// What `GET /api/v1/work-items/:workItemId/workspace` answers: the workspace a WorkItem has, or the\n// recorded fact that it has none.\n//\n// `null` rather than a 404, because \"this WorkItem has no workspace\" is the ordinary state of every\n// prose-only stage and of every work item before its first code stage -- not a missing resource. A\n// 404 would make the caller distinguish \"no workspace\" from \"no such WorkItem\" by inspecting an\n// error code, and the cockpit asks this question for whichever item the owner selected, most of\n// which have never cut one.\n//\n// A response object rather than the bare workspace for the same reason every other listing here\n// wraps its payload (projectsResponseSchema, workItemsResponseSchema): a top-level `null` body\n// carries no schemaVersion, so a later field could not be added without breaking every reader.\n//\n// A field on a response nobody reads is a declaration without a consumer, so this projects the\n// stored workspace rather than forwarding it whole -- and the rule is applied to every field it\n// leaves off, not to `leaseHolder` alone:\n//\n// - `leaseHolder`. The lease is how the daemon keeps two StageAttempts from writing the same\n// worktree at once (spec D6); no caller of this route reads it, and none is planned to -- the\n// cockpit shows where the agent writes, not which attempt currently holds the pen.\n// - `id`, `projectId`, `workItemId`. Identity the caller already holds: this route is reached at\n// `/work-items/:workItemId/workspace`, so the id in the URL the caller just used is the same\n// `workItemId` this field would repeat, `projectId` is already on the WorkItem the cockpit holds\n// (WorkbenchPage.tsx's WorkspacePanel reads `item.projectId`, never the workspace's own copy), and\n// nothing reads the workspace's own `id` -- the lease commands that take a `workspaceId` are\n// system-driven (session-loop.ts), never issued from the web client this route serves.\n// - `createdAt`, `version`. Neither is rendered, and `version` exists for the optimistic-concurrency\n// commands (ACQUIRE_WORKSPACE_LEASE, RELEASE_WORKSPACE_LEASE, MARK_WORKSPACE_ORPHANED) that only\n// the session loop issues -- the same system-only path as `id` above.\n//\n// `snapshotCommit` stays, and that is also a decision rather than an oversight: it is unread today,\n// but docs/plans/15-e1-5-change-visibility-spec.ru.md §D1 already names it half of the diff base\n// (`snapshotCommit ?? baseCommit`) that milestone reads back through this same response. A field\n// with a cited future consumer is not the defect this rule is about.\nexport const publishedWorkItemWorkspaceSchema = workItemWorkspaceSchema.omit({\n leaseHolder: true,\n id: true,\n projectId: true,\n workItemId: true,\n createdAt: true,\n version: true,\n});\nexport const workItemWorkspaceResponseSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n workspace: publishedWorkItemWorkspaceSchema.nullable(),\n})\n .strict();\n// E1.5 (docs/plans/15-e1-5-change-visibility-spec.ru.md §4, §5): what a work item has changed in\n// its worktree, given a boundary form so the daemon can answer GET\n// /api/v1/work-items/:workItemId/changes and .../changes/diff with it.\n//\n// The shape of a change summary is declared once, in @loomrail/workspace's\n// packages/workspace/src/changes.ts (Tasks 1-2 of this milestone) -- ChangeStatus, ChangedFile,\n// ChangeSummary, FileDiff. `changedFileSchema` below and the shared fields of `fileDiffSchema` are\n// that declaration's boundary FORM, not a second declaration of it: their shape is copied by hand\n// here (Zod cannot be derived from a plain TypeScript type), but\n// packages/contracts/test/workspace.unit.test.ts imports ChangedFile and FileDiff straight from\n// packages/workspace/src/changes.ts and asserts, at the type level, that\n// `z.infer<typeof changedFileSchema>` equals `ChangedFile` and that fileDiffSchema's non-boundary\n// fields equal `FileDiff`, in both directions. If a field is ever added, renamed, widened, or\n// narrowed on one side and not the other, `pnpm typecheck` fails before either side ships --\n// which is the point: a runtime test only catches the fixtures it was given, and this shape has\n// already drifted silently once in this milestone (session.unit.test.ts's incomplete-fixture bug,\n// named in the Task 3 brief). The import is type-only (`import type`, erased by\n// `verbatimModuleSyntax`) and reaches across a relative path rather than \"@loomrail/workspace\" the\n// package, so it costs neither package a new dependency edge: @loomrail/contracts stays the\n// zero-dependency package every other workspace package (including @loomrail/workspace's own\n// consumer, @loomrail/persistence-sqlite) builds on, and no dist output of either package embeds\n// the other.\n//\n// `ChangeSummary.tree` is deliberately NOT part of this response and so is not part of the\n// equality check either. It is not the stage-end resultTree label the daemon writes onto\n// StageAttempt -- that label is read through `treeOfWorktree`, a separate, baseline-independent\n// function, not through this summary -- but the two would be shown together if either were shown at\n// all, and D3 says in so many words that the label \"не показывается в этой вехе\" (is not shown\n// this milestone).\n//\n// `baseline` is on both schemas and lands differently on each, because spec §4 puts it differently\n// on each. `FileDiff` there is a plain reading with no work item in it, so @loomrail/workspace's\n// `FileDiff` carries the baseline it was read against and this schema's field is shared, checked\n// like the rest; `WorkItemChangeSummary` there is the boundary shape -- it carries `workItemId`,\n// which no reading knows -- so its `baseline` is attached by the daemon when it builds the\n// response, the same way it attaches `workItemId` via the URL rather than the payload (see\n// `publishedWorkItemWorkspaceSchema` above, which drops that same field for that same reason).\nconst changeStatusSchema = z.enum([\"ADDED\", \"MODIFIED\", \"DELETED\", \"RENAMED\"]);\n// Shared by `changedFileSchema.path`/`previousPath` and `fileDiffSchema.path`: a path this contract\n// shows the owner, bounded the same way `carriedPathsSchema` above bounds one -- 4096 characters,\n// spec §5 -- because every path here is a string the daemon read from git output and will store,\n// log, or interpolate into a request, not a value this contract can otherwise trust to be short.\n//\n// Bounded but NOT trimmed, unlike `carriedPathsSchema`, and the difference is what the two strings\n// are for. A carried path is an input list this contract narrows on the way in; a changed path is\n// an identifier the contract publishes and then has to accept back on the file-diff handle. A\n// leading or trailing space is a legal filename character, and `.trim()` -- inherited from that\n// other schema -- silently renamed such a file: the summary listed `\"trail \"` while the contract\n// published `\"trail\"`, and asking for that published name back earned a PathNotAFileError for a\n// file that is really there. A contract that renames what it reports cannot be round-tripped.\nconst changedPathSchema = z.string().min(1).max(4_096);\n// A line count from a work item's change summary. Nullable, never defaulted to zero: a binary\n// file's `insertions`/`deletions` are null because there is no line count to report, and reporting\n// zero would read as \"nothing changed in it\" -- spec §4, D8, and the Task 3 brief's own worked\n// example (a binary file whose counts stay null through this schema).\nconst changeLineCountSchema = z.number().int().nonnegative().nullable();\nexport const changedFileSchema = z\n .object({\n path: changedPathSchema,\n previousPath: changedPathSchema.nullable(),\n status: changeStatusSchema,\n insertions: changeLineCountSchema,\n deletions: changeLineCountSchema,\n binary: z.boolean(),\n})\n .strict();\nexport const workItemChangeSummarySchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n // Non-nullable, unlike WorkItemWorkspace.baseCommit above: a summary computed with no base to\n // compare against is not a degraded summary, it is not a summary (spec §5).\n baseline: commitShaSchema,\n files: z.array(changedFileSchema),\n truncated: z.boolean(),\n})\n .strict();\nexport const fileDiffSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n path: changedPathSchema,\n baseline: commitShaSchema,\n binary: z.boolean(),\n // Null for a binary file, never \"\": an empty string would read as an empty, but real, diff\n // (spec D8).\n patch: z.string().nullable(),\n truncated: z.boolean(),\n omittedBytes: z.number().int().nonnegative(),\n})\n .strict();\n// The `changes` handle's response, and NOT `workItemChangeSummarySchema` on its own.\n//\n// A WorkItem with no workspace has nothing to summarise, and that is the ordinary state of every\n// prose-only stage rather than a failure (spec §7's first row). It cannot be expressed as a\n// degraded summary, because `baseline` above is deliberately non-nullable: a summary with no base\n// to compare against is not a summary. So the fact travels the way E1's\n// GET /api/v1/work-items/:workItemId/workspace already carries the very same fact --\n// `null` with 200, with 404 left to mean the one thing it should mean, that the WorkItem itself\n// does not exist. One convention for one condition, rather than a second one invented here.\nexport const workItemChangesResponseSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n changes: workItemChangeSummarySchema.nullable(),\n})\n .strict();\n// The body handle's response, enveloped for the same reason and answering the same `null` for the\n// same condition (spec D5 keeps the two handles apart; it does not make them answer \"no workspace\"\n// two different ways).\nexport const workItemFileDiffResponseSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n diff: fileDiffSchema.nullable(),\n})\n .strict();\n//# sourceMappingURL=workspace.js.map","import { z } from \"zod\";\nimport { actorSchema, correlationIdSchema, opaqueIdSchema, schemaVersionSchema, utcTimestampSchema, } from \"./shared.js\";\nimport { workItemWorkspaceOrphanedEventSchema, workItemWorkspaceSchema } from \"./workspace.js\";\n// A Git TREE object id, not a commit one. Same forty lowercase hex characters as\n// `commitShaSchema` in workspace.ts and deliberately a separate declaration: what this names is the\n// content of a directory, and a schema that called it a commit would invite a reader to pass it to\n// `git log` or `git show <sha>^` and get nothing. The SHA-1 bound is the same statement about this\n// codebase that workspace.ts spells out -- no SHA-256 repository is created or accepted anywhere in\n// Loomrail, so widening the regex is part of adding that support rather than a bug fix.\nconst treeShaSchema = z.string().regex(/^[0-9a-f]{40}$/);\nexport const workflowStageSchema = z.enum([\"DISCOVERY\", \"PLAN\", \"IMPLEMENT\", \"REVIEW\", \"QA\", \"ACCEPTANCE\"]);\n// Provider identity belongs to the durable contract, not to an adapter implementation: commands,\n// EvidenceArtifacts and provider capabilities must all use the same closed vocabulary without\n// making @loomrail/contracts depend back on @loomrail/provider-core.\nexport const providerIdSchema = z.enum([\"MOCK\", \"CODEX\", \"CLAUDE_CODE\"]);\nexport const pipelineRunStatusSchema = z.enum([\n \"RUNNING\",\n \"WAITING_HUMAN\",\n \"SOFT_PAUSED\",\n \"HARD_PAUSED\",\n \"INTERRUPTED\",\n \"SUCCEEDED\",\n \"FAILED\",\n \"CANCELLED\",\n]);\nexport const stageAttemptStatusSchema = z.enum([\n \"PENDING\",\n \"QUEUED\",\n \"RUNNING\",\n \"WAITING_HUMAN\",\n \"SOFT_PAUSED\",\n \"HARD_PAUSED\",\n \"SUCCEEDED\",\n \"FAILED\",\n \"CANCELLED\",\n \"INTERRUPTED\",\n \"RECOVERING\",\n \"STALE\",\n]);\nexport const humanRequestKindSchema = z.enum([\n \"SINGLE_CHOICE\",\n \"MULTIPLE_CHOICE\",\n \"CONFIRMATION\",\n \"FREE_TEXT\",\n]);\nexport const humanRequestStatusSchema = z.enum([\n \"OPEN\",\n \"CLAIMED\",\n \"SNOOZED\",\n \"RESOLVED\",\n \"EXPIRED\",\n \"CANCELLED\",\n]);\nexport const workflowDispatchModeSchema = z.enum([\"START\", \"RESUME\"]);\nexport const workflowDispatchStatusSchema = z.enum([\"PENDING\", \"COMPLETED\", \"FAILED\"]);\nexport const usageQualitySchema = z.enum([\"ACTUAL\", \"PROVIDER_ESTIMATE\", \"LOOMRAIL_ESTIMATE\"]);\nexport const usageKindSchema = z.literal(\"ESTIMATED_TOKENS\");\nexport const budgetPauseKindSchema = z.enum([\"SOFT\", \"HARD\"]);\nexport const recoveryReasonSchema = z.literal(\"DAEMON_RESTART\");\nexport const evidenceArtifactKindSchema = z.enum([\"REVIEW_REPORT\", \"QA_REPORT\"]);\nexport const evidenceArtifactStatusSchema = z.literal(\"PASSED\");\nexport const acceptanceStatusSchema = z.enum([\"PENDING\", \"ACCEPTED\", \"RETURNED\", \"REJECTED\"]);\nexport const acceptanceActionSchema = z.enum([\"ACCEPT\", \"RETURN_TO_WORK\", \"REJECT\"]);\nexport const providerSessionStatusSchema = z.enum([\"RUNNING\", \"ENDED\"]);\nexport const providerSessionEndReasonSchema = z.enum([\n \"COMPLETED\",\n \"HANDOFF\",\n \"CONTEXT_EXHAUSTED\",\n \"INTERRUPTED\",\n \"CANCELLED\",\n]);\n// The kinds a context-pack section's provenance can point at (packages/context-assembly's\n// render.ts is the only producer today). WORKFLOW_POSITION carries no source: templateId and\n// templateVersion are recorded at the recipe's top level instead (spec §4.2).\nexport const contextSourceKindSchema = z.enum([\n \"WORK_ITEM\",\n \"DECISION\",\n \"CHECKPOINT\",\n \"EVIDENCE\",\n \"ACTIVITY\",\n]);\nexport const contextPackSpecSourceSchema = z.literal(\"WORKFLOW_TEMPLATE\"); // A3 adds ROLE_PLAYBOOK\nexport const contextPackOmittedReasonSchema = z.literal(\"CONTEXT_BUDGET\");\nconst titleSchema = z.string().trim().min(1).max(200);\nconst descriptionSchema = z.string().trim().min(1).max(4_000);\nconst budgetThresholdSchema = z.number().positive().max(1);\nexport const contextSectionIdSchema = z.enum([\n \"WORK_ITEM_BRIEF\",\n \"WORKFLOW_POSITION\",\n \"DECISIONS\",\n \"LATEST_CHECKPOINT\",\n \"EVIDENCE\",\n \"ACTIVITY\",\n]);\nexport const contextPackSectionSchema = z\n .object({\n id: contextSectionIdSchema,\n ordinal: z.number().int().nonnegative(),\n required: z.boolean(),\n})\n .strict();\nexport const contextPackSpecSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n sections: z.array(contextPackSectionSchema).min(1).max(20),\n})\n .strict();\n// The assembled pack that crosses the provider-adapter boundary (A2). Declared here rather than\n// in @loomrail/context-assembly so that provider-core can depend on the type without depending on\n// an assembly implementation package for it.\nexport const contextPackSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n text: z.string(),\n contentHash: z.string().regex(/^sha256:[0-9a-f]{64}$/),\n})\n .strict();\n// Per-section provenance is a list, not a single { kind, id, version } pair: cardinality carries\n// meaning (0 = a genuinely derived section, 1 = one durable entity, N = a collection), and\n// DECISIONS/EVIDENCE/ACTIVITY are collections of records, each with its own id and version. A\n// single pair cannot express N of them. This mirrors ContextPackRecipeDraft in\n// packages/context-assembly/src/assemble.ts, which is the only producer of this shape today.\nexport const contextPackRecipeSourceSchema = z\n .object({\n kind: contextSourceKindSchema,\n id: opaqueIdSchema,\n version: z.number().int().positive(),\n})\n .strict();\n// The cap on how many source records one section of a recipe may cite. Exported rather than\n// inlined because the persistence layer's collection reads (READ_CONTEXT_SOURCES) have to be\n// bounded by the *same* number: a work item with more decisions than this used to produce a recipe\n// that `contextPackRecipeInputSchema.parse` rejected, which threw out of the session loop -- and out\n// of daemon startup, if the attempt was picked up by the boot drain. A narrower pack is a degraded\n// session; an unparseable recipe is no session at all.\nexport const maxContextPackRecipeSources = 200;\nexport const contextPackRecipeSectionSchema = z\n .object({\n id: contextSectionIdSchema,\n sources: z.array(contextPackRecipeSourceSchema).max(maxContextPackRecipeSources),\n bytes: z.number().int().nonnegative(),\n})\n .strict();\nexport const contextPackRecipeOmittedSectionSchema = z\n .object({\n id: contextSectionIdSchema,\n reason: contextPackOmittedReasonSchema,\n})\n .strict();\n// Persisted alongside the assembled pack (spec §4.2). `sections`/`omitted`/`estimatedTokens`/\n// `budgetTokens` are exactly what the assembler's ContextPackRecipeDraft emits; the remaining\n// fields (id, providerSessionId, templateId, templateVersion, specSource, contentHash,\n// estimateQuality, createdAt) are added by the persistence layer that writes the recipe alongside\n// the session and the PROVIDER_SESSION_STARTED event.\nexport const contextPackRecipeSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n id: opaqueIdSchema,\n providerSessionId: opaqueIdSchema,\n templateId: opaqueIdSchema,\n templateVersion: z.number().int().positive(),\n specSource: contextPackSpecSourceSchema,\n sections: z.array(contextPackRecipeSectionSchema).min(1).max(20),\n omitted: z.array(contextPackRecipeOmittedSectionSchema).max(20),\n contentHash: z.string().regex(/^sha256:[0-9a-f]{64}$/),\n estimatedTokens: z.number().int().nonnegative(),\n budgetTokens: z.number().int().positive(),\n estimateQuality: usageQualitySchema,\n createdAt: utcTimestampSchema,\n})\n .strict();\n// The OS pid of the child process a live session actually spawned. Shared between\n// `providerSessionSchema` (what a session carries once one is known) and\n// `recordProviderSessionProcessCommandSchema` (how one gets there) so the daemon's own validation\n// of what `ProviderSessionListener.onProcessStarted` reports (@loomrail/provider-core) can never\n// disagree with what the persisted column will accept.\nexport const providerSessionProcessPidSchema = z.number().int().positive();\nexport const providerSessionSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n id: opaqueIdSchema,\n stageAttemptId: opaqueIdSchema,\n ordinal: z.number().int().positive(),\n status: providerSessionStatusSchema,\n endReason: providerSessionEndReasonSchema.nullable(),\n handoffRequestedAt: utcTimestampSchema.nullable(),\n startedAt: utcTimestampSchema,\n endedAt: utcTimestampSchema.nullable(),\n version: z.number().int().positive(),\n // Spec §8: the OS pid of the child process this RUNNING session is driving, so a daemon that\n // dies without killing it can still find and kill that process on the next start. Nullable, not\n // defaulted to 0 -- \"no process was ever started\" and \"a process whose pid is 0\" are different\n // facts, and a defaulted column could not tell them apart. Starts null and is filled in later,\n // if at all, by RECORD_PROVIDER_SESSION_PROCESS (MOCK and any adapter that spawns nothing never\n // sends one, and the session simply stays null -- see `ProviderSessionListener.onProcessStarted`).\n pid: providerSessionProcessPidSchema.nullable(),\n})\n .strict()\n .refine((session) => (session.status === \"ENDED\") === (session.endReason !== null), \"An ended session must carry an end reason and a running one must not\")\n .refine((session) => (session.status === \"ENDED\") === (session.endedAt !== null), \"An ended session must carry an end timestamp and a running one must not\");\n// What the agent publishes mid-session (spec §5.1's onCheckpoint). Empty completed/remaining/\n// deadEnds/openQuestions lists are legitimate -- a session may genuinely have hit no dead ends --\n// but a checkpoint with no summary carries nothing forward to the next session's context pack.\nexport const checkpointDraftSchema = z\n .object({\n summary: descriptionSchema,\n completed: z.array(z.string().trim().min(1).max(500)).max(50),\n remaining: z.array(z.string().trim().min(1).max(500)).max(50),\n deadEnds: z.array(z.string().trim().min(1).max(500)).max(50),\n openQuestions: z.array(z.string().trim().min(1).max(500)).max(50),\n})\n .strict();\n// Checkpoint is append-only and never edited (D7): unlike the other entities in this file it\n// carries no optimistic-concurrency `version` field, matching evidenceArtifactSchema's pattern.\nexport const checkpointSchema = checkpointDraftSchema\n .extend({\n schemaVersion: schemaVersionSchema,\n id: opaqueIdSchema,\n stageAttemptId: opaqueIdSchema,\n providerSessionId: opaqueIdSchema,\n ordinal: z.number().int().positive(),\n createdAt: utcTimestampSchema,\n})\n .strict();\nexport const contextWindowUsageSchema = z\n .object({\n usedTokens: z.number().int().nonnegative(),\n windowTokens: z.number().int().positive(),\n quality: usageQualitySchema,\n})\n .strict()\n .refine((usage) => usage.usedTokens <= usage.windowTokens, \"Usage cannot exceed the window\");\n// A separate channel from ContextWindowUsage on purpose (spec BD-001). Window occupancy drives\n// session handoff; spend drives budget thresholds and the HARD pause. They are different\n// quantities with different consumers, and folding one into the other would oblige the consumer\n// of one to parse the other. `costUsd` is optional because not every provider prices its own\n// usage; the token fields are the figures every provider can report. `.strict()` matters here more\n// than on most schemas: this is the one channel a provider could otherwise use to smuggle\n// arbitrary content (e.g. a `transcript` field) past the contract as though it were spend.\nexport const providerUsageSchema = z\n .object({\n inputTokens: z.number().int().nonnegative(),\n outputTokens: z.number().int().nonnegative(),\n cachedInputTokens: z.number().int().nonnegative().optional(),\n reasoningOutputTokens: z.number().int().nonnegative().optional(),\n costUsd: z.number().nonnegative().optional(),\n quality: usageQualitySchema,\n})\n .strict();\nexport const workflowTemplateStageSchema = z\n .object({\n stage: workflowStageSchema,\n ordinal: z.number().int().nonnegative(),\n contextPack: contextPackSpecSchema,\n})\n .strict();\nexport const workflowTemplateSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n id: opaqueIdSchema,\n version: z.number().int().positive(),\n name: titleSchema,\n stages: z.array(workflowTemplateStageSchema).min(1).max(20),\n})\n .strict();\nexport const pipelineRunSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n id: opaqueIdSchema,\n projectId: opaqueIdSchema,\n workItemId: opaqueIdSchema,\n workflowTemplateId: opaqueIdSchema,\n workflowVersion: z.number().int().positive(),\n status: pipelineRunStatusSchema,\n currentStageAttemptId: opaqueIdSchema,\n version: z.number().int().positive(),\n createdAt: utcTimestampSchema,\n updatedAt: utcTimestampSchema,\n finishedAt: utcTimestampSchema.nullable(),\n})\n .strict();\nexport const stageAttemptSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n id: opaqueIdSchema,\n pipelineRunId: opaqueIdSchema,\n projectId: opaqueIdSchema,\n workItemId: opaqueIdSchema,\n stage: workflowStageSchema,\n attempt: z.number().int().positive(),\n status: stageAttemptStatusSchema,\n version: z.number().int().positive(),\n startedAt: utcTimestampSchema.nullable(),\n finishedAt: utcTimestampSchema.nullable(),\n failureCode: z.string().trim().min(1).max(100).nullable(),\n // §6.5: a session that publishes no checkpoint is unproductive; two in a row trigger a\n // HARD-pause. Lives on the StageAttempt (not in daemon memory) so a daemon restart -- itself\n // a normal end of a session -- cannot reset the very guard meant to catch that scenario.\n unproductiveSessions: z.number().int().nonnegative(),\n // §7: how many times the pack share has been stepped down after a provider rejected a pack\n // Loomrail judged as fitting. Durable for exactly the reason `unproductiveSessions` is: §6.4\n // makes a daemon restart an ordinary end of a session, so a counter held in daemon memory\n // would be cleared by the very event the \"one automatic retry, then ask\" rule must survive.\n packShareBackoffs: z.number().int().nonnegative(),\n /**\n * The Git tree the work item's worktree held when this stage succeeded (spec D3, §4).\n *\n * NOTHING IN E1.5 READS THIS, and that is deliberate rather than unfinished: spec §11 lists the\n * per-stage breakdown among the milestone's non-goals, so this field is written by the session\n * loop and displayed nowhere. A field with no reader is normally a declaration wearing the\n * shape of a contract, so here is the reader it is precomputed for, named:\n *\n * WHICH MILESTONE: the one that closes the second half of GD-002 -- checkpoint commits,\n * squash, and the Conventional Commit message the owner sees before acceptance -- which\n * requires GD-001, the agent's right to write Git history. Named in\n * docs/plans/06-post-phase-0-decomposition.ru.md §2 and in the E1.5 spec §1, both of which say\n * only that it \"goes separately\". It carries no ID in the approved order in that document's\n * §7 and is not scheduled; that is a gap in the roadmap, stated here rather than papered over.\n *\n * WHAT WILL READ IT: that milestone's per-stage breakdown, which needs one point of reference\n * per stage to say what each stage contributed, and its squash step, which builds checkpoint\n * commits from those same points. Neither can reconstruct them afterwards -- once the worktree\n * moves on, the tree a stage ended on is not recoverable from anything Loomrail keeps -- which\n * is the whole reason for spending forty bytes now.\n *\n * What survives to that milestone is narrower than \"a point to diff from\", and the difference is\n * measured rather than assumed. `git write-tree` writes the tree into the repository's object\n * database UNREACHABLE from any ref, along with the blobs `add -A` wrote for it; `git prune`\n * (and `git gc --auto`, which ordinary git commands trigger) removes unreachable objects older\n * than `gc.pruneExpire`, two weeks by default. Probed on a throwaway repository: after\n * `git prune --expire=now` the recorded tree answers `could not get object info`. So a reader\n * arriving weeks later can always compare two of these for EQUALITY -- \"this stage changed\n * nothing\", \"these two stages ended on the same tree\" -- and can only diff from one while the\n * owner's repository still holds the objects.\n *\n * Nullable, not optional, and the two states are genuinely different facts. `null` is \"no tree\n * was measured for this stage\": it never ran in a worktree (every prose stage), it has not\n * finished, or the worktree was gone when the label was taken. A stage that ran and changed\n * NOTHING is not null -- it records the tree it started on, which is a real sha -- so \"changed\n * nothing\" can never be mistaken for \"never measured\". Every StageAttempt recorded before\n * migration 0013 is null forever, which is the same fact and needs no special reading.\n */\n resultTree: treeShaSchema.nullable(),\n})\n .strict();\n// The `StageAttempt.failureCode` values that mark a HARD pause as raised by the session loop\n// (spec §6.5, §D8, §7) rather than by the token budget. Lives here, not in @loomrail/domain,\n// because it has two consumers on either side of the apps/web boundary: `decideAnswerHumanRequest`\n// and `decideApproveBudgetOverride` (packages/domain) decide behaviour from it, and the Task\n// Cockpit (apps/web) decides display from it -- apps/web depends on @loomrail/contracts and\n// @loomrail/ui only, never on @loomrail/domain. Should the two readings of \"is this a session\n// pause\" drift apart, the cockpit reads every HARD_PAUSED attempt as a budget pause and offers an\n// \"approve budget override\" action that decideApproveBudgetOverride throws on for these codes.\nexport const sessionPauseFailureCodes = [\n \"NO_PROGRESS\",\n \"CONTEXT_FLOOR_EXCEEDED\",\n \"PROVIDER_REJECTED_PACK\",\n \"PROVIDER_START_FAILED\",\n \"SESSION_LIMIT_REACHED\",\n];\nexport const isSessionPauseFailureCode = (code) => code !== null && sessionPauseFailureCodes.includes(code);\nexport const budgetPolicySchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n id: opaqueIdSchema,\n projectId: opaqueIdSchema,\n workItemId: opaqueIdSchema,\n pipelineRunId: opaqueIdSchema,\n revision: z.number().int().positive(),\n maxEstimatedTokens: z.number().int().positive(),\n warningThresholds: z.array(budgetThresholdSchema).min(1).max(10),\n createdBy: actorSchema,\n createdAt: utcTimestampSchema,\n})\n .strict();\nexport const usageRecordSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n id: opaqueIdSchema,\n projectId: opaqueIdSchema,\n workItemId: opaqueIdSchema,\n pipelineRunId: opaqueIdSchema,\n stageAttemptId: opaqueIdSchema,\n budgetPolicyId: opaqueIdSchema,\n kind: usageKindSchema,\n amount: z.number().int().positive(),\n quality: usageQualitySchema,\n recordedAt: utcTimestampSchema,\n})\n .strict();\nexport const recoveryReportSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n id: opaqueIdSchema,\n projectId: opaqueIdSchema,\n workItemId: opaqueIdSchema,\n pipelineRunId: opaqueIdSchema,\n stageAttemptId: opaqueIdSchema,\n previousStatus: z.literal(\"RUNNING\"),\n recoveredStatus: z.literal(\"INTERRUPTED\"),\n reason: recoveryReasonSchema,\n createdAt: utcTimestampSchema,\n})\n .strict();\nexport const providerArtifactDraftSchema = z\n .object({\n kind: evidenceArtifactKindSchema,\n title: titleSchema,\n summary: descriptionSchema,\n checks: z.array(z.string().trim().min(1).max(500)).min(1).max(20),\n})\n .strict();\nexport const evidenceArtifactSchema = providerArtifactDraftSchema\n .extend({\n schemaVersion: schemaVersionSchema,\n id: opaqueIdSchema,\n projectId: opaqueIdSchema,\n workItemId: opaqueIdSchema,\n pipelineRunId: opaqueIdSchema,\n stageAttemptId: opaqueIdSchema,\n stage: z.enum([\"REVIEW\", \"QA\"]),\n status: evidenceArtifactStatusSchema,\n provider: providerIdSchema,\n createdAt: utcTimestampSchema,\n})\n .strict();\nexport const acceptanceCriterionEvidenceSchema = z\n .object({\n criterion: z.string().trim().min(1).max(500),\n implementation: descriptionSchema,\n reviewArtifactId: opaqueIdSchema,\n qaArtifactId: opaqueIdSchema,\n verification: descriptionSchema,\n knownRisk: descriptionSchema.nullable(),\n})\n .strict();\nexport const acceptancePackageSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n id: opaqueIdSchema,\n projectId: opaqueIdSchema,\n workItemId: opaqueIdSchema,\n pipelineRunId: opaqueIdSchema,\n stageAttemptId: opaqueIdSchema,\n humanRequestId: opaqueIdSchema,\n status: acceptanceStatusSchema,\n criteria: z.array(acceptanceCriterionEvidenceSchema).max(50),\n artifactIds: z.array(opaqueIdSchema).min(2).max(20),\n releaseNote: descriptionSchema,\n verifyInstructions: z.array(descriptionSchema).min(1).max(20),\n version: z.number().int().positive(),\n createdAt: utcTimestampSchema,\n resolvedAt: utcTimestampSchema.nullable(),\n resolvedBy: actorSchema.nullable(),\n resolutionReason: descriptionSchema.nullable(),\n})\n .strict();\nexport const humanRequestOptionSchema = z\n .object({\n id: opaqueIdSchema,\n label: titleSchema,\n consequence: descriptionSchema,\n recommended: z.boolean(),\n})\n .strict();\nexport const humanRequestSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n id: opaqueIdSchema,\n projectId: opaqueIdSchema,\n workItemId: opaqueIdSchema,\n stageAttemptId: opaqueIdSchema,\n kind: humanRequestKindSchema,\n blocking: z.boolean(),\n title: titleSchema,\n context: descriptionSchema,\n recommendation: descriptionSchema.nullable(),\n options: z.array(humanRequestOptionSchema).max(20),\n allowOther: z.boolean(),\n status: humanRequestStatusSchema,\n version: z.number().int().positive(),\n createdAt: utcTimestampSchema,\n resolvedAt: utcTimestampSchema.nullable(),\n})\n .strict();\nexport const humanRequestAnswerSchema = z.discriminatedUnion(\"type\", [\n z\n .object({\n type: z.literal(\"OPTION\"),\n optionIds: z.array(opaqueIdSchema).min(1).max(20),\n })\n .strict(),\n z\n .object({\n type: z.literal(\"OTHER\"),\n text: z.string().trim().min(1).max(2_000),\n })\n .strict(),\n]);\nexport const decisionSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n id: opaqueIdSchema,\n projectId: opaqueIdSchema,\n workItemId: opaqueIdSchema,\n humanRequestId: opaqueIdSchema,\n answer: humanRequestAnswerSchema,\n actor: actorSchema,\n reason: z.string().trim().min(1).max(2_000).nullable(),\n createdAt: utcTimestampSchema,\n})\n .strict();\nexport const workflowDispatchSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n id: opaqueIdSchema,\n projectId: opaqueIdSchema,\n workItemId: opaqueIdSchema,\n pipelineRunId: opaqueIdSchema,\n stageAttemptId: opaqueIdSchema,\n mode: workflowDispatchModeSchema,\n status: workflowDispatchStatusSchema,\n createdAt: utcTimestampSchema,\n completedAt: utcTimestampSchema.nullable(),\n})\n .strict();\nconst humanRequestDraftBaseSchema = humanRequestSchema\n .pick({\n blocking: true,\n title: true,\n context: true,\n recommendation: true,\n})\n .strict();\nconst enumeratedHumanRequestDraftSchema = (kind) => humanRequestDraftBaseSchema\n .extend({\n kind: z.literal(kind),\n options: z.array(humanRequestOptionSchema).min(1).max(20),\n allowOther: z.boolean(),\n})\n .strict();\n// A provider-originated request must always expose at least one answer path. Enumerated requests\n// therefore carry an option, while FREE_TEXT explicitly accepts the OTHER answer shape. Keeping\n// these as a plain union emits nested `anyOf` for Structured Outputs; a discriminated union would\n// emit `oneOf`, which the Codex CLI schema subset does not accept.\nexport const humanRequestDraftSchema = z.union([\n enumeratedHumanRequestDraftSchema(\"SINGLE_CHOICE\"),\n enumeratedHumanRequestDraftSchema(\"MULTIPLE_CHOICE\"),\n enumeratedHumanRequestDraftSchema(\"CONFIRMATION\"),\n humanRequestDraftBaseSchema\n .extend({\n kind: z.literal(\"FREE_TEXT\"),\n options: z.array(humanRequestOptionSchema).max(0),\n allowOther: z.literal(true),\n })\n .strict(),\n]);\nexport const providerOutcomeSchema = z.discriminatedUnion(\"type\", [\n z\n .object({\n type: z.literal(\"NEEDS_HUMAN\"),\n request: humanRequestDraftSchema,\n })\n .strict(),\n z\n .object({\n type: z.literal(\"COMPLETED\"),\n summary: z.string().trim().min(1).max(4_000),\n artifacts: z.array(providerArtifactDraftSchema).max(5).optional(),\n })\n .strict(),\n z\n .object({\n type: z.literal(\"READY_FOR_ACCEPTANCE\"),\n releaseNote: descriptionSchema,\n verifyInstructions: z.array(descriptionSchema).min(1).max(20),\n })\n .strict(),\n z\n .object({\n type: z.literal(\"BUDGET_LIMIT_REACHED\"),\n usageIncrements: z.array(z.number().int().positive()).min(1).max(100),\n quality: usageQualitySchema,\n })\n .strict(),\n // Session-level results (spec §5.2, §6.3): the session wound down before the stage finished.\n // HANDED_OFF always carries the checkpoint it wound down with; CONTEXT_EXHAUSTED may not --\n // the adapter hit the wall before it could publish one, which is exactly the unproductive-\n // session case spec §6.5 guards against. Both are handled by the session loop, not by\n // decideApplyProviderOutcome (see the guard there).\n z\n .object({\n type: z.literal(\"HANDED_OFF\"),\n checkpoint: checkpointDraftSchema,\n })\n .strict(),\n z\n .object({\n type: z.literal(\"CONTEXT_EXHAUSTED\"),\n checkpoint: checkpointDraftSchema.optional(),\n })\n .strict(),\n]);\nconst eventBaseSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n sequence: z.number().int().positive(),\n id: opaqueIdSchema,\n aggregateId: opaqueIdSchema,\n projectId: opaqueIdSchema,\n actor: actorSchema,\n occurredAt: utcTimestampSchema,\n correlationId: correlationIdSchema,\n})\n .strict();\nexport const pipelineStartedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"PIPELINE_STARTED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z\n .object({ run: pipelineRunSchema, stageAttempt: stageAttemptSchema, budgetPolicy: budgetPolicySchema })\n .strict(),\n});\nexport const stageAttemptChangedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"STAGE_ATTEMPT_CHANGED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z\n .object({\n run: pipelineRunSchema,\n stageAttempt: stageAttemptSchema,\n previousStatus: stageAttemptStatusSchema,\n })\n .strict(),\n});\nexport const humanRequestOpenedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"HUMAN_REQUEST_OPENED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z.object({ request: humanRequestSchema }).strict(),\n});\nexport const humanRequestResolvedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"HUMAN_REQUEST_RESOLVED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z.object({ request: humanRequestSchema, decision: decisionSchema }).strict(),\n});\nexport const usageRecordedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"USAGE_RECORDED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z.object({ usageRecord: usageRecordSchema, cumulativeAmount: z.number().int().positive() }).strict(),\n});\nexport const budgetThresholdReachedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"BUDGET_THRESHOLD_REACHED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z\n .object({\n budgetPolicy: budgetPolicySchema,\n threshold: budgetThresholdSchema,\n cumulativeAmount: z.number().int().nonnegative(),\n })\n .strict(),\n});\nexport const pipelinePausedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"PIPELINE_PAUSED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z\n .object({\n run: pipelineRunSchema,\n stageAttempt: stageAttemptSchema,\n kind: budgetPauseKindSchema,\n reason: descriptionSchema,\n })\n .strict(),\n});\nexport const pipelineResumedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"PIPELINE_RESUMED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z.object({ run: pipelineRunSchema, stageAttempt: stageAttemptSchema }).strict(),\n});\nexport const pipelineCancelledEventSchema = eventBaseSchema.extend({\n type: z.literal(\"PIPELINE_CANCELLED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z.object({ run: pipelineRunSchema, stageAttempt: stageAttemptSchema }).strict(),\n});\nexport const budgetOverrideApprovedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"BUDGET_OVERRIDE_APPROVED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z\n .object({\n run: pipelineRunSchema,\n previousStageAttempt: stageAttemptSchema,\n stageAttempt: stageAttemptSchema,\n budgetPolicy: budgetPolicySchema,\n })\n .strict(),\n});\nexport const recoveryReportCreatedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"RECOVERY_REPORT_CREATED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z\n .object({ report: recoveryReportSchema, run: pipelineRunSchema, stageAttempt: stageAttemptSchema })\n .strict(),\n});\nexport const evidenceArtifactRecordedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"EVIDENCE_ARTIFACT_RECORDED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z.object({ artifact: evidenceArtifactSchema }).strict(),\n});\nexport const acceptanceRequestedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"ACCEPTANCE_REQUESTED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z\n .object({\n acceptancePackage: acceptancePackageSchema,\n request: humanRequestSchema,\n run: pipelineRunSchema,\n stageAttempt: stageAttemptSchema,\n })\n .strict(),\n});\nexport const acceptanceResolvedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"ACCEPTANCE_RESOLVED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z\n .object({\n action: acceptanceActionSchema,\n acceptancePackage: acceptancePackageSchema,\n request: humanRequestSchema,\n decision: decisionSchema,\n run: pipelineRunSchema,\n stageAttempt: stageAttemptSchema,\n })\n .strict(),\n});\nexport const pipelineCompletedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"PIPELINE_COMPLETED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z.object({ run: pipelineRunSchema, stageAttempt: stageAttemptSchema }).strict(),\n});\n// Spec §4.4: PROVIDER_SESSION_STARTED must carry the recipe's contentHash and the list of omitted\n// section ids, so a reader of the audit log can see what the agent was and was not given without\n// loading the recipe row. Embedding the full recipe -- which contentHash and omitted are already\n// fields of -- satisfies that without inventing a second, narrower shape to keep in sync with it.\nexport const providerSessionStartedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"PROVIDER_SESSION_STARTED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z.object({ session: providerSessionSchema, recipe: contextPackRecipeSchema }).strict(),\n});\nexport const checkpointPublishedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"CHECKPOINT_PUBLISHED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z.object({ checkpoint: checkpointSchema }).strict(),\n});\n// Emitted once per ProviderSession, on the first occupancy report that crosses\n// handoffThreshold (spec §6.2). Carries the usage that triggered it so the audit trail shows why\n// the session started winding down, not just that it did.\nexport const contextHandoffRequestedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"CONTEXT_HANDOFF_REQUESTED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z.object({ session: providerSessionSchema, usage: contextWindowUsageSchema }).strict(),\n});\nexport const providerSessionEndedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"PROVIDER_SESSION_ENDED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z.object({ session: providerSessionSchema }).strict(),\n});\n// Spec §D8 and §6.1 step 3: the required sections did not fit the pack budget, so no session was\n// started at all. The byte figures are on the event rather than only in a log line because \"the\n// required core does not fit\" is only actionable to an owner who can see by how much -- and because\n// no ContextPackRecipe exists to carry them: the assembly stopped before producing one.\nexport const contextFloorExceededEventSchema = eventBaseSchema.extend({\n type: z.literal(\"CONTEXT_FLOOR_EXCEEDED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z\n .object({\n run: pipelineRunSchema,\n stageAttempt: stageAttemptSchema,\n sessionOrdinal: z.number().int().positive(),\n requiredBytes: z.number().int().nonnegative(),\n budgetBytes: z.number().int().nonnegative(),\n budgetTokens: z.number().int().positive(),\n })\n .strict(),\n});\nconst commandBaseSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n commandId: opaqueIdSchema,\n correlationId: correlationIdSchema,\n actor: actorSchema,\n})\n .strict();\nexport const startMockPipelineCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"START_MOCK_PIPELINE\"),\n payload: z\n .object({\n workItemId: opaqueIdSchema,\n expectedVersion: z.number().int().positive(),\n template: workflowTemplateSchema,\n budget: z\n .object({\n maxEstimatedTokens: z.number().int().positive(),\n warningThresholds: z.array(budgetThresholdSchema).min(1).max(10),\n })\n .strict(),\n })\n .strict(),\n});\nexport const markWorkflowDispatchStartedCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"MARK_WORKFLOW_DISPATCH_STARTED\"),\n payload: z.object({ dispatchId: opaqueIdSchema }).strict(),\n});\nconst applyProviderOutcomePayloadSchema = z\n .object({\n dispatchId: opaqueIdSchema,\n /**\n * The adapter identity measured by the daemon, not a claim inside untrusted provider output.\n *\n * Optional only for append-only command-receipt compatibility: commands recorded before D2\n * have no such member and must keep the exact parsed shape their input hash was computed from.\n * Every new production caller supplies it; the domain reads an absent historical value as\n * MOCK, which was the only EvidenceArtifact provider the old schema could persist.\n */\n provider: providerIdSchema.optional(),\n outcome: providerOutcomeSchema,\n template: workflowTemplateSchema,\n /**\n * The stage-end tree label (see `stageAttemptSchema.resultTree`), measured by the daemon just\n * before it applies the outcome.\n *\n * Beside `outcome` rather than inside it, because it is not the provider's claim: `outcome` is\n * untrusted output from an agent, while this is Loomrail's own reading of the worktree through\n * `treeOfWorktree` (`@loomrail/workspace`) -- a baseline-independent reading, not the\n * `summariseChanges` machinery the owner-facing change summary uses, because no summary is\n * produced here for a tree to be paired with. Folding it into the COMPLETED outcome would let a\n * provider name the tree its own work is recorded against.\n *\n * Required and nullable rather than optional: every caller states what it measured, `null`\n * included, so a caller that simply forgot is caught by the schema instead of being recorded as\n * \"no tree was there\". Only the COMPLETED branch stores it -- the others end a session or park\n * the stage on a question, neither of which is a stage ending.\n */\n resultTree: treeShaSchema.nullable(),\n})\n .strict();\nexport const applyProviderOutcomeCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"APPLY_PROVIDER_OUTCOME\"),\n payload: applyProviderOutcomePayloadSchema,\n});\n// \"APPLY_MOCK_PROVIDER_OUTCOME\" is the historical discriminant: commands already recorded under\n// that name (the commands table is append-only audit history and is not rewritten) must still\n// parse when the same commandId is resubmitted, so the receipt cache can return the cached\n// result. Kept as a distinct single-literal schema (rather than folded into\n// applyProviderOutcomeCommandSchema's type as a two-value literal) so every member of\n// stateCommandSchema keeps a single-literal discriminant and TypeScript can still narrow it away\n// completely once handled. Nothing constructs a fresh command with this type going forward.\nexport const legacyApplyMockProviderOutcomeCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"APPLY_MOCK_PROVIDER_OUTCOME\"),\n payload: applyProviderOutcomePayloadSchema,\n});\nexport const answerHumanRequestCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"ANSWER_HUMAN_REQUEST\"),\n payload: z\n .object({\n humanRequestId: opaqueIdSchema,\n expectedVersion: z.number().int().positive(),\n answer: humanRequestAnswerSchema,\n })\n .strict(),\n});\nconst pipelineControlPayloadSchema = z\n .object({\n pipelineRunId: opaqueIdSchema,\n expectedVersion: z.number().int().positive(),\n})\n .strict();\nexport const pausePipelineCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"PAUSE_PIPELINE\"),\n payload: pipelineControlPayloadSchema,\n});\nexport const resumePipelineCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"RESUME_PIPELINE\"),\n payload: pipelineControlPayloadSchema,\n});\nexport const cancelPipelineCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"CANCEL_PIPELINE\"),\n payload: pipelineControlPayloadSchema,\n});\nexport const approveBudgetOverrideCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"APPROVE_BUDGET_OVERRIDE\"),\n payload: pipelineControlPayloadSchema.extend({\n maxEstimatedTokens: z.number().int().positive(),\n }),\n});\nexport const reconcileWorkflowsCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"RECONCILE_WORKFLOWS\"),\n payload: z.object({}).strict(),\n});\nexport const resolveAcceptanceCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"RESOLVE_ACCEPTANCE\"),\n payload: z\n .object({\n acceptancePackageId: opaqueIdSchema,\n expectedVersion: z.number().int().positive(),\n expectedRunVersion: z.number().int().positive(),\n action: acceptanceActionSchema,\n reason: descriptionSchema.nullable(),\n })\n .strict(),\n});\n// What START_PROVIDER_SESSION's caller submits for the recipe: context-assembly's\n// ContextPackRecipeDraft (sections/omitted/estimatedTokens/budgetTokens, the assembler's own\n// output) plus the fields the assembler cannot know -- templateId/templateVersion/specSource come\n// from the stage's ContextPackSpec, contentHash from the assembled ContextPack, estimateQuality\n// from the caller's window-size source. Everything else (id, providerSessionId, createdAt) is\n// assigned by the persistence layer that writes this alongside the ProviderSession (spec §6.1 step\n// 4). Named distinctly from context-assembly's ContextPackRecipeDraft -- the two are different\n// shapes sharing a concept (10 fields here vs. 4 there), and collapsing the names would send a\n// reader through StartProviderSessionCommand[\"payload\"][\"recipe\"] to find this instead of\n// importing it directly.\nexport const contextPackRecipeInputSchema = contextPackRecipeSchema.omit({\n id: true,\n providerSessionId: true,\n createdAt: true,\n});\nexport const startProviderSessionCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"START_PROVIDER_SESSION\"),\n payload: z\n .object({\n stageAttemptId: opaqueIdSchema,\n recipe: contextPackRecipeInputSchema,\n // Optional, not required: a pid is never known at START time -- `ProviderAdapter.start()`\n // has not even been called yet here, and it is `start()` that spawns the process (see\n // `ProviderSessionListener.onProcessStarted` in @loomrail/provider-core). Every real caller\n // omits it and the session is recorded with no known process until (and unless)\n // `RECORD_PROVIDER_SESSION_PROCESS` reports one later. A caller that does know a pid up\n // front -- a test -- can still record it here. Omitted and `null` are treated identically by\n // the command handler; the ProviderSession itself always carries `pid` as `null`, not absent.\n pid: providerSessionProcessPidSchema.nullable().optional(),\n })\n .strict(),\n});\n// The one durable write `ProviderSessionListener.onProcessStarted` produces (see\n// @loomrail/provider-core): a live adapter spawns its child deep inside `start()`, after\n// START_PROVIDER_SESSION has already run and the session already exists, so there is no way to\n// carry a pid on that command -- it has to arrive as a follow-up write to the session it belongs\n// to. Kept as its own command rather than folded into another one: unlike checkpoints or usage\n// reports, a pid is reported at most once per session and has no natural host command to ride\n// along with.\nexport const recordProviderSessionProcessCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"RECORD_PROVIDER_SESSION_PROCESS\"),\n payload: z\n .object({\n providerSessionId: opaqueIdSchema,\n pid: providerSessionProcessPidSchema,\n })\n .strict(),\n});\nexport const publishCheckpointCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"PUBLISH_CHECKPOINT\"),\n payload: z\n .object({\n providerSessionId: opaqueIdSchema,\n checkpoint: checkpointDraftSchema,\n })\n .strict(),\n});\nexport const endProviderSessionCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"END_PROVIDER_SESSION\"),\n payload: z\n .object({\n providerSessionId: opaqueIdSchema,\n endReason: providerSessionEndReasonSchema,\n // Whether the provider actually began running this session. Spec §6.5's unproductive-session\n // guard is about an agent that ran and published nothing; a session the adapter refused to\n // start never had the chance, and §7's pack-size branch owns that case instead. Recording the\n // fact rather than the rule keeps `endReason` truthful in the audit log: the session really\n // was interrupted, it just was not the agent's silence that interrupted it.\n providerStarted: z.boolean(),\n })\n .strict()\n .refine((payload) => payload.providerStarted || payload.endReason === \"INTERRUPTED\", \"A session the provider never started can only have ended as INTERRUPTED\"),\n});\n// Spec §6.2. The caller supplies the occupancy report and the threshold it is judged against;\n// whether this is the first crossing (and therefore whether a handoff is requested at all) is\n// decided from the stored session, not from the caller, so a repeated report is a safe no-op.\nexport const requestContextHandoffCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"REQUEST_CONTEXT_HANDOFF\"),\n payload: z\n .object({\n providerSessionId: opaqueIdSchema,\n usage: contextWindowUsageSchema,\n handoffThreshold: budgetThresholdSchema,\n })\n .strict(),\n});\n// The two ways a session fails to happen at all, both of which spec §D8/§7 resolve the same way:\n// a HARD pause plus a question to the owner. Kept as one command with a discriminated reason\n// rather than two near-identical commands, because everything except the wording of the question\n// and one event is shared.\nexport const stageAttemptHardPauseReasonSchema = z.discriminatedUnion(\"type\", [\n z\n .object({\n type: z.literal(\"CONTEXT_FLOOR_EXCEEDED\"),\n sessionOrdinal: z.number().int().positive(),\n requiredBytes: z.number().int().nonnegative(),\n budgetBytes: z.number().int().nonnegative(),\n budgetTokens: z.number().int().positive(),\n })\n .strict(),\n z\n .object({\n type: z.literal(\"PROVIDER_REJECTED_PACK\"),\n sessionOrdinal: z.number().int().positive(),\n })\n .strict(),\n // A provider failure that is not a size rejection. Kept apart from PROVIDER_REJECTED_PACK so a\n // transient error is never answered by shrinking the pack, and so the owner is not asked about\n // a context size that had nothing to do with it (spec §6.3 routes failures to existing handling).\n z\n .object({\n type: z.literal(\"PROVIDER_START_FAILED\"),\n sessionOrdinal: z.number().int().positive(),\n })\n .strict(),\n // The session loop's own backstop (spec §6.5). Not a way a session fails to happen, but the one\n // way the attempt stops without any session having failed: the provider kept handing off\n // productively and the attempt never finished. It resolves the same way as the others -- pause,\n // withdraw the dispatch, ask the owner -- because the alternative is a loop that logs and leaves\n // its dispatch PENDING for the drain to pick up again.\n z\n .object({\n type: z.literal(\"SESSION_LIMIT_REACHED\"),\n sessionOrdinal: z.number().int().positive(),\n maxSessions: z.number().int().positive(),\n })\n .strict(),\n]);\n// Spec §7's one automatic retry after a rejected pack. A command of its own rather than a flag on\n// END_PROVIDER_SESSION: the reduction is a durable state change on the StageAttempt with its own\n// audit event, and folding it into the session's end would hide it inside a command about\n// something else.\nexport const reduceContextPackShareCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"REDUCE_CONTEXT_PACK_SHARE\"),\n payload: z.object({ stageAttemptId: opaqueIdSchema }).strict(),\n});\nexport const hardPauseStageAttemptCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"HARD_PAUSE_STAGE_ATTEMPT\"),\n payload: z\n .object({\n stageAttemptId: opaqueIdSchema,\n reason: stageAttemptHardPauseReasonSchema,\n })\n .strict(),\n});\nexport const pipelineStartedResultSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n type: z.literal(\"PIPELINE_STARTED\"),\n replayed: z.boolean(),\n workItemId: opaqueIdSchema,\n run: pipelineRunSchema,\n stageAttempt: stageAttemptSchema,\n budgetPolicy: budgetPolicySchema,\n dispatch: workflowDispatchSchema,\n events: z.array(pipelineStartedEventSchema),\n})\n .strict();\nexport const workflowDispatchStartedResultSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n type: z.literal(\"WORKFLOW_DISPATCH_STARTED\"),\n replayed: z.boolean(),\n workItemId: opaqueIdSchema,\n run: pipelineRunSchema,\n stageAttempt: stageAttemptSchema,\n dispatch: workflowDispatchSchema,\n events: z.array(stageAttemptChangedEventSchema),\n})\n .strict();\nconst providerOutcomeEventSchema = z.discriminatedUnion(\"type\", [\n stageAttemptChangedEventSchema,\n humanRequestOpenedEventSchema,\n usageRecordedEventSchema,\n budgetThresholdReachedEventSchema,\n pipelinePausedEventSchema,\n evidenceArtifactRecordedEventSchema,\n acceptanceRequestedEventSchema,\n pipelineCompletedEventSchema,\n]);\nexport const mockProviderOutcomeAppliedResultSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n type: z.literal(\"MOCK_PROVIDER_OUTCOME_APPLIED\"),\n replayed: z.boolean(),\n workItemId: opaqueIdSchema,\n run: pipelineRunSchema,\n stageAttempt: stageAttemptSchema,\n usageRecords: z.array(usageRecordSchema),\n artifacts: z.array(evidenceArtifactSchema),\n acceptancePackage: acceptancePackageSchema.nullable(),\n events: z.array(providerOutcomeEventSchema),\n})\n .strict();\nexport const humanRequestAnsweredResultSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n type: z.literal(\"HUMAN_REQUEST_ANSWERED\"),\n replayed: z.boolean(),\n workItemId: opaqueIdSchema,\n request: humanRequestSchema,\n decision: decisionSchema,\n dispatch: workflowDispatchSchema,\n events: z.array(humanRequestResolvedEventSchema),\n})\n .strict();\nconst pipelineControlEventSchema = z.discriminatedUnion(\"type\", [\n pipelinePausedEventSchema,\n pipelineResumedEventSchema,\n pipelineCancelledEventSchema,\n]);\nexport const pipelineControlAppliedResultSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n type: z.literal(\"PIPELINE_CONTROL_APPLIED\"),\n replayed: z.boolean(),\n action: z.enum([\"PAUSE\", \"RESUME\", \"CANCEL\"]),\n workItemId: opaqueIdSchema,\n run: pipelineRunSchema,\n stageAttempt: stageAttemptSchema,\n dispatch: workflowDispatchSchema.nullable(),\n events: z.array(pipelineControlEventSchema),\n})\n .strict();\nexport const budgetOverrideApprovedResultSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n type: z.literal(\"BUDGET_OVERRIDE_APPROVED\"),\n replayed: z.boolean(),\n workItemId: opaqueIdSchema,\n run: pipelineRunSchema,\n previousStageAttempt: stageAttemptSchema,\n stageAttempt: stageAttemptSchema,\n budgetPolicy: budgetPolicySchema,\n dispatch: workflowDispatchSchema,\n events: z.array(budgetOverrideApprovedEventSchema),\n})\n .strict();\nexport const workflowsReconciledResultSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n type: z.literal(\"WORKFLOWS_RECONCILED\"),\n replayed: z.boolean(),\n recoveryReports: z.array(recoveryReportSchema),\n // Spec §6.4 makes a daemon restart the ordinary end of a ProviderSession, so reconciliation\n // now closes orphaned sessions as well as orphaned dispatches and reports both kinds of event.\n interruptedSessions: z.array(providerSessionSchema),\n // Task 10 (spec §6, \"Восстановление\"): every READY workspace whose worktree directory was\n // found gone or prunable at this startup, now moved to ORPHANED. Never a resurrection (AD-008)\n // -- nothing here recreates a workspace or touches the branch it leaves behind (D12).\n orphanedWorkspaces: z.array(workItemWorkspaceSchema),\n events: z.array(z.discriminatedUnion(\"type\", [\n recoveryReportCreatedEventSchema,\n providerSessionEndedEventSchema,\n workItemWorkspaceOrphanedEventSchema,\n ])),\n})\n .strict();\nconst acceptanceResolutionEventSchema = z.discriminatedUnion(\"type\", [\n humanRequestResolvedEventSchema,\n acceptanceResolvedEventSchema,\n pipelineCompletedEventSchema,\n]);\nexport const acceptanceResolvedResultSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n type: z.literal(\"ACCEPTANCE_RESOLVED\"),\n replayed: z.boolean(),\n action: acceptanceActionSchema,\n workItemId: opaqueIdSchema,\n run: pipelineRunSchema,\n stageAttempt: stageAttemptSchema,\n acceptancePackage: acceptancePackageSchema,\n request: humanRequestSchema,\n decision: decisionSchema,\n events: z.array(acceptanceResolutionEventSchema),\n})\n .strict();\nexport const providerSessionStartedResultSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n type: z.literal(\"PROVIDER_SESSION_STARTED\"),\n replayed: z.boolean(),\n workItemId: opaqueIdSchema,\n session: providerSessionSchema,\n recipe: contextPackRecipeSchema,\n events: z.array(providerSessionStartedEventSchema),\n})\n .strict();\n// A pid is current state, not a business event -- nothing an owner reads through the audit log\n// needs to know which OS process a session used, only that reconciliation can find it. Every other\n// command result in this union carries `events`; this one keeps the field for shape uniformity but\n// types it `z.array(z.never())`, which only the empty array can ever satisfy, so the schema itself\n// states that this command never produces one rather than leaving `[]` looking like an omission.\nexport const providerSessionProcessRecordedResultSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n type: z.literal(\"PROVIDER_SESSION_PROCESS_RECORDED\"),\n replayed: z.boolean(),\n workItemId: opaqueIdSchema,\n session: providerSessionSchema,\n events: z.array(z.never()),\n})\n .strict();\nexport const checkpointPublishedResultSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n type: z.literal(\"CHECKPOINT_PUBLISHED\"),\n replayed: z.boolean(),\n workItemId: opaqueIdSchema,\n checkpoint: checkpointSchema,\n events: z.array(checkpointPublishedEventSchema),\n})\n .strict();\n// Ending a session is never only a session-level write: spec §6.5 makes the unproductive-session\n// counter part of the same transaction, and the second unproductive session in a row also pauses\n// the run and opens a question to the owner. `nextSessionOrdinal` is the caller-facing answer to\n// \"does another session follow?\" -- null covers both \"the stage finished\" and \"the attempt was\n// hard-paused\", which the caller distinguishes by `stageAttempt.status`.\nexport const providerSessionEndedResultSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n type: z.literal(\"PROVIDER_SESSION_ENDED\"),\n replayed: z.boolean(),\n workItemId: opaqueIdSchema,\n session: providerSessionSchema,\n stageAttempt: stageAttemptSchema,\n request: humanRequestSchema.nullable(),\n nextSessionOrdinal: z.number().int().positive().nullable(),\n events: z.array(z.discriminatedUnion(\"type\", [\n providerSessionEndedEventSchema,\n stageAttemptChangedEventSchema,\n pipelinePausedEventSchema,\n humanRequestOpenedEventSchema,\n ])),\n})\n .strict();\nexport const contextHandoffRequestedResultSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n type: z.literal(\"CONTEXT_HANDOFF_REQUESTED\"),\n replayed: z.boolean(),\n workItemId: opaqueIdSchema,\n session: providerSessionSchema,\n // False when the threshold had already been crossed, or the session had already ended: the\n // caller uses it to decide whether to actually ask the adapter to wind down and to arm the\n // deadline, so a repeated occupancy report does neither twice.\n requested: z.boolean(),\n events: z.array(contextHandoffRequestedEventSchema),\n})\n .strict();\nexport const contextPackShareReducedResultSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n type: z.literal(\"CONTEXT_PACK_SHARE_REDUCED\"),\n replayed: z.boolean(),\n workItemId: opaqueIdSchema,\n stageAttempt: stageAttemptSchema,\n events: z.array(stageAttemptChangedEventSchema),\n})\n .strict();\nexport const stageAttemptHardPausedResultSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n type: z.literal(\"STAGE_ATTEMPT_HARD_PAUSED\"),\n replayed: z.boolean(),\n workItemId: opaqueIdSchema,\n run: pipelineRunSchema,\n stageAttempt: stageAttemptSchema,\n request: humanRequestSchema,\n events: z.array(z.discriminatedUnion(\"type\", [\n contextFloorExceededEventSchema,\n stageAttemptChangedEventSchema,\n pipelinePausedEventSchema,\n humanRequestOpenedEventSchema,\n ])),\n})\n .strict();\nexport const startMockPipelineRequestSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n commandId: opaqueIdSchema,\n expectedVersion: z.number().int().positive(),\n})\n .strict();\nexport const answerHumanRequestRequestSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n commandId: opaqueIdSchema,\n expectedVersion: z.number().int().positive(),\n answer: humanRequestAnswerSchema,\n})\n .strict();\nexport const pipelineControlRequestSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n commandId: opaqueIdSchema,\n expectedVersion: z.number().int().positive(),\n})\n .strict();\nexport const budgetOverrideRequestSchema = pipelineControlRequestSchema.extend({\n maxEstimatedTokens: z.number().int().positive(),\n});\nexport const resolveAcceptanceRequestSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n commandId: opaqueIdSchema,\n expectedVersion: z.number().int().positive(),\n expectedRunVersion: z.number().int().positive(),\n action: acceptanceActionSchema,\n reason: descriptionSchema.nullable().default(null),\n})\n .strict();\nexport const workflowSnapshotSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n run: pipelineRunSchema.nullable(),\n stageAttempts: z.array(stageAttemptSchema),\n humanRequests: z.array(humanRequestSchema),\n decisions: z.array(decisionSchema),\n budgetPolicies: z.array(budgetPolicySchema),\n usageRecords: z.array(usageRecordSchema),\n recoveryReports: z.array(recoveryReportSchema),\n artifacts: z.array(evidenceArtifactSchema),\n acceptancePackage: acceptancePackageSchema.nullable(),\n})\n .strict();\nexport const humanRequestsResponseSchema = z\n .object({ schemaVersion: schemaVersionSchema, humanRequests: z.array(humanRequestSchema) })\n .strict();\n// Spec §D5's nesting, read back for the Task Cockpit (Task 12). Kept out of workflowSnapshotSchema\n// deliberately, matching persistence-sqlite's LIST_PROVIDER_SESSIONS: the snapshot is fetched on\n// every board render, and an attempt's session history grows without bound.\n// `peakContextWindowUsage` is keyed by ProviderSession id and carries the highest occupancy each\n// session has been observed at (spec §6.2 -- occupancy is saved on every report, not only the one\n// that crosses the handoff threshold, and the highest of them is what is kept). Deliberately the\n// peak and not the current reading: it answers \"how full did this session get\", which is what\n// explains a cut, and it does not move under a provider that compacts its own window. A session\n// with no entry has never had its window measured, which is not the same as one measured at zero.\n// For a session that asked to wind down the figure is the reading at handoff rather than the true\n// peak, because reporting stops there -- see the note in packages/persistence-sqlite/src/types.ts.\n// The cockpit labels that case \"at handoff\" and never as a peak, so the wording stays honest.\nexport const providerSessionsResponseSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n sessions: z.array(providerSessionSchema),\n checkpoints: z.array(checkpointSchema),\n peakContextWindowUsage: z.record(opaqueIdSchema, contextWindowUsageSchema),\n})\n .strict();\n// The daemon runs a single provider adapter for its whole lifetime, so this describes \"the provider\n// a session would run on right now\" rather than a per-session fact. Still a trimmed projection of\n// the full ProviderCapabilities shape provider-core owns -- apps/web has no reason to depend on\n// that package -- but it now carries the three fields milestone A2 added and never propagated:\n// without them the owner cannot see which stages the selected adapter serves, or that its CLI is\n// missing from this machine, until a dispatch is refused.\nexport const providerCapabilitiesResponseSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n provider: z.string().trim().min(1).max(50),\n // `capabilities().start`: whether the adapter's CLI was found on this machine at all. A\n // separate claim from `stages` -- an adapter declares what it would serve if it could run, and\n // this says whether it currently can.\n start: z.boolean(),\n stages: z.array(workflowStageSchema).min(1).max(20),\n checkpointOnRequest: z.boolean(),\n contextWindowReporting: z.boolean(),\n costReporting: z.boolean(),\n})\n .strict();\n//# sourceMappingURL=workflow.js.map","import { z } from \"zod\";\nimport { actorSchema, correlationIdSchema, opaqueIdSchema, schemaVersionSchema, utcTimestampSchema, } from \"./shared.js\";\nimport { acceptanceRequestedEventSchema, acceptanceResolvedEventSchema, acceptanceResolvedResultSchema, approveBudgetOverrideCommandSchema, answerHumanRequestCommandSchema, applyProviderOutcomeCommandSchema, legacyApplyMockProviderOutcomeCommandSchema, budgetOverrideApprovedEventSchema, budgetOverrideApprovedResultSchema, budgetThresholdReachedEventSchema, cancelPipelineCommandSchema, checkpointPublishedEventSchema, checkpointPublishedResultSchema, contextFloorExceededEventSchema, contextHandoffRequestedEventSchema, contextHandoffRequestedResultSchema, contextPackShareReducedResultSchema, endProviderSessionCommandSchema, hardPauseStageAttemptCommandSchema, humanRequestAnsweredResultSchema, humanRequestOpenedEventSchema, humanRequestResolvedEventSchema, evidenceArtifactRecordedEventSchema, markWorkflowDispatchStartedCommandSchema, mockProviderOutcomeAppliedResultSchema, pausePipelineCommandSchema, pipelineCancelledEventSchema, pipelineCompletedEventSchema, pipelineControlAppliedResultSchema, pipelinePausedEventSchema, pipelineResumedEventSchema, pipelineStartedEventSchema, pipelineStartedResultSchema, providerSessionEndedEventSchema, providerSessionEndedResultSchema, providerSessionProcessRecordedResultSchema, providerSessionStartedEventSchema, providerSessionStartedResultSchema, publishCheckpointCommandSchema, reconcileWorkflowsCommandSchema, recordProviderSessionProcessCommandSchema, reduceContextPackShareCommandSchema, recoveryReportCreatedEventSchema, resolveAcceptanceCommandSchema, resumePipelineCommandSchema, requestContextHandoffCommandSchema, stageAttemptChangedEventSchema, stageAttemptHardPausedResultSchema, startMockPipelineCommandSchema, startProviderSessionCommandSchema, usageRecordedEventSchema, workflowDispatchStartedResultSchema, workflowStageSchema, workflowsReconciledResultSchema, } from \"./workflow.js\";\nimport { acquireWorkspaceLeaseCommandSchema, createWorkItemWorkspaceCommandSchema, markWorkspaceOrphanedCommandSchema, releaseWorkspaceLeaseCommandSchema, workItemWorkspaceCreatedEventSchema, workItemWorkspaceCreatedResultSchema, workItemWorkspaceOrphanedEventSchema, workItemWorkspaceOrphanedResultSchema, workspaceLeaseAcquiredResultSchema, workspaceLeaseReleasedResultSchema, } from \"./workspace.js\";\nexport const fixtureProjectIdSchema = z.enum([\"web-app-a\", \"api-service-b\"]);\nexport const projectStatusSchema = z.enum([\"ACTIVE\", \"ARCHIVED\"]);\nexport const workItemTypeSchema = z.enum([\"EPIC\", \"FEATURE\", \"TASK\", \"BUG\", \"SPIKE\", \"SUBTASK\"]);\nexport const workItemStateSchema = z.enum([\n \"BACKLOG\",\n \"READY\",\n \"IN_PROGRESS\",\n \"BLOCKED\",\n \"DONE\",\n \"CANCELLED\",\n]);\nexport const prioritySchema = z.enum([\"LOW\", \"MEDIUM\", \"HIGH\", \"URGENT\"]);\nexport const riskSchema = z.enum([\"LOW\", \"MEDIUM\", \"HIGH\", \"CRITICAL\"]);\nconst titleSchema = z.string().trim().min(1).max(200);\nconst descriptionSchema = z.string().trim().max(20_000);\n/**\n * A repository path exactly as an owner typed it, before anything has judged it.\n *\n * Bounded only in length, because this is the *request* side: a path that is relative, or points at\n * something that is not a repository, has to reach the daemon so the owner can be told which of\n * those it was. Rejecting it here would collapse both into one \"the request payload is invalid\".\n */\nconst repositoryPathTextSchema = z.string().min(1).max(4_096);\n// Absolute, tested here rather than with `node:path`'s `isAbsolute`, because this package is parsed\n// in the browser as well as in the daemon and must not import a Node builtin -- and because\n// `isAbsolute` answers for the platform it is running on, while a contract has to mean the same\n// thing wherever it is read. Both platform spellings are accepted: a rooted POSIX path, a\n// drive-letter path, and a UNC share, since macOS and Windows are both blocking platforms.\nconst absolutePathPattern = /^(?:[/\\\\]|[A-Za-z]:[/\\\\])/;\n/**\n * A repository path a Project may actually *record*.\n *\n * Absolute, without exception. A relative path has no meaning outside the process that resolved it:\n * typing `.` into the Settings field used to register whatever directory the daemon happened to be\n * launched from, silently and with a 200, while every field description promised an absolute path.\n * A Project's path is read back by a daemon started from somewhere else entirely -- a launcher, a\n * login item, a different shell -- so a stored relative path names a different repository on the\n * next start than it did on this one.\n *\n * Enforced on the command and on the Project itself rather than only at the HTTP edge, so no route,\n * fixture or test can put a relative path into the database by a path that skips the edge check.\n */\nconst repositoryPathSchema = repositoryPathTextSchema.regex(absolutePathPattern, \"A repository path must be absolute\");\nconst acceptanceCriteriaSchema = z.array(z.string().trim().min(1).max(500)).max(50);\nexport const projectSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n id: opaqueIdSchema,\n workspaceId: opaqueIdSchema,\n // Nullable, not optional: a Project registered by path is a local Git repository the owner\n // named, and it genuinely has no bundled fixture behind it (spec\n // docs/plans/13-e1-workspace-execution-spec.ru.md §4). Absent would read as \"not recorded\";\n // null records the fact that there is nothing to record -- the same discipline\n // workItemWorkspaceSchema's baseCommit and snapshotCommit follow in workspace.ts.\n fixtureId: fixtureProjectIdSchema.nullable(),\n name: titleSchema,\n repositoryPath: repositoryPathSchema,\n status: projectStatusSchema,\n version: z.number().int().positive(),\n createdAt: utcTimestampSchema,\n updatedAt: utcTimestampSchema,\n})\n .strict();\nexport const workItemSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n id: opaqueIdSchema,\n projectId: opaqueIdSchema,\n parentId: opaqueIdSchema.nullable(),\n type: workItemTypeSchema,\n title: titleSchema,\n description: descriptionSchema,\n state: workItemStateSchema,\n currentStage: workflowStageSchema.nullable(),\n priority: prioritySchema,\n risk: riskSchema,\n acceptanceCriteria: acceptanceCriteriaSchema,\n version: z.number().int().positive(),\n createdAt: utcTimestampSchema,\n updatedAt: utcTimestampSchema,\n})\n .strict();\nconst eventBaseSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n sequence: z.number().int().positive(),\n id: opaqueIdSchema,\n aggregateId: opaqueIdSchema,\n projectId: opaqueIdSchema,\n actor: actorSchema,\n occurredAt: utcTimestampSchema,\n correlationId: correlationIdSchema,\n})\n .strict();\n/**\n * Records that, at this moment, this Project is registered at this repository path.\n *\n * REPOINT_FIXTURE_PROJECT emits this too, and deliberately not an event type of its own. What the\n * repoint changes is exactly what this event already carries -- the Project, path included -- and\n * the path it moved *off* is not lost by reusing the type: it is the `repositoryPath` on this same\n * Project's earlier PROJECT_REGISTERED event, which the append-only log still holds. A second event\n * type would have bought a field the log already answers, at the price of rebuilding the `events`\n * CHECK constraint (migration 0011's shape) on the owner's real database.\n */\nexport const projectRegisteredEventSchema = eventBaseSchema.extend({\n type: z.literal(\"PROJECT_REGISTERED\"),\n aggregateType: z.literal(\"PROJECT\"),\n data: z.object({ project: projectSchema }).strict(),\n});\nexport const workItemCreatedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"WORK_ITEM_CREATED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z.object({ workItem: workItemSchema }).strict(),\n});\nexport const workItemChangedFieldSchema = z.enum([\n \"title\",\n \"description\",\n \"priority\",\n \"risk\",\n \"acceptanceCriteria\",\n]);\nexport const workItemUpdatedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"WORK_ITEM_UPDATED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z\n .object({\n workItem: workItemSchema,\n changedFields: z.array(workItemChangedFieldSchema).min(1),\n })\n .strict(),\n});\nexport const workItemStateChangedEventSchema = eventBaseSchema.extend({\n type: z.literal(\"WORK_ITEM_STATE_CHANGED\"),\n aggregateType: z.literal(\"WORK_ITEM\"),\n data: z\n .object({\n workItem: workItemSchema,\n previousState: workItemStateSchema,\n })\n .strict(),\n});\nexport const domainEventSchema = z.discriminatedUnion(\"type\", [\n projectRegisteredEventSchema,\n workItemCreatedEventSchema,\n workItemUpdatedEventSchema,\n workItemStateChangedEventSchema,\n pipelineStartedEventSchema,\n stageAttemptChangedEventSchema,\n humanRequestOpenedEventSchema,\n humanRequestResolvedEventSchema,\n usageRecordedEventSchema,\n budgetThresholdReachedEventSchema,\n pipelinePausedEventSchema,\n pipelineResumedEventSchema,\n pipelineCancelledEventSchema,\n budgetOverrideApprovedEventSchema,\n recoveryReportCreatedEventSchema,\n evidenceArtifactRecordedEventSchema,\n acceptanceRequestedEventSchema,\n acceptanceResolvedEventSchema,\n pipelineCompletedEventSchema,\n providerSessionStartedEventSchema,\n checkpointPublishedEventSchema,\n contextHandoffRequestedEventSchema,\n providerSessionEndedEventSchema,\n contextFloorExceededEventSchema,\n workItemWorkspaceCreatedEventSchema,\n workItemWorkspaceOrphanedEventSchema,\n]);\nconst commandBaseSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n commandId: opaqueIdSchema,\n correlationId: correlationIdSchema,\n actor: actorSchema,\n})\n .strict();\n/**\n * Registers a Project at a local Git repository.\n *\n * One command for both ways in, because there is only one thing being recorded: a repository\n * Loomrail may branch. Where the repository came from is data, not a second operation -- a bundled\n * fixture names itself in `fixtureId`, a repository the owner registered by path leaves it null,\n * and everything downstream (the dedupe on id/fixture/path, the PROJECT_REGISTERED event, the row)\n * is identical either way. It was called REGISTER_FIXTURE_PROJECT while a fixture was the only way\n * in; keeping that name over a null `fixtureId` would be a command lying about what it registers.\n */\nexport const registerProjectCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"REGISTER_PROJECT\"),\n payload: z\n .object({\n id: opaqueIdSchema,\n fixtureId: fixtureProjectIdSchema.nullable(),\n name: titleSchema,\n repositoryPath: repositoryPathSchema,\n })\n .strict(),\n});\n/**\n * Moves a fixture-backed Project off the bundled template it still records, onto the repository\n * that template has just been materialised into.\n *\n * Why this exists at all: the two demo Projects were registered before a bundled fixture became a\n * real repository, so their `repository_path` names a directory *inside Loomrail's own checkout*.\n * Migration 0012 carried those paths across verbatim -- correctly, because a migration cannot know\n * the data directory, which is runtime configuration -- and pressing \"Initialize demo workspace\"\n * afterwards materialised the repository and then answered PROJECT_ALREADY_REGISTERED, leaving the\n * fresh repository orphaned on disk and the Project pointing at the template forever. Every stage\n * that needs a workspace is refused at such a path, and no route repaired it.\n *\n * A command of its own rather than a widening of REGISTER_PROJECT, because it is a different claim:\n * that one asserts nothing is registered here yet, this one asserts something is and names both the\n * path it must currently record and the path it should record instead.\n *\n * `expectedRepositoryPath` is the guard, not a convenience. The persistence layer applies this only\n * when the row still carries exactly that path, so a Project the owner registered by path can never\n * be moved by it, and a concurrent registration that already fixed the row is refused rather than\n * silently re-applied.\n */\nexport const repointFixtureProjectCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"REPOINT_FIXTURE_PROJECT\"),\n payload: z\n .object({\n projectId: opaqueIdSchema,\n // Non-nullable, unlike REGISTER_PROJECT's: only a fixture-backed Project can be re-pointed,\n // and requiring the fixture here is half of what keeps a path-registered one out of reach.\n fixtureId: fixtureProjectIdSchema,\n expectedRepositoryPath: repositoryPathSchema,\n repositoryPath: repositoryPathSchema,\n })\n .strict(),\n});\nexport const createWorkItemCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"CREATE_WORK_ITEM\"),\n payload: z\n .object({\n projectId: opaqueIdSchema,\n parentId: opaqueIdSchema.nullable().default(null),\n type: workItemTypeSchema,\n title: titleSchema,\n description: descriptionSchema.default(\"\"),\n priority: prioritySchema.default(\"MEDIUM\"),\n risk: riskSchema.default(\"MEDIUM\"),\n acceptanceCriteria: acceptanceCriteriaSchema.default([]),\n })\n .strict(),\n});\nexport const workItemPatchSchema = z\n .object({\n title: titleSchema.optional(),\n description: descriptionSchema.optional(),\n priority: prioritySchema.optional(),\n risk: riskSchema.optional(),\n acceptanceCriteria: acceptanceCriteriaSchema.optional(),\n})\n .strict()\n .refine((patch) => Object.keys(patch).length > 0, { message: \"At least one field must be updated\" });\nexport const updateWorkItemCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"UPDATE_WORK_ITEM\"),\n payload: z\n .object({\n workItemId: opaqueIdSchema,\n expectedVersion: z.number().int().positive(),\n patch: workItemPatchSchema,\n })\n .strict(),\n});\nexport const moveWorkItemCommandSchema = commandBaseSchema.extend({\n type: z.literal(\"MOVE_WORK_ITEM\"),\n payload: z\n .object({\n workItemId: opaqueIdSchema,\n expectedVersion: z.number().int().positive(),\n targetState: workItemStateSchema,\n })\n .strict(),\n});\nexport const stateCommandSchema = z.discriminatedUnion(\"type\", [\n registerProjectCommandSchema,\n repointFixtureProjectCommandSchema,\n createWorkItemCommandSchema,\n updateWorkItemCommandSchema,\n moveWorkItemCommandSchema,\n startMockPipelineCommandSchema,\n markWorkflowDispatchStartedCommandSchema,\n applyProviderOutcomeCommandSchema,\n legacyApplyMockProviderOutcomeCommandSchema,\n answerHumanRequestCommandSchema,\n pausePipelineCommandSchema,\n resumePipelineCommandSchema,\n cancelPipelineCommandSchema,\n approveBudgetOverrideCommandSchema,\n reconcileWorkflowsCommandSchema,\n resolveAcceptanceCommandSchema,\n startProviderSessionCommandSchema,\n recordProviderSessionProcessCommandSchema,\n publishCheckpointCommandSchema,\n endProviderSessionCommandSchema,\n requestContextHandoffCommandSchema,\n hardPauseStageAttemptCommandSchema,\n reduceContextPackShareCommandSchema,\n createWorkItemWorkspaceCommandSchema,\n acquireWorkspaceLeaseCommandSchema,\n releaseWorkspaceLeaseCommandSchema,\n markWorkspaceOrphanedCommandSchema,\n]);\nconst commandResultBaseSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n replayed: z.boolean(),\n})\n .strict();\nexport const projectRegisteredResultSchema = commandResultBaseSchema.extend({\n type: z.literal(\"PROJECT_REGISTERED\"),\n project: projectSchema,\n event: projectRegisteredEventSchema,\n});\nexport const workItemCreatedResultSchema = commandResultBaseSchema.extend({\n type: z.literal(\"WORK_ITEM_CREATED\"),\n workItem: workItemSchema,\n event: workItemCreatedEventSchema,\n});\nexport const workItemUpdatedResultSchema = commandResultBaseSchema.extend({\n type: z.literal(\"WORK_ITEM_UPDATED\"),\n workItem: workItemSchema,\n event: workItemUpdatedEventSchema,\n});\nexport const workItemMovedResultSchema = commandResultBaseSchema.extend({\n type: z.literal(\"WORK_ITEM_MOVED\"),\n workItem: workItemSchema,\n event: workItemStateChangedEventSchema,\n});\nexport const stateCommandResultSchema = z.discriminatedUnion(\"type\", [\n projectRegisteredResultSchema,\n workItemCreatedResultSchema,\n workItemUpdatedResultSchema,\n workItemMovedResultSchema,\n pipelineStartedResultSchema,\n workflowDispatchStartedResultSchema,\n mockProviderOutcomeAppliedResultSchema,\n humanRequestAnsweredResultSchema,\n pipelineControlAppliedResultSchema,\n budgetOverrideApprovedResultSchema,\n workflowsReconciledResultSchema,\n acceptanceResolvedResultSchema,\n providerSessionStartedResultSchema,\n providerSessionProcessRecordedResultSchema,\n checkpointPublishedResultSchema,\n providerSessionEndedResultSchema,\n contextHandoffRequestedResultSchema,\n stageAttemptHardPausedResultSchema,\n contextPackShareReducedResultSchema,\n workItemWorkspaceCreatedResultSchema,\n workspaceLeaseAcquiredResultSchema,\n workspaceLeaseReleasedResultSchema,\n workItemWorkspaceOrphanedResultSchema,\n]);\nexport const registerFixtureProjectRequestSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n commandId: opaqueIdSchema,\n fixtureId: fixtureProjectIdSchema,\n})\n .strict();\n/**\n * Registering the owner's own repository by path.\n *\n * A separate request from the fixture one rather than a widening of it, because the two share no\n * input: a fixture registration names one of two catalog entries and Loomrail derives the path, the\n * id and the name from the bundled manifest; this one names a path on the owner's disk and derives\n * everything from that. Folding them together would mean a schema with two optional fields and a\n * refinement saying exactly one must be present -- a union at the boundary, standing in for two\n * endpoints, so that the handler could immediately branch back apart.\n *\n * The path is the only field. There is deliberately no `name`: see the daemon's\n * `registerRepositoryProject`, which takes the repository directory's own name.\n *\n * `repositoryPathTextSchema`, not `repositoryPathSchema`: the request accepts what the owner typed\n * so that the daemon can answer *why* it is not usable -- \"this path is not absolute\", \"this is not\n * a repository\", \"this is a directory inside the repository at X\" are three different fixes, and a\n * schema refusal at the edge would give all three the same \"the request payload is invalid\".\n * `repositoryPathSchema` still guards what is ultimately recorded, on the command below.\n */\nexport const registerRepositoryProjectRequestSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n commandId: opaqueIdSchema,\n repositoryPath: repositoryPathTextSchema,\n})\n .strict();\nexport const createWorkItemRequestSchema = createWorkItemCommandSchema.shape.payload\n .omit({ projectId: true })\n .extend({\n schemaVersion: schemaVersionSchema,\n commandId: opaqueIdSchema,\n projectId: opaqueIdSchema,\n})\n .strict();\nexport const updateWorkItemRequestSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n commandId: opaqueIdSchema,\n expectedVersion: z.number().int().positive(),\n patch: workItemPatchSchema,\n})\n .strict();\nexport const moveWorkItemRequestSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n commandId: opaqueIdSchema,\n expectedVersion: z.number().int().positive(),\n targetState: workItemStateSchema,\n})\n .strict();\n/**\n * Whether a Project's recorded `repositoryPath` is, right now, the top level of a Git repository.\n *\n * A Project is a durable record and this is a fact about the filesystem this minute, so it is not a\n * field of `projectSchema`: it is never stored, never carried on an event, and it can be true one\n * start and false the next without the Project having changed at all. It rides on the list response\n * because the list is the one place the owner sees their Projects, and a Project whose repository\n * has gone is otherwise indistinguishable from a healthy one -- the two demo Projects on a database\n * that predates E1 record a path inside Loomrail's own checkout, every IMPLEMENT and QA on them is\n * refused there, and nothing in the UI said so.\n */\nexport const projectRepositoryStatusSchema = z.enum([\"READY\", \"UNUSABLE\"]);\nexport const listedProjectSchema = projectSchema\n .extend({ repositoryStatus: projectRepositoryStatusSchema })\n .strict();\nexport const projectsResponseSchema = z\n .object({ schemaVersion: schemaVersionSchema, projects: z.array(listedProjectSchema) })\n .strict();\nexport const workItemResponseSchema = z\n .object({ schemaVersion: schemaVersionSchema, workItem: workItemSchema })\n .strict();\nexport const workItemsResponseSchema = z\n .object({ schemaVersion: schemaVersionSchema, workItems: z.array(workItemSchema) })\n .strict();\nexport const eventPageDirectionSchema = z.enum([\"ASC\", \"DESC\"]);\nexport const eventsResponseSchema = z\n .object({\n schemaVersion: schemaVersionSchema,\n events: z.array(domainEventSchema),\n nextSequence: z.number().int().nonnegative(),\n hasMore: z.boolean(),\n})\n .strict();\n//# sourceMappingURL=work-management.js.map","import { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nconst paths = {\n add: [\"M12 5v14\", \"M5 12h14\"],\n agents: [\n \"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2\",\n \"M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8\",\n \"M22 21v-2a4 4 0 0 0-3-3.87\",\n \"M16 3.13a4 4 0 0 1 0 7.75\",\n ],\n board: [\n \"M1 2.6c0-.56 0-.84.109-1.054a1 1 0 0 1 .437-.437C1.76 1 2.04 1 2.6 1h2.8c.56 0 .84 0 1.054.109a1 1 0 0 1 .437.437C7 1.76 7 2.04 7 2.6v.8c0 .56 0 .84-.109 1.054a1 1 0 0 1-.437.437C6.24 5 5.96 5 5.4 5H2.6c-.56 0-.84 0-1.054-.109a1 1 0 0 1-.437-.437C1 4.24 1 3.96 1 3.4v-.8ZM9 2.6c0-.56 0-.84.109-1.054a1 1 0 0 1 .437-.437C9.76 1 10.04 1 10.6 1h2.8c.56 0 .84 0 1.054.109a1 1 0 0 1 .437.437C15 1.76 15 2.04 15 2.6v.8c0 .56 0 .84-.109 1.054a1 1 0 0 1-.437.437C14.24 5 13.96 5 13.4 5h-2.8c-.56 0-.84 0-1.054-.109a1 1 0 0 1-.437-.437C9 4.24 9 3.96 9 3.4v-.8ZM1 7.6c0-.56 0-.84.109-1.054a1 1 0 0 1 .437-.437C1.76 6 2.04 6 2.6 6h2.8c.56 0 .84 0 1.054.109a1 1 0 0 1 .437.437C7 6.76 7 7.04 7 7.6v.8c0 .56 0 .84-.109 1.054a1 1 0 0 1-.437.437C6.24 10 5.96 10 5.4 10H2.6c-.56 0-.84 0-1.054-.109a1 1 0 0 1-.437-.437C1 9.24 1 8.96 1 8.4v-.8ZM9 7.6c0-.56 0-.84.109-1.054a1 1 0 0 1 .437-.437C9.76 6 10.04 6 10.6 6h2.8c.56 0 .84 0 1.054.109a1 1 0 0 1 .437.437C15 6.76 15 7.04 15 7.6v.8c0 .56 0 .84-.109 1.054a1 1 0 0 1-.437.437C14.24 10 13.96 10 13.4 10h-2.8c-.56 0-.84 0-1.054-.109a1 1 0 0 1-.437-.437C9 9.24 9 8.96 9 8.4v-.8ZM1 12.6c0-.56 0-.84.109-1.054a1 1 0 0 1 .437-.437C1.76 11 2.04 11 2.6 11h2.8c.56 0 .84 0 1.054.109a1 1 0 0 1 .437.437C7 11.76 7 12.04 7 12.6v.8c0 .56 0 .84-.109 1.054a1 1 0 0 1-.437.437C6.24 15 5.96 15 5.4 15H2.6c-.56 0-.84 0-1.054-.109a1 1 0 0 1-.437-.437C1 14.24 1 13.96 1 13.4v-.8ZM9 12.6c0-.56 0-.84.109-1.054a1 1 0 0 1 .437-.437C9.76 11 10.04 11 10.6 11h2.8c.56 0 .84 0 1.054.109a1 1 0 0 1 .437.437C15 11.76 15 12.04 15 12.6v.8c0 .56 0 .84-.109 1.054a1 1 0 0 1-.437.437C14.24 15 13.96 15 13.4 15h-2.8c-.56 0-.84 0-1.054-.109a1 1 0 0 1-.437-.437C9 14.24 9 13.96 9 13.4v-.8Z\",\n ],\n branch: [\n \"M6 3v12\",\n \"M18 9a6 6 0 0 1-6 6H6\",\n \"M6 3a2 2 0 1 0 0 4 2 2 0 0 0 0-4\",\n \"M18 5a2 2 0 1 0 0 4 2 2 0 0 0 0-4\",\n \"M18 17a2 2 0 1 0 0 4 2 2 0 0 0 0-4\",\n ],\n budget: [\"M12 2v20\", \"M17 5H9.5a3.5 3.5 0 0 0 0 7H14a3.5 3.5 0 0 1 0 7H6\"],\n check: [\"m5 12 4 4L19 6\"],\n chevronDown: [\"m6 9 6 6 6-6\"],\n chevronLeft: [\"m15 18-6-6 6-6\"],\n chevronRight: [\"m9 18 6-6-6-6\"],\n clock: [\"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20\", \"M12 6v6l4 2\"],\n close: [\"M6 6l12 12\", \"M18 6 6 18\"],\n code: [\"m8 9-4 3 4 3\", \"m16 9 4 3-4 3\", \"m14 5-4 14\"],\n command: [\"M18 9h-9a3 3 0 1 1 3-3v12a3 3 0 1 1-3-3h9a3 3 0 1 1-3 3V6a3 3 0 1 1 3 3Z\"],\n error: [\"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20\", \"m15 9-6 6\", \"m9 9 6 6\"],\n edit: [\"M12 20h9\", \"M16.5 3.5a2.12 2.12 0 0 1 3 3L8 18l-4 1 1-4Z\"],\n external: [\"M14 3h7v7\", \"m10 14 11-11\", \"M21 14v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5\"],\n filter: [\"M4 6h16\", \"M7 12h10\", \"M10 18h4\"],\n inbox: [\"M4 4h16v16H4z\", \"M4 14h4l2 3h4l2-3h4\"],\n info: [\"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20\", \"M12 11v6\", \"M12 7h.01\"],\n layers: [\"m12 2 9 5-9 5-9-5 9-5Z\", \"m3 12 9 5 9-5\", \"m3 17 9 5 9-5\"],\n link: [\n \"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\",\n \"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\",\n ],\n list: [\n \"M1 1.8c0-.28 0-.42.054-.527a.5.5 0 0 1 .219-.218C1.38 1 1.52 1 1.8 1h12.4c.28 0 .42 0 .527.054a.5.5 0 0 1 .218.219C15 1.38 15 1.52 15 1.8v.4c0 .28 0 .42-.055.527a.5.5 0 0 1-.218.219C14.62 3 14.48 3 14.2 3H1.8c-.28 0-.42 0-.527-.054a.5.5 0 0 1-.218-.219C1 2.62 1 2.48 1 2.2v-.4ZM1 13.8c0-.28 0-.42.054-.527a.5.5 0 0 1 .219-.218C1.38 13 1.52 13 1.8 13h12.4c.28 0 .42 0 .527.055a.5.5 0 0 1 .218.218c.055.107.055.247.055.527v.4c0 .28 0 .42-.055.527a.5.5 0 0 1-.218.218C14.62 15 14.48 15 14.2 15H1.8c-.28 0-.42 0-.527-.055a.5.5 0 0 1-.218-.218C1 14.62 1 14.48 1 14.2v-.4ZM1 9.8c0-.28 0-.42.054-.527a.5.5 0 0 1 .219-.218C1.38 9 1.52 9 1.8 9h12.4c.28 0 .42 0 .527.055a.5.5 0 0 1 .218.218C15 9.38 15 9.52 15 9.8v.4c0 .28 0 .42-.055.527a.5.5 0 0 1-.218.218C14.62 11 14.48 11 14.2 11H1.8c-.28 0-.42 0-.527-.055a.5.5 0 0 1-.218-.218C1 10.62 1 10.48 1 10.2v-.4ZM1 5.8c0-.28 0-.42.054-.527a.5.5 0 0 1 .219-.218C1.38 5 1.52 5 1.8 5h12.4c.28 0 .42 0 .527.054a.5.5 0 0 1 .218.219C15 5.38 15 5.52 15 5.8v.4c0 .28 0 .42-.055.527a.5.5 0 0 1-.218.218C14.62 7 14.48 7 14.2 7H1.8c-.28 0-.42 0-.527-.054a.5.5 0 0 1-.218-.219C1 6.62 1 6.48 1 6.2v-.4Z\",\n ],\n menu: [\"M4 7h16\", \"M4 12h16\", \"M4 17h16\"],\n minus: [\"M5 12h14\"],\n monitor: [\"M3 4h18v12H3z\", \"M8 20h8\", \"M12 16v4\"],\n moon: [\"M21 12.8A9 9 0 1 1 11.2 3 7 7 0 0 0 21 12.8Z\"],\n more: [\"M5 12h.01\", \"M12 12h.01\", \"M19 12h.01\"],\n pause: [\"M8 5v14\", \"M16 5v14\"],\n person: [\"M20 21a8 8 0 0 0-16 0\", \"M12 13a5 5 0 1 0 0-10 5 5 0 0 0 0 10\"],\n play: [\"m7 4 13 8-13 8V4Z\"],\n projects: [\"M4 4h6l2 3h8v13H4z\"],\n question: [\"M9.1 9a3 3 0 1 1 5.83 1c0 2-3 2-3 4\", \"M12 18h.01\", \"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20\"],\n search: [\"M11 19a8 8 0 1 1 0-16 8 8 0 0 1 0 16\", \"m21 21-4.35-4.35\"],\n sessions: [\"M4 4h16v16H4z\", \"M8 8h8\", \"M8 12h5\", \"M8 16h3\"],\n settings: [\"M4 7h10\", \"M18 7h2\", \"M4 17h2\", \"M10 17h10\", \"M14 4v6\", \"M7 14v6\"],\n sortAscending: [\n \"M8.23 3.674a.75.75 0 0 1-.961 1.152l-1.77-1.475V14.25a.75.75 0 0 1-1.5 0V3.351L2.23 4.826a.75.75 0 1 1-.96-1.152l3-2.5a.75.75 0 0 1 .96 0z\",\n \"M6.999 7.25a.75.75 0 0 1 .75-.75h6.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1-.75-.75M6.999 10.25a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75M6.999 13.25a.75.75 0 0 1 .75-.75h1.5a.75.75 0 0 1 0 1.5h-1.5a.75.75 0 0 1-.75-.75\",\n ],\n star: [\"m12 2 3.1 6.3 6.9 1-5 4.9 1.2 6.8-6.2-3.2L5.8 21 7 14.2 2 9.3l6.9-1L12 2Z\"],\n success: [\"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20\", \"m8 12 3 3 5-6\"],\n sun: [\n \"M12 4V2\",\n \"M12 22v-2\",\n \"m4.93 4.93-1.42-1.42\",\n \"m20.49 20.49-1.42-1.42\",\n \"M4 12H2\",\n \"M22 12h-2\",\n \"m6.34 17.66-1.41 1.41\",\n \"m19.07 4.93-1.41 1.41\",\n \"M12 17a5 5 0 1 0 0-10 5 5 0 0 0 0 10\",\n ],\n terminal: [\"m4 6 4 4-4 4\", \"M10 16h6\", \"M3 3h18v18H3z\"],\n test: [\"M9 2v6l-5 9a3 3 0 0 0 2.6 4.5h10.8A3 3 0 0 0 20 17l-5-9V2\", \"M7 14h10\", \"M8 2h8\"],\n views: [\"m12 3 9 5-9 5-9-5 9-5Z\", \"m3 13 9 5 9-5\"],\n viewAdd: [\n \"M6.97358 1.34476C7.57022.885624 8.41055.885024 9.00788 1.3433L14.5499 5.59521C15.15 6.05565 15.15 6.94435 14.5499 7.40478L9.00788 11.6567C8.41055 12.115 7.57022 12.1144 6.97358 11.6552L1.44875 7.40374C.850417 6.94331.850415 6.05669 1.44875 5.59625L6.97358 1.34476ZM8 3.25c.41421 0 .75.33579.75.75v1.75h1.75a.75.75 0 0 1 0 1.5H8.75V9a.75.75 0 0 1-1.5 0V7.25H5.5a.75.75 0 0 1 0-1.5h1.75V4c0-.41421.33579-.75.75-.75Z\",\n \"M1.15024 9.79849c.24384-.33474.69848-.39736 1.01548-.13987l4.34409 3.33628c.78087.6343 1.8682.6343 2.64907 0l4.67552-3.33628c.3169-.25749.7716-.19487 1.0154.13987.2439.33471.1846.81481-.1324 1.07231l-4.6755 3.3363c-1.30145 1.0572-3.11366 1.0572-4.41512 0l-4.34409-3.3363c-.316992-.2575-.376293-.7376-.13245-1.07231Z\",\n ],\n warning: [\"m12 3 10 18H2L12 3Z\", \"M12 9v4\", \"M12 17h.01\"],\n};\nexport const Icon = ({ name, size = 16, ...props }) => {\n if (name === \"spinner\") {\n return (_jsxs(\"svg\", { \"aria-hidden\": \"true\", className: \"lr-icon lr-icon--spinner\", fill: \"none\", height: size, viewBox: \"0 0 24 24\", width: size, ...props, children: [_jsx(\"circle\", { cx: \"12\", cy: \"12\", opacity: \"0.25\", r: \"9\", stroke: \"currentColor\", strokeWidth: \"2\" }), _jsx(\"path\", { d: \"M21 12a9 9 0 0 0-9-9\", stroke: \"currentColor\", strokeLinecap: \"round\", strokeWidth: \"2\" })] }));\n }\n if (name === \"more\") {\n return (_jsxs(\"svg\", { \"aria-hidden\": \"true\", className: \"lr-icon\", fill: \"currentColor\", height: size, viewBox: \"0 0 24 24\", width: size, ...props, children: [_jsx(\"circle\", { cx: \"5\", cy: \"12\", r: \"1.5\" }), _jsx(\"circle\", { cx: \"12\", cy: \"12\", r: \"1.5\" }), _jsx(\"circle\", { cx: \"19\", cy: \"12\", r: \"1.5\" })] }));\n }\n if (name === \"board\" || name === \"list\" || name === \"sortAscending\" || name === \"viewAdd\") {\n return (_jsx(\"svg\", { \"aria-hidden\": \"true\", className: \"lr-icon\", fill: \"currentColor\", height: size, viewBox: \"0 0 16 16\", width: size, ...props, children: paths[name].map((path) => (_jsx(\"path\", { d: path }, path))) }));\n }\n const strokeWidth = name === \"add\" || name === \"filter\" || name === \"settings\" ? 2.1 : 1.7;\n return (_jsx(\"svg\", { \"aria-hidden\": \"true\", className: \"lr-icon\", fill: \"none\", height: size, viewBox: \"0 0 24 24\", width: size, ...props, children: paths[name].map((path) => (_jsx(\"path\", { d: path, stroke: \"currentColor\", strokeLinecap: \"round\", strokeLinejoin: \"round\", strokeWidth: strokeWidth }, path))) }));\n};\n//# sourceMappingURL=icons.js.map","import { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nimport { forwardRef } from \"react\";\nimport { Icon } from \"./icons.js\";\nexport const cn = (...values) => values.filter(Boolean).join(\" \");\nexport const Button = forwardRef(({ children, className, disabled, icon, loading = false, shape = \"rounded\", size = \"md\", trailingIcon, variant = \"ghost\", ...props }, ref) => (_jsxs(\"button\", { \"aria-busy\": loading, className: cn(\"lr-button\", `lr-button--${variant}`, `lr-button--${shape}`, `lr-control--${size}`, loading && \"is-loading\", className), disabled: loading || disabled === true, ref: ref, ...props, children: [icon ? _jsx(Icon, { name: loading ? \"spinner\" : icon }) : null, _jsx(\"span\", { className: cn(\"lr-button__content\", !icon && loading && \"is-visually-loading\"), children: children }), trailingIcon ? _jsx(Icon, { name: trailingIcon }) : null, !icon && loading ? _jsx(Icon, { name: \"spinner\" }) : null] })));\nButton.displayName = \"Button\";\nexport const IconButton = forwardRef(({ className, disabled, label, loading = false, name, size = \"md\", variant = \"ghost\", ...props }, ref) => (_jsx(\"button\", { \"aria-busy\": loading, \"aria-label\": label, className: cn(\"lr-icon-button\", `lr-button--${variant}`, `lr-control--${size}`, className), disabled: loading || disabled === true, ref: ref, ...props, children: _jsx(Icon, { name: loading ? \"spinner\" : name }) })));\nIconButton.displayName = \"IconButton\";\nexport const Badge = ({ className, tone = \"neutral\", ...props }) => (_jsx(\"span\", { className: cn(\"lr-badge\", `lr-badge--${tone}`, className), ...props }));\nexport const Status = ({ className, label, tone, ...props }) => (_jsxs(\"span\", { className: cn(\"lr-status\", `lr-status--${tone}`, className), ...props, children: [_jsx(\"span\", { \"aria-hidden\": \"true\", className: \"lr-status__icon\" }), _jsx(\"span\", { children: label })] }));\nexport const Avatar = ({ className, label, tone = \"neutral\", ...props }) => (_jsx(\"span\", { \"aria-label\": label, className: cn(\"lr-avatar\", `lr-avatar--${tone}`, className), role: \"img\", ...props, children: label\n .split(/\\s+/)\n .slice(0, 2)\n .map((part) => part[0])\n .join(\"\")\n .toUpperCase() }));\nexport const Skeleton = ({ className, width, ...props }) => (_jsx(\"span\", { className: cn(\"lr-skeleton\", className), style: width ? { width } : undefined, ...props }));\nconst feedbackIcons = {\n empty: \"inbox\",\n error: \"error\",\n offline: \"monitor\",\n success: \"success\",\n};\nexport const FeedbackState = ({ action, className, description, title, tone = \"empty\", ...props }) => (_jsxs(\"div\", { className: cn(\"lr-feedback\", `lr-feedback--${tone}`, className), ...props, children: [_jsx(\"span\", { \"aria-hidden\": \"true\", className: \"lr-feedback__icon\", children: _jsx(Icon, { name: feedbackIcons[tone], size: 18 }) }), _jsxs(\"div\", { children: [_jsx(\"strong\", { children: title }), _jsx(\"p\", { children: description })] }), action ? _jsx(\"div\", { className: \"lr-feedback__action\", children: action }) : null] }));\nexport const Kbd = ({ className, ...props }) => (_jsx(\"kbd\", { className: cn(\"lr-kbd\", className), ...props }));\n//# sourceMappingURL=foundation.js.map","import { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nimport { forwardRef, useId } from \"react\";\nimport { Checkbox as CheckboxPrimitive, RadioGroup as RadioPrimitive, Select as SelectPrimitive, Switch as SwitchPrimitive, } from \"radix-ui\";\nimport { cn } from \"./foundation.js\";\nimport { Icon } from \"./icons.js\";\nexport const Field = ({ children, description, error, htmlFor, label, required = false, }) => (_jsxs(\"div\", { className: cn(\"lr-field\", error && \"has-error\"), children: [_jsxs(\"label\", { className: \"lr-field__label\", htmlFor: htmlFor, children: [label, required ? _jsx(\"span\", { \"aria-hidden\": \"true\", children: \" *\" }) : null] }), children, error ? (_jsxs(\"span\", { className: \"lr-field__error\", id: `${htmlFor}-error`, role: \"alert\", children: [_jsx(Icon, { name: \"error\", size: 13 }), error] })) : description ? (_jsx(\"span\", { className: \"lr-field__description\", id: `${htmlFor}-description`, children: description })) : null] }));\nexport const TextField = forwardRef(({ className, icon, invalid = false, size = \"lg\", ...props }, ref) => (_jsxs(\"span\", { className: cn(\"lr-text-field\", `lr-control--${size}`, invalid && \"has-error\", className), children: [icon ? _jsx(Icon, { name: icon }) : null, _jsx(\"input\", { \"aria-invalid\": invalid, ref: ref, ...props })] })));\nTextField.displayName = \"TextField\";\nexport const Textarea = forwardRef(({ className, invalid = false, ...props }, ref) => (_jsx(\"textarea\", { \"aria-invalid\": invalid, className: cn(\"lr-textarea\", invalid && \"has-error\", className), ref: ref, ...props })));\nTextarea.displayName = \"Textarea\";\nexport const Checkbox = ({ className, description, id, label, ...props }) => {\n const generatedId = useId();\n const controlId = id ?? generatedId;\n return (_jsxs(\"label\", { className: \"lr-check-row\", htmlFor: controlId, children: [_jsx(CheckboxPrimitive.Root, { className: cn(\"lr-checkbox\", className), id: controlId, ...props, children: _jsx(CheckboxPrimitive.Indicator, { children: _jsx(Icon, { name: \"check\", size: 12 }) }) }), _jsxs(\"span\", { children: [_jsx(\"strong\", { children: label }), description ? _jsx(\"small\", { children: description }) : null] })] }));\n};\nexport const Switch = ({ className, description, id, label, ...props }) => {\n const generatedId = useId();\n const controlId = id ?? generatedId;\n return (_jsxs(\"label\", { className: \"lr-switch-row\", htmlFor: controlId, children: [_jsxs(\"span\", { children: [_jsx(\"strong\", { children: label }), description ? _jsx(\"small\", { children: description }) : null] }), _jsx(SwitchPrimitive.Root, { className: cn(\"lr-switch\", className), id: controlId, ...props, children: _jsx(SwitchPrimitive.Thumb, { className: \"lr-switch__thumb\" }) })] }));\n};\nexport const RadioGroup = ({ className, options, ...props }) => (_jsx(RadioPrimitive.Root, { className: cn(\"lr-radio-group\", className), ...props, children: options.map((option) => (_jsxs(\"label\", { className: \"lr-radio-row\", children: [_jsx(RadioPrimitive.Item, { className: \"lr-radio\", value: option.value, children: _jsx(RadioPrimitive.Indicator, { className: \"lr-radio__indicator\" }) }), _jsxs(\"span\", { children: [_jsx(\"strong\", { children: option.label }), option.description ? _jsx(\"small\", { children: option.description }) : null] })] }, option.value))) }));\nexport const SelectControl = ({ ariaLabel, contentClassName, defaultValue, disabled = false, id, onValueChange, options, placeholder = \"Select…\", size = \"lg\", value, variant = \"default\", }) => {\n const rootProps = {\n ...(defaultValue === undefined ? {} : { defaultValue }),\n ...(onValueChange === undefined ? {} : { onValueChange }),\n ...(value === undefined ? {} : { value }),\n };\n return (_jsxs(SelectPrimitive.Root, { disabled: disabled, ...rootProps, children: [_jsxs(SelectPrimitive.Trigger, { \"aria-label\": ariaLabel, className: cn(\"lr-select-trigger\", `lr-control--${size}`, variant === \"compact\" && \"lr-select-trigger--compact\"), id: id, children: [_jsx(SelectPrimitive.Value, { placeholder: placeholder }), _jsx(SelectPrimitive.Icon, { children: _jsx(Icon, { name: \"chevronDown\", size: 13 }) })] }), _jsx(SelectPrimitive.Portal, { children: _jsx(SelectPrimitive.Content, { className: cn(\"lr-select-content\", variant === \"compact\" && \"lr-select-content--compact\", contentClassName), position: \"popper\", sideOffset: 4, children: _jsx(SelectPrimitive.Viewport, { className: \"lr-select-viewport\", children: options.map((option) => (_jsxs(SelectPrimitive.Item, { className: \"lr-select-item\", value: option.value, ...(option.disabled === undefined ? {} : { disabled: option.disabled }), children: [_jsxs(\"span\", { className: \"lr-select-item__copy\", children: [_jsx(SelectPrimitive.ItemText, { children: option.label }), option.description ? _jsx(\"small\", { children: option.description }) : null] }), _jsx(SelectPrimitive.ItemIndicator, { className: \"lr-select-item__indicator\", children: _jsx(Icon, { name: \"check\", size: 13 }) })] }, option.value))) }) }) })] }));\n};\n//# sourceMappingURL=forms.js.map","export const filterColumnKey = (path) => path.length === 0 ? \"root\" : path.join(\"/\");\nexport const normalizeFilterQuery = (query) => query.trim().toLocaleLowerCase();\nconst hasChildren = (node) => (node.children?.length ?? 0) > 0;\nconst matchesQuery = (node, normalizedQuery) => `${node.label} ${node.description ?? \"\"}`.toLocaleLowerCase().includes(normalizedQuery);\n/**\n * Rows to show for one filter level. A deep level also searches the values nested under each\n * property, so the root search behaves like a single search across every filter. A property that\n * matches by itself stays a single row: its values remain reachable by opening it.\n */\nexport const searchFilterNodes = (nodes, query, deep = false) => {\n const normalizedQuery = normalizeFilterQuery(query);\n if (normalizedQuery === \"\") {\n return nodes.map((node) => ({ node }));\n }\n const collect = (candidates, parent) => candidates.flatMap((node) => {\n if (matchesQuery(node, normalizedQuery)) {\n return parent ? [{ node, parent }] : [{ node }];\n }\n if (!deep || !hasChildren(node)) {\n return [];\n }\n return collect(node.children ?? [], node);\n });\n return collect(nodes, undefined);\n};\n/**\n * The part of an open branch path that is still reachable under the current searches. Typing in a\n * level hides properties, and a submenu whose property is no longer listed has nothing to hang on.\n */\nexport const pruneFilterPath = (options, path, queries) => {\n const reachable = [];\n let nodes = options;\n for (const nodeId of path) {\n const columnPath = [...reachable];\n const results = searchFilterNodes(nodes, queries[filterColumnKey(columnPath)] ?? \"\", columnPath.length === 0);\n const branch = results.find((result) => result.node.id === nodeId && !result.parent)?.node;\n if (!branch || !hasChildren(branch)) {\n break;\n }\n reachable.push(nodeId);\n nodes = branch.children ?? [];\n }\n return reachable;\n};\n//# sourceMappingURL=filter-search.js.map","import { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nimport { useRef, useState } from \"react\";\nimport { Dialog as DialogPrimitive, DropdownMenu as DropdownMenuPrimitive, Popover as PopoverPrimitive, Tooltip as TooltipPrimitive, } from \"radix-ui\";\nimport { cn, IconButton, Kbd } from \"./foundation.js\";\nimport { Icon } from \"./icons.js\";\nexport const Tooltip = ({ children, label, side = \"bottom\" }) => (_jsx(TooltipPrimitive.Provider, { delayDuration: 350, skipDelayDuration: 150, children: _jsxs(TooltipPrimitive.Root, { children: [_jsx(TooltipPrimitive.Trigger, { asChild: true, \n // Radix opens a tooltip on any focus at all. A popover or dialog hands focus to its first\n // control the moment it opens, so a tooltip on that control would announce itself to an\n // owner who only clicked the overlay open. Focus the browser calls keyboard focus still\n // earns the tooltip; a click that merely lands focus here does not.\n onFocus: (event) => {\n if (!event.currentTarget.matches(\":focus-visible\"))\n event.preventDefault();\n }, children: children }), _jsx(TooltipPrimitive.Portal, { children: _jsxs(TooltipPrimitive.Content, { className: \"lr-tooltip\", side: side, sideOffset: 6, children: [label, _jsx(TooltipPrimitive.Arrow, { className: \"lr-tooltip__arrow\" })] }) })] }) }));\nexport const ActionMenu = ({ align = \"start\", contentClassName, groups, side = \"bottom\", trigger, triggerTooltip, }) => (_jsxs(DropdownMenuPrimitive.Root, { children: [triggerTooltip ? (_jsx(Tooltip, { label: triggerTooltip, children: _jsx(DropdownMenuPrimitive.Trigger, { asChild: true, children: trigger }) })) : (_jsx(DropdownMenuPrimitive.Trigger, { asChild: true, children: trigger })), _jsx(DropdownMenuPrimitive.Portal, { children: _jsx(DropdownMenuPrimitive.Content, { align: align, className: cn(\"lr-menu\", contentClassName), collisionPadding: 8, side: side, sideOffset: 5, children: groups.map((group, groupIndex) => (_jsxs(\"div\", { className: \"lr-menu__group\", children: [group.map((item) => (_jsxs(DropdownMenuPrimitive.Item, { className: cn(\"lr-menu__item\", item.icon && \"has-icon\", item.danger && \"is-danger\"), disabled: item.disabled === true || item.onSelect === undefined, ...(item.onSelect === undefined ? {} : { onSelect: item.onSelect }), children: [item.icon ? (_jsx(\"span\", { className: \"lr-menu__item-icon\", children: _jsx(Icon, { name: item.icon, size: 14 }) })) : null, _jsx(\"span\", { children: item.label }), item.shortcut ? _jsx(Kbd, { children: item.shortcut }) : null] }, item.label))), groupIndex < groups.length - 1 ? (_jsx(DropdownMenuPrimitive.Separator, { className: \"lr-menu__separator\" })) : null] }, group.map((item) => item.label).join(\"-\")))) }) })] }));\nexport const PopoverSurface = ({ align = \"end\", children, className, label, side = \"bottom\", trigger, triggerTooltip, }) => {\n const contentRef = useRef(null);\n const [open, setOpen] = useState(false);\n return (_jsxs(PopoverPrimitive.Root, { onOpenChange: setOpen, open: open, children: [triggerTooltip ? (_jsx(Tooltip, { label: triggerTooltip, children: _jsx(PopoverPrimitive.Trigger, { asChild: true, children: trigger }) })) : (_jsx(PopoverPrimitive.Trigger, { asChild: true, children: trigger })), _jsx(PopoverPrimitive.Portal, { children: _jsx(PopoverPrimitive.Content, { align: align, \"aria-label\": label, className: cn(\"lr-popover\", className), collisionPadding: 8, \n // Radix hands Escape to the topmost dismissable layer alone, and a tooltip standing over\n // this surface is that layer -- which would leave the surface sitting through the press\n // meant to close it. It answers for its own Escape instead, and only for one pressed on\n // the surface itself: a portalled menu or select still answers for the presses it owns.\n onKeyDown: (event) => {\n if (event.key !== \"Escape\")\n return;\n if (!(event.target instanceof Node))\n return;\n if (!event.currentTarget.contains(event.target))\n return;\n setOpen(false);\n }, \n // Radix would arm whichever control sits first inside, ringing it and offering it to the\n // next keypress -- a choice the owner never made by opening the surface. The surface\n // itself takes the focus instead: it still announces its label and Tab still walks in.\n onOpenAutoFocus: (event) => {\n event.preventDefault();\n contentRef.current?.focus();\n }, ref: contentRef, side: side, sideOffset: 6, children: children }) })] }));\n};\nexport const DialogSurface = ({ children, className, closeLabel = \"Close dialog\", description, footer, onOpenChange, open, size = \"md\", title, trigger, triggerTooltip, }) => {\n const contentRef = useRef(null);\n const rootProps = {\n ...(onOpenChange === undefined ? {} : { onOpenChange }),\n ...(open === undefined ? {} : { open }),\n };\n return (_jsxs(DialogPrimitive.Root, { ...rootProps, children: [trigger ? (triggerTooltip ? (_jsx(Tooltip, { label: triggerTooltip, children: _jsx(DialogPrimitive.Trigger, { asChild: true, children: trigger }) })) : (_jsx(DialogPrimitive.Trigger, { asChild: true, children: trigger }))) : null, _jsxs(DialogPrimitive.Portal, { children: [_jsx(DialogPrimitive.Overlay, { className: \"lr-dialog-overlay\" }), _jsxs(DialogPrimitive.Content, { className: cn(\"lr-dialog\", `lr-dialog--${size}`, className), onOpenAutoFocus: (event) => {\n event.preventDefault();\n contentRef.current?.focus();\n }, ref: contentRef, tabIndex: -1, children: [_jsxs(\"header\", { className: \"lr-dialog__header\", children: [_jsxs(\"div\", { children: [_jsx(DialogPrimitive.Title, { children: title }), description ? _jsx(DialogPrimitive.Description, { children: description }) : null] }), _jsx(Tooltip, { label: closeLabel, children: _jsx(DialogPrimitive.Close, { asChild: true, children: _jsx(IconButton, { label: closeLabel, name: \"close\", size: \"lg\" }) }) })] }), _jsx(\"div\", { className: \"lr-dialog__body\", children: children }), footer ? _jsx(\"footer\", { className: \"lr-dialog__footer\", children: footer }) : null] })] })] }));\n};\n//# sourceMappingURL=overlays.js.map","import { jsxs as _jsxs, jsx as _jsx } from \"react/jsx-runtime\";\nimport { cloneElement, Fragment, useEffect, useRef, useState, useSyncExternalStore } from \"react\";\nimport { Dialog as DialogPrimitive, Popover as PopoverPrimitive } from \"radix-ui\";\nimport { filterColumnKey, normalizeFilterQuery, pruneFilterPath, searchFilterNodes, } from \"./filter-search.js\";\nimport { Button, cn, IconButton } from \"./foundation.js\";\nimport { Icon } from \"./icons.js\";\nimport { Tooltip } from \"./overlays.js\";\nconst defaultFilterMessages = {\n add: \"Add\",\n addFilterPlaceholder: \"Add Filter…\",\n backTo: \"Back to\",\n clear: \"Clear\",\n close: \"Close filters\",\n description: \"Choose one or more task properties. Each selection is applied immediately.\",\n edit: \"Edit\",\n filterPlaceholder: \"Filter…\",\n is: \"is\",\n isAnyOf: \"is any of\",\n noMatchingProperties: \"No matching properties\",\n noMatchingValues: \"No matching values\",\n oneValue: \"1 value\",\n options: \"options\",\n remove: \"Remove\",\n rootTitle: \"Filters\",\n search: \"Search\",\n selectedValues: \"selected values\",\n};\nconst mobileFilterQuery = \"(max-width: 760px)\";\nconst filterHoverIntentDelay = 80;\nconst rootFilterPanelOffset = 187;\nconst nestedFilterPanelStride = 197;\nconst subscribeToMobileFilter = (onStoreChange) => {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return () => undefined;\n }\n const mediaQuery = window.matchMedia(mobileFilterQuery);\n mediaQuery.addEventListener(\"change\", onStoreChange);\n return () => {\n mediaQuery.removeEventListener(\"change\", onStoreChange);\n };\n};\nconst getMobileFilterSnapshot = () => typeof window !== \"undefined\" &&\n typeof window.matchMedia === \"function\" &&\n window.matchMedia(mobileFilterQuery).matches;\nconst getMobileFilterServerSnapshot = () => false;\nconst getColumns = (options, path, rootTitle) => {\n const columns = [{ key: \"root\", nodes: options, path: [], title: rootTitle }];\n let currentNodes = options;\n for (const [index, nodeId] of path.entries()) {\n const node = currentNodes.find((candidate) => candidate.id === nodeId);\n if (!node?.children || node.children.length === 0) {\n break;\n }\n const nextPath = path.slice(0, index + 1);\n columns.push({\n key: filterColumnKey(nextPath),\n nodes: node.children,\n path: nextPath,\n title: node.label,\n });\n currentNodes = node.children;\n }\n return columns;\n};\nconst estimateFilterPanelHeight = (nodes) => Math.min(707, 50 +\n nodes.reduce((height, node) => height + (node.dividerBefore ? 12 : 0) + (node.description ? 46 : 32), 0));\nconst getOrderedLeafIds = (nodes) => nodes.flatMap((node) => node.children && node.children.length > 0 ? getOrderedLeafIds(node.children) : [node.id]);\nconst orderSelectedLeafIds = (options, selected) => getOrderedLeafIds(options).filter((nodeId) => selected.includes(nodeId));\nconst getAppliedFilterGroups = (options, selected) => {\n const groups = new Map();\n const visit = (nodes, parent) => {\n nodes.forEach((node) => {\n if (node.children && node.children.length > 0) {\n visit(node.children, node);\n return;\n }\n if (!selected.includes(node.id)) {\n return;\n }\n const owner = parent ?? node;\n const current = groups.get(owner.id);\n groups.set(owner.id, {\n icon: owner.icon,\n id: owner.id,\n label: owner.label,\n options: owner.children ?? [node],\n selected: current ? [...current.selected, node] : [node],\n });\n });\n };\n visit(options, undefined);\n return [...groups.values()];\n};\nconst focusRelativeItem = (event, direction) => {\n const list = event.currentTarget.closest(\".lr-filter-list\");\n if (!list) {\n return;\n }\n const items = Array.from(list.querySelectorAll(\"[data-filter-item]\"));\n const currentIndex = items.indexOf(event.currentTarget);\n const nextIndex = (currentIndex + direction + items.length) % items.length;\n items[nextIndex]?.focus();\n};\nconst focusBoundaryItem = (event, position) => {\n const list = event.currentTarget.closest(\".lr-filter-list\");\n if (!list) {\n return;\n }\n const items = Array.from(list.querySelectorAll(\"[data-filter-item]\"));\n const item = position === \"first\" ? items[0] : items.at(-1);\n item?.focus();\n};\nconst FilterLevel = ({ activeChildId, column, floatingPosition, mobile = false, messages, onBack, onOpenBranch, onQueryChange, onToggle, query, searchRef, selected, }) => {\n const isRoot = column.path.length === 0;\n const searching = normalizeFilterQuery(query) !== \"\";\n const results = searchFilterNodes(column.nodes, query, isRoot);\n return (_jsxs(\"section\", { \"aria-label\": column.title, className: cn(\"lr-filter-level\", mobile && \"lr-filter-level--mobile\"), \"data-filter-column\": column.key, \"data-filter-depth\": column.path.length, style: floatingPosition, children: [_jsxs(\"label\", { className: \"lr-filter-search\", children: [_jsxs(\"span\", { className: \"lr-visually-hidden\", children: [messages.search, \" \", column.title] }), _jsx(\"input\", { \"aria-label\": `${messages.search} ${column.title}`, onChange: (event) => {\n onQueryChange(column.key, event.currentTarget.value);\n }, onKeyDown: (event) => {\n if (event.key !== \"ArrowDown\") {\n return;\n }\n event.preventDefault();\n event.currentTarget\n .closest(\".lr-filter-level\")\n ?.querySelector(\"[data-filter-item]\")\n ?.focus();\n }, placeholder: column.path.length === 0 ? messages.addFilterPlaceholder : messages.filterPlaceholder, ref: searchRef, spellCheck: false, type: \"search\", value: query })] }), _jsxs(\"div\", { \"aria-label\": `${column.title} ${messages.options}`, className: \"lr-filter-list\", role: \"menu\", children: [results.map(({ node, parent }) => {\n const branch = Boolean(node.children && node.children.length > 0);\n const isActive = branch && activeChildId === node.id;\n const isSelected = !branch && selected.includes(node.id);\n const key = parent ? `${parent.id}/${node.id}` : node.id;\n const fullLabel = parent ? `${parent.label}: ${node.label}` : node.label;\n const divider = node.dividerBefore && !searching ? (_jsx(\"div\", { className: \"lr-filter-separator\", role: \"separator\" })) : null;\n if (!branch) {\n return (_jsxs(Fragment, { children: [divider, _jsxs(\"div\", { className: \"lr-filter-choice\", role: \"none\", children: [_jsx(\"button\", { \"aria-label\": `${isSelected ? messages.remove : messages.add} ${fullLabel}`, \"aria-pressed\": isSelected, className: \"lr-filter-choice__checkbox\", onClick: () => {\n onToggle(node.id, false);\n }, type: \"button\", children: isSelected ? _jsx(Icon, { name: \"check\", size: 10 }) : null }), _jsxs(\"button\", { \"aria-checked\": isSelected, \"aria-label\": parent ? fullLabel : undefined, className: \"lr-filter-item lr-filter-item--choice\", \"data-filter-item\": true, \"data-filter-node\": node.id, onClick: () => {\n onToggle(node.id, true);\n }, onKeyDown: (event) => {\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n focusRelativeItem(event, 1);\n }\n else if (event.key === \"ArrowUp\") {\n event.preventDefault();\n focusRelativeItem(event, -1);\n }\n else if (event.key === \"Home\") {\n event.preventDefault();\n focusBoundaryItem(event, \"first\");\n }\n else if (event.key === \"End\") {\n event.preventDefault();\n focusBoundaryItem(event, \"last\");\n }\n else if (event.key === \"ArrowLeft\" && column.path.length > 0) {\n event.preventDefault();\n onBack();\n }\n }, role: \"menuitemcheckbox\", type: \"button\", children: [_jsxs(\"span\", { className: \"lr-filter-item__copy\", children: [_jsxs(\"span\", { children: [parent ? (_jsx(\"span\", { \"aria-hidden\": \"true\", className: \"lr-filter-item__context\", children: parent.label })) : null, node.label] }), node.description ? _jsx(\"small\", { children: node.description }) : null] }), node.count !== undefined && !parent ? (_jsx(\"span\", { className: \"lr-filter-item__meta\", children: _jsx(\"small\", { children: node.count }) })) : null] })] })] }, key));\n }\n return (_jsxs(Fragment, { children: [divider, _jsxs(\"button\", { \"aria-expanded\": isActive, \"aria-haspopup\": \"menu\", className: \"lr-filter-item\", \"data-active\": isActive, \"data-filter-item\": true, \"data-filter-node\": node.id, onClick: (event) => {\n onOpenBranch(node, column, true, event.currentTarget);\n }, onPointerEnter: (event) => {\n if (!mobile) {\n onOpenBranch(node, column, false, event.currentTarget);\n }\n }, onKeyDown: (event) => {\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n focusRelativeItem(event, 1);\n }\n else if (event.key === \"ArrowUp\") {\n event.preventDefault();\n focusRelativeItem(event, -1);\n }\n else if (event.key === \"Home\") {\n event.preventDefault();\n focusBoundaryItem(event, \"first\");\n }\n else if (event.key === \"End\") {\n event.preventDefault();\n focusBoundaryItem(event, \"last\");\n }\n else if (event.key === \"ArrowRight\") {\n event.preventDefault();\n onOpenBranch(node, column, true, event.currentTarget);\n }\n else if (event.key === \"ArrowLeft\" && column.path.length > 0) {\n event.preventDefault();\n onBack();\n }\n }, role: \"menuitem\", type: \"button\", children: [_jsx(\"span\", { className: \"lr-filter-item__icon\", children: node.icon ? _jsx(Icon, { name: node.icon, size: 14 }) : null }), _jsxs(\"span\", { className: \"lr-filter-item__copy\", children: [_jsx(\"span\", { children: node.label }), node.description ? _jsx(\"small\", { children: node.description }) : null] }), _jsx(\"span\", { className: \"lr-filter-item__meta\", children: _jsx(Icon, { name: \"chevronRight\", size: 12 }) })] })] }, key));\n }), results.length === 0 ? (_jsx(\"p\", { className: \"lr-filter-empty\", children: isRoot ? messages.noMatchingProperties : messages.noMatchingValues })) : null] })] }));\n};\nexport const CascadingFilter = ({ ariaLabel, defaultValue = [], messages, onValueChange, options, trigger, triggerTooltip, value, }) => {\n const copy = { ...defaultFilterMessages, ...messages };\n const isMobile = useSyncExternalStore(subscribeToMobileFilter, getMobileFilterSnapshot, getMobileFilterServerSnapshot);\n const [open, setOpen] = useState(false);\n const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);\n const committedValue = value ?? uncontrolledValue;\n const [path, setPath] = useState([]);\n const [panelTops, setPanelTops] = useState({});\n const [queries, setQueries] = useState({});\n const desktopSearchRef = useRef(null);\n const desktopPointerDismissRef = useRef(false);\n const hoverIntentTimeoutRef = useRef(undefined);\n const mobileSearchRef = useRef(null);\n const triggerRef = useRef(null);\n const triggerWithRef = cloneElement(trigger, {\n ref: triggerRef,\n });\n const columns = getColumns(options, path, copy.rootTitle);\n const currentColumn = columns.at(-1) ?? {\n key: \"root\",\n nodes: options,\n path: [],\n title: copy.rootTitle,\n };\n const clearScheduledBranch = () => {\n if (hoverIntentTimeoutRef.current === undefined) {\n return;\n }\n window.clearTimeout(hoverIntentTimeoutRef.current);\n hoverIntentTimeoutRef.current = undefined;\n };\n useEffect(() => () => {\n if (hoverIntentTimeoutRef.current !== undefined) {\n window.clearTimeout(hoverIntentTimeoutRef.current);\n }\n }, []);\n const handleOpenChange = (nextOpen) => {\n clearScheduledBranch();\n if (nextOpen) {\n desktopPointerDismissRef.current = false;\n setPath([]);\n setPanelTops({});\n setQueries({});\n }\n setOpen(nextOpen);\n };\n const handleToggle = (nodeId, closeAfter) => {\n clearScheduledBranch();\n const nextValue = committedValue.includes(nodeId)\n ? committedValue.filter((selectedId) => selectedId !== nodeId)\n : [...committedValue, nodeId];\n const orderedIds = orderSelectedLeafIds(options, nextValue);\n if (value === undefined) {\n setUncontrolledValue(orderedIds);\n }\n onValueChange?.(orderedIds);\n if (closeAfter) {\n setOpen(false);\n }\n };\n const handleOpenBranch = (node, column, moveFocus = true, anchor) => {\n clearScheduledBranch();\n const openBranch = () => {\n hoverIntentTimeoutRef.current = undefined;\n const nextPath = [...column.path, node.id];\n const nextColumnKey = filterColumnKey(nextPath);\n if (!isMobile && anchor) {\n const popover = anchor.closest(\".lr-filter-popover\");\n if (popover) {\n const popoverRect = popover.getBoundingClientRect();\n const anchorRect = anchor.getBoundingClientRect();\n const panelHeight = estimateFilterPanelHeight(node.children ?? []);\n const availableBottom = window.innerHeight - popoverRect.top - 8;\n const maximumTop = Math.max(0, availableBottom - panelHeight);\n const nextTop = Math.min(Math.max(0, anchorRect.top - popoverRect.top - 1), maximumTop);\n setPanelTops((current) => ({ ...current, [nextColumnKey]: nextTop }));\n }\n }\n setPath(nextPath);\n if (!moveFocus) {\n return;\n }\n window.requestAnimationFrame(() => {\n const target = isMobile\n ? mobileSearchRef.current\n : document.querySelector(`.lr-filter-level[data-filter-depth=\"${nextPath.length.toString()}\"] input`);\n target?.focus();\n });\n };\n if (!moveFocus && !isMobile) {\n hoverIntentTimeoutRef.current = window.setTimeout(openBranch, filterHoverIntentDelay);\n return;\n }\n openBranch();\n };\n const handleBack = () => {\n const departingNodeId = path.at(-1);\n const nextPath = path.slice(0, -1);\n setPath(nextPath);\n window.requestAnimationFrame(() => {\n if (isMobile) {\n mobileSearchRef.current?.focus();\n return;\n }\n if (departingNodeId) {\n document.querySelector(`[data-filter-node=\"${departingNodeId}\"]`)?.focus();\n }\n });\n };\n const handleQueryChange = (key, nextQuery) => {\n clearScheduledBranch();\n const nextQueries = { ...queries, [key]: nextQuery };\n setQueries(nextQueries);\n setPath((current) => pruneFilterPath(options, current, nextQueries));\n };\n if (isMobile) {\n const parentTitle = columns.at(-2)?.title ?? ariaLabel;\n return (_jsxs(DialogPrimitive.Root, { onOpenChange: handleOpenChange, open: open, children: [triggerTooltip ? (_jsx(Tooltip, { label: triggerTooltip, children: _jsx(DialogPrimitive.Trigger, { asChild: true, children: triggerWithRef }) })) : (_jsx(DialogPrimitive.Trigger, { asChild: true, children: triggerWithRef })), _jsxs(DialogPrimitive.Portal, { children: [_jsx(DialogPrimitive.Overlay, { className: \"lr-dialog-overlay\" }), _jsxs(DialogPrimitive.Content, { className: \"lr-filter-dialog\", onOpenAutoFocus: (event) => {\n event.preventDefault();\n mobileSearchRef.current?.focus();\n }, onCloseAutoFocus: (event) => {\n event.preventDefault();\n triggerRef.current?.focus();\n }, children: [_jsxs(\"header\", { className: \"lr-filter-dialog__header\", children: [_jsxs(\"div\", { className: \"lr-filter-dialog__heading\", children: [path.length > 0 ? (_jsx(Tooltip, { label: `${copy.backTo} ${parentTitle}`, children: _jsx(IconButton, { label: `${copy.backTo} ${parentTitle}`, name: \"chevronLeft\", onClick: handleBack, size: \"lg\" }) })) : null, _jsx(DialogPrimitive.Title, { children: path.length === 0 ? ariaLabel : currentColumn.title })] }), _jsx(Tooltip, { label: copy.close, children: _jsx(DialogPrimitive.Close, { asChild: true, children: _jsx(IconButton, { label: copy.close, name: \"close\", size: \"lg\" }) }) })] }), _jsx(DialogPrimitive.Description, { className: \"lr-visually-hidden\", children: copy.description }), _jsx(\"div\", { className: \"lr-filter-dialog__body\", children: _jsx(FilterLevel, { activeChildId: undefined, column: currentColumn, mobile: true, messages: copy, onBack: handleBack, onOpenBranch: handleOpenBranch, onQueryChange: handleQueryChange, onToggle: handleToggle, query: queries[currentColumn.key] ?? \"\", searchRef: mobileSearchRef, selected: committedValue }, currentColumn.key) })] })] })] }));\n }\n return (_jsxs(PopoverPrimitive.Root, { onOpenChange: handleOpenChange, open: open, children: [triggerTooltip ? (_jsx(Tooltip, { label: triggerTooltip, children: _jsx(PopoverPrimitive.Trigger, { asChild: true, children: triggerWithRef }) })) : (_jsx(PopoverPrimitive.Trigger, { asChild: true, children: triggerWithRef })), _jsx(PopoverPrimitive.Portal, { children: _jsxs(PopoverPrimitive.Content, { align: \"start\", \"aria-label\": ariaLabel, className: \"lr-filter-popover\", collisionPadding: 8, onOpenAutoFocus: (event) => {\n event.preventDefault();\n desktopSearchRef.current?.focus();\n }, onCloseAutoFocus: (event) => {\n event.preventDefault();\n if (!desktopPointerDismissRef.current) {\n triggerRef.current?.focus();\n }\n desktopPointerDismissRef.current = false;\n }, onEscapeKeyDown: () => {\n desktopPointerDismissRef.current = false;\n }, onPointerDownOutside: () => {\n desktopPointerDismissRef.current = true;\n }, sideOffset: 6, children: [_jsx(\"div\", { className: \"lr-filter-main-panel\", children: _jsx(FilterLevel, { activeChildId: path[0], column: columns[0] ?? { key: \"root\", nodes: options, path: [], title: copy.rootTitle }, messages: copy, onBack: handleBack, onOpenBranch: handleOpenBranch, onQueryChange: handleQueryChange, onToggle: handleToggle, query: queries[\"root\"] ?? \"\", searchRef: desktopSearchRef, selected: committedValue }) }), _jsx(\"div\", { className: \"lr-filter-submenus\", children: columns.slice(1).map((column) => (_jsx(FilterLevel, { activeChildId: path[column.path.length], column: column, floatingPosition: {\n height: estimateFilterPanelHeight(column.nodes),\n right: rootFilterPanelOffset + (column.path.length - 1) * nestedFilterPanelStride,\n top: panelTops[column.key] ?? 0,\n }, messages: copy, onBack: handleBack, onOpenBranch: handleOpenBranch, onQueryChange: handleQueryChange, onToggle: handleToggle, query: queries[column.key] ?? \"\", searchRef: undefined, selected: committedValue }, column.path.length))) })] }) })] }));\n};\nconst AppliedFilterEditor = ({ group, messages, onValueChange, options, value, }) => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState(\"\");\n const searchRef = useRef(null);\n const normalizedQuery = query.trim().toLocaleLowerCase();\n const visibleOptions = group.options.filter((option) => `${option.label} ${option.description ?? \"\"}`.toLocaleLowerCase().includes(normalizedQuery));\n const selectedIds = group.selected.map((option) => option.id);\n const valueLabel = group.selected.length === 1\n ? (group.selected[0]?.label ?? messages.oneValue)\n : `${group.selected[0]?.label ?? group.selected.length.toString()} +${(group.selected.length - 1).toString()}`;\n const handleToggle = (nodeId, closeAfter) => {\n const nextValue = value.includes(nodeId)\n ? value.filter((selectedId) => selectedId !== nodeId)\n : [...value, nodeId];\n onValueChange(orderSelectedLeafIds(options, nextValue));\n if (closeAfter) {\n setOpen(false);\n }\n };\n return (_jsxs(PopoverPrimitive.Root, { onOpenChange: (nextOpen) => {\n if (nextOpen) {\n setQuery(\"\");\n }\n setOpen(nextOpen);\n }, open: open, children: [_jsxs(\"div\", { className: \"lr-applied-filter\", children: [_jsx(PopoverPrimitive.Trigger, { asChild: true, children: _jsxs(\"button\", { \"aria-label\": `${messages.edit} ${group.label}`, className: \"lr-applied-filter__editor\", type: \"button\", children: [_jsxs(\"span\", { className: \"lr-applied-filter__property\", children: [_jsx(Icon, { name: group.icon ?? \"filter\", size: 12 }), group.label] }), _jsx(\"span\", { className: \"lr-applied-filter__operator\", children: group.selected.length === 1 ? messages.is : messages.isAnyOf }), _jsx(\"span\", { className: \"lr-applied-filter__value\", children: valueLabel })] }) }), _jsx(\"button\", { \"aria-label\": `${messages.remove} ${group.label}`, className: \"lr-applied-filter__remove\", onClick: () => {\n onValueChange(value.filter((nodeId) => !selectedIds.includes(nodeId)));\n }, type: \"button\", children: _jsx(Icon, { name: \"close\", size: 12 }) })] }), _jsx(PopoverPrimitive.Portal, { children: _jsxs(PopoverPrimitive.Content, { align: \"start\", \"aria-label\": `${messages.edit} ${group.label}`, className: \"lr-applied-filter-popover\", collisionPadding: 8, onOpenAutoFocus: (event) => {\n event.preventDefault();\n searchRef.current?.focus();\n }, sideOffset: 6, children: [_jsxs(\"label\", { className: \"lr-filter-search lr-applied-filter-popover__search\", children: [_jsxs(\"span\", { className: \"lr-visually-hidden\", children: [messages.search, \" \", group.label] }), _jsx(\"input\", { \"aria-label\": `${messages.search} ${group.label}`, onChange: (event) => {\n setQuery(event.currentTarget.value);\n }, placeholder: messages.filterPlaceholder, ref: searchRef, spellCheck: false, type: \"search\", value: query })] }), _jsxs(\"div\", { \"aria-label\": `${group.label} ${messages.selectedValues}`, className: \"lr-filter-list\", role: \"menu\", children: [visibleOptions.map((option) => {\n const selected = value.includes(option.id);\n return (_jsxs(\"div\", { className: \"lr-filter-choice\", role: \"none\", children: [_jsx(\"button\", { \"aria-label\": `${selected ? messages.remove : messages.add} ${option.label}`, \"aria-pressed\": selected, className: \"lr-filter-choice__checkbox\", onClick: () => {\n handleToggle(option.id, false);\n }, type: \"button\", children: selected ? _jsx(Icon, { name: \"check\", size: 12 }) : null }), _jsxs(\"button\", { \"aria-checked\": selected, className: \"lr-filter-item lr-filter-item--choice\", \"data-filter-item\": true, onClick: () => {\n handleToggle(option.id, true);\n }, onKeyDown: (event) => {\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n focusRelativeItem(event, 1);\n }\n if (event.key === \"ArrowUp\") {\n event.preventDefault();\n focusRelativeItem(event, -1);\n }\n if (event.key === \"Home\") {\n event.preventDefault();\n focusBoundaryItem(event, \"first\");\n }\n if (event.key === \"End\") {\n event.preventDefault();\n focusBoundaryItem(event, \"last\");\n }\n }, role: \"menuitemcheckbox\", type: \"button\", children: [_jsxs(\"span\", { className: \"lr-filter-item__copy\", children: [_jsx(\"span\", { children: option.label }), option.description ? _jsx(\"small\", { children: option.description }) : null] }), _jsx(\"span\", { className: \"lr-filter-item__meta\", children: option.count !== undefined ? _jsx(\"small\", { children: option.count }) : null })] })] }, option.id));\n }), visibleOptions.length === 0 ? (_jsx(\"p\", { className: \"lr-filter-empty\", children: messages.noMatchingValues })) : null] })] }) })] }));\n};\nexport const AppliedFilterBar = ({ addFilter, ariaLabel, className, messages, onClear, onValueChange, options, supplementalConditions, value, }) => {\n const copy = { ...defaultFilterMessages, ...messages };\n const groups = getAppliedFilterGroups(options, value);\n return (_jsxs(\"div\", { \"aria-label\": ariaLabel, className: cn(\"lr-applied-filter-bar\", className), role: \"region\", children: [_jsxs(\"div\", { className: \"lr-applied-filter-bar__conditions\", children: [supplementalConditions, groups.map((group) => (_jsx(AppliedFilterEditor, { group: group, messages: copy, onValueChange: onValueChange, options: options, value: value }, group.id))), _jsx(\"div\", { className: \"lr-applied-filter-bar__add\", children: addFilter })] }), value.length > 0 || supplementalConditions ? (_jsx(Button, { className: \"lr-applied-filter-bar__clear\", onClick: () => {\n if (onClear) {\n onClear();\n return;\n }\n onValueChange([]);\n }, shape: \"pill\", children: copy.clear })) : null] }));\n};\n//# sourceMappingURL=filters.js.map","import { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nimport { Avatar, Badge, Button, cn, Status } from \"./foundation.js\";\nimport { Icon } from \"./icons.js\";\nexport const TaskCard = ({ agent, badge, className, description, id, meta, selected = false, title, ...props }) => (_jsxs(\"article\", { className: cn(\"lr-task-card\", selected && \"is-selected\", className), ...props, children: [_jsxs(\"div\", { className: \"lr-task-card__header\", children: [_jsx(\"span\", { children: id }), badge ? _jsx(Badge, { tone: badge.tone ?? \"neutral\", children: badge.label }) : null] }), _jsx(\"strong\", { className: \"lr-task-card__title\", children: title }), description ? _jsx(\"p\", { children: description }) : null, _jsx(\"footer\", { children: _jsxs(\"span\", { className: \"lr-task-card__agent\", children: [agent ? _jsx(Avatar, { label: agent }) : null, meta] }) })] }));\nexport const KanbanColumn = ({ addLabel, children, count, label, onAdd, tone, }) => (_jsxs(\"section\", { className: \"lr-kanban-column\", children: [_jsxs(\"header\", { children: [_jsx(Status, { label: label, tone: tone }), _jsx(\"span\", { className: \"lr-kanban-column__count\", children: count }), onAdd ? (_jsx(Button, { \"aria-label\": addLabel ?? `Add task to ${label}`, className: \"lr-kanban-column__add\", onClick: onAdd, size: \"sm\", children: _jsx(Icon, { name: \"add\", size: 13 }) })) : null] }), _jsx(\"div\", { className: \"lr-kanban-column__stack\", children: children })] }));\nexport const TimelineEvent = ({ detail, icon = \"check\", label, time, tone = \"neutral\", }) => (_jsxs(\"div\", { className: cn(\"lr-timeline-event\", `lr-timeline-event--${tone}`), children: [_jsx(\"span\", { \"aria-hidden\": \"true\", className: \"lr-timeline-event__icon\", children: _jsx(Icon, { name: icon, size: 12 }) }), _jsxs(\"div\", { children: [_jsx(\"strong\", { children: label }), detail ? _jsx(\"span\", { children: detail }) : null] }), _jsx(\"time\", { children: time })] }));\nexport const InspectorSection = ({ action, children, title }) => (_jsxs(\"section\", { className: \"lr-inspector-section\", children: [_jsxs(\"header\", { children: [_jsx(\"strong\", { children: title }), action] }), _jsx(\"div\", { className: \"lr-inspector-section__body\", children: children })] }));\nexport const RunSummary = ({ properties }) => (_jsx(\"dl\", { className: \"lr-run-summary\", children: properties.map((property) => (_jsxs(\"div\", { children: [_jsx(\"dt\", { children: property.label }), _jsx(\"dd\", { children: property.value })] }, property.label))) }));\nexport const ProviderSessionTimeline = ({ attempt, note, sessions, title, }) => (_jsxs(\"div\", { className: \"lr-session-timeline-panel\", children: [attempt ? (_jsxs(\"div\", { className: \"lr-session-timeline__row\", children: [_jsx(\"strong\", { className: \"lr-session-timeline-panel__title\", children: attempt.heading }), _jsx(Status, { label: attempt.statusLabel, tone: attempt.tone })] })) : null, _jsx(\"strong\", { className: attempt ? \"lr-session-timeline-panel__subtitle\" : \"lr-session-timeline-panel__title\", children: title }), note ? _jsx(\"p\", { className: \"lr-session-timeline-panel__note\", children: note }) : null, _jsx(\"ol\", { className: \"lr-session-timeline\", children: sessions.map((session) => (_jsxs(\"li\", { \"aria-label\": session.ariaLabel, className: \"lr-session-timeline__item\", children: [_jsx(\"span\", { \"aria-hidden\": \"true\", className: \"lr-session-timeline__ordinal\", children: session.ordinal }), _jsxs(\"div\", { className: \"lr-session-timeline__body\", children: [_jsxs(\"div\", { className: \"lr-session-timeline__row\", children: [_jsx(Status, { label: session.statusLabel, tone: session.tone }), session.handoffRequestedLabel ? (_jsx(Badge, { tone: \"warning\", children: session.handoffRequestedLabel })) : null] }), session.occupancyPercent !== undefined && session.occupancyLabel !== undefined ? (_jsxs(\"div\", { className: \"lr-session-timeline__occupancy\", children: [_jsx(\"progress\", { \"aria-hidden\": \"true\", max: 100, value: session.occupancyPercent }), _jsxs(\"p\", { className: \"lr-session-timeline__occupancy-text\", children: [_jsx(\"span\", { children: session.occupancyLabel }), session.occupancyQualityLabel === undefined ? null : (_jsx(\"span\", { className: \"lr-session-timeline__occupancy-quality\", children: session.occupancyQualityLabel }))] })] })) : null, session.checkpoints.length > 0 ? (_jsx(\"ul\", { className: \"lr-session-timeline__checkpoints\", children: session.checkpoints.map((checkpoint) => (_jsx(\"li\", { children: _jsxs(\"details\", { className: \"lr-checkpoint-card\", open: checkpoint.defaultOpen, children: [_jsxs(\"summary\", { children: [_jsx(Icon, { \"aria-hidden\": \"true\", className: \"lr-checkpoint-card__chevron\", name: \"chevronRight\", size: 12 }), _jsx(\"span\", { children: checkpoint.summary }), _jsx(\"time\", { children: checkpoint.timeLabel })] }), _jsx(\"div\", { className: \"lr-checkpoint-card__body\", children: checkpoint.groups.map((group) => group.items.length > 0 ? (_jsxs(\"div\", { children: [_jsx(\"strong\", { children: group.label }), _jsx(\"ul\", { children: group.items.map((item, index) => (_jsx(\"li\", { children: item }, `${index.toString()}-${item}`))) })] }, group.label)) : null) })] }) }, checkpoint.id))) })) : session.emptyCheckpointsLabel ? (_jsx(\"p\", { className: \"lr-session-timeline__empty\", children: session.emptyCheckpointsLabel })) : null] })] }, session.id))) })] }));\n//# sourceMappingURL=patterns.js.map","type BrandMarkProps = {\n className?: string;\n size?: number;\n};\n\nexport const BrandMark = ({ className, size = 24 }: BrandMarkProps): React.JSX.Element => (\n <svg\n aria-hidden=\"true\"\n className={className}\n focusable=\"false\"\n height={size}\n viewBox=\"0 0 96 96\"\n width={size}\n >\n <rect fill=\"#5e6ad2\" height=\"96\" rx=\"24\" width=\"96\" />\n <path\n d=\"M27 23v46h46\"\n fill=\"none\"\n stroke=\"#fff\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"10\"\n />\n <path\n d=\"M48 23v25h25\"\n fill=\"none\"\n stroke=\"#fff\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"10\"\n />\n </svg>\n);\n","/* eslint-disable react-refresh/only-export-components -- the provider and its typed locale helpers are one module */\nimport { createContext, useContext, useMemo, useState } from \"react\";\nimport type { ReactNode } from \"react\";\n\nconst LOCALE_STORAGE_KEY = \"loomrail.locale\";\n\nconst en = {\n \"settings.open\": \"Open settings\",\n \"settings.title\": \"Settings\",\n \"settings.description\": \"Preferences stored in this browser.\",\n \"settings.appearance\": \"Appearance\",\n \"settings.density\": \"Board density\",\n \"settings.density.description\": \"Compact tightens the spacing inside and between cards.\",\n \"settings.density.comfortable\": \"Comfortable\",\n \"settings.density.compact\": \"Compact\",\n \"layout.resize.sidebar\": \"Resize the sidebar\",\n \"layout.resize.inspector\": \"Resize the task inspector\",\n \"settings.layout\": \"Layout\",\n \"settings.layout.description\": \"Drag a panel edge to resize it, or nudge it with the arrow keys.\",\n \"settings.layout.reset\": \"Reset panel widths\",\n \"settings.projects\": \"Projects\",\n \"settings.projects.register.label\": \"Register a local repository\",\n \"settings.projects.register.description\":\n \"The absolute path to a Git repository on this machine. Its directory name becomes the project name.\",\n \"settings.projects.register.placeholder\": \"/absolute/path/to/your-repository\",\n \"settings.projects.register.action\": \"Register repository\",\n \"settings.projects.repositoryLabel\": \"Repository\",\n \"settings.projects.unusable\":\n \"This path is not a Git repository right now, so any stage that changes files is refused here.\",\n \"settings.projects.repair\": \"Repair demo repository\",\n \"language.change\": \"Change language\",\n \"language.english\": \"English\",\n \"language.russian\": \"Русский\",\n \"nav.humanRequests\": \"Human requests\",\n \"nav.workspace\": \"Workspace\",\n \"nav.open\": \"Open navigation\",\n \"nav.yourProjects\": \"Your projects\",\n \"nav.currentWork\": \"Current work\",\n \"connection.connecting\": \"Connecting…\",\n \"connection.local\": \"Local daemon\",\n \"connection.offline\": \"Offline\",\n \"connection.recovery.retryTitle\": \"Loomrail is temporarily unreachable\",\n \"connection.recovery.retryDescription\":\n \"Check that the local process is still running. You can retry without losing saved work.\",\n \"connection.recovery.reopenTitle\": \"This local session has ended\",\n \"connection.recovery.reopenDescription\":\n \"Stop the old process if needed, then start Loomrail from the repository. A fresh authenticated tab will open automatically.\",\n \"connection.recovery.command\": \"Run in a terminal\",\n \"connection.recovery.retryAction\": \"Try again\",\n \"theme.change\": \"Change color theme\",\n \"theme.light\": \"Light\",\n \"theme.dark\": \"Dark\",\n \"theme.system\": \"System\",\n \"project.switch\": \"Switch project\",\n \"project.loading\": \"Loading…\",\n \"project.none\": \"No projects\",\n \"project.noneSingle\": \"No project\",\n search: \"Search\",\n \"task.new\": \"New task\",\n \"task.create.description\":\n \"Create the work item first. Loomrail will propose the delivery pipeline after the brief is clear.\",\n \"task.create.title\": \"Title\",\n \"task.create.titlePlaceholder\": \"What should the team deliver?\",\n \"task.create.brief\": \"Brief\",\n \"task.create.briefDescription\": \"Enough context for the planning agents to ask useful questions.\",\n \"task.create.briefPlaceholder\": \"Outcome, constraints, relevant files…\",\n \"task.create.project\": \"Project\",\n \"task.create.priority\": \"Priority\",\n \"task.create.submit\": \"Create task\",\n \"task.edit\": \"Edit task\",\n \"task.edit.description\": \"Update the persisted brief and planning properties for this WorkItem.\",\n \"task.edit.criteriaDescription\": \"Write one acceptance criterion per line, up to 50.\",\n \"task.edit.criteriaError\": \"Use no more than 50 lines and 500 characters per criterion.\",\n \"task.edit.submit\": \"Save changes\",\n \"action.cancel\": \"Cancel\",\n \"action.closeDialog\": \"Close dialog\",\n \"view.active\": \"Active\",\n \"view.backlog\": \"Backlog\",\n \"view.allIssues\": \"All issues\",\n \"view.filter\": \"Filter tasks\",\n \"view.display\": \"Display settings\",\n \"view.ordering\": \"Ordering\",\n \"view.orderBy\": \"Order tasks by\",\n \"view.boardOptions\": \"Board options\",\n \"view.showEmptyColumns\": \"Show empty columns\",\n \"view.direction.asc\": \"Sort ascending\",\n \"view.direction.desc\": \"Sort descending\",\n \"view.title\": \"Title\",\n \"view.updated\": \"Updated\",\n \"view.created\": \"Created\",\n \"property.priority\": \"Priority\",\n \"work.current\": \"Current work\",\n \"work.boardLabel\": \"Current work board\",\n \"work.summary.needsYou\": \"Needs you\",\n \"work.summary.filter\": \"Quick filter\",\n \"work.summary.clear\": \"Clear quick filter\",\n \"view.actions\": \"Open view actions\",\n \"view.copyLink\": \"Copy view link\",\n \"filter.status\": \"Status\",\n \"filter.priority\": \"Priority\",\n \"filter.risk\": \"Risk\",\n \"filter.rootTitle\": \"Filters\",\n \"filter.search\": \"Search\",\n \"filter.addPlaceholder\": \"Add Filter…\",\n \"filter.placeholder\": \"Filter…\",\n \"filter.noProperties\": \"No matching properties\",\n \"filter.noValues\": \"No matching values\",\n \"filter.add\": \"Add\",\n \"filter.remove\": \"Remove\",\n \"filter.options\": \"options\",\n \"filter.backTo\": \"Back to\",\n \"filter.close\": \"Close filters\",\n \"filter.description\": \"Choose one or more task properties. Each selection is applied immediately.\",\n \"filter.edit\": \"Edit\",\n \"filter.is\": \"is\",\n \"filter.isAnyOf\": \"is any of\",\n \"filter.oneValue\": \"1 value\",\n \"filter.selectedValues\": \"selected values\",\n \"filter.clear\": \"Clear\",\n \"state.BACKLOG\": \"Backlog\",\n \"state.READY\": \"Ready\",\n \"state.IN_PROGRESS\": \"Running\",\n \"state.BLOCKED\": \"Blocked\",\n \"state.DONE\": \"Done\",\n \"state.CANCELLED\": \"Cancelled\",\n \"priority.LOW\": \"Low\",\n \"priority.MEDIUM\": \"Medium\",\n \"priority.HIGH\": \"High\",\n \"priority.URGENT\": \"Urgent\",\n \"risk.LOW\": \"Low\",\n \"risk.MEDIUM\": \"Medium\",\n \"risk.HIGH\": \"High\",\n \"risk.CRITICAL\": \"Critical\",\n \"type.EPIC\": \"Epic\",\n \"type.FEATURE\": \"Feature\",\n \"type.TASK\": \"Task\",\n \"type.BUG\": \"Bug\",\n \"type.SPIKE\": \"Spike\",\n \"type.SUBTASK\": \"Subtask\",\n \"stage.DISCOVERY\": \"Discovery\",\n \"stage.PLAN\": \"Plan\",\n \"stage.IMPLEMENT\": \"Implementation\",\n \"stage.REVIEW\": \"Review\",\n \"stage.QA\": \"QA\",\n \"stage.ACCEPTANCE\": \"Acceptance\",\n \"empty.noProjects.title\": \"No local projects yet\",\n \"empty.noProjects.description\":\n \"Register the two bundled, non-executable fixture projects to start a persisted board.\",\n \"empty.noProjects.action\": \"Initialize demo workspace\",\n \"loading.board.title\": \"Loading board…\",\n \"loading.inspector.title\": \"Loading task details…\",\n \"error.board.title\": \"The local board could not be loaded\",\n \"error.unknown\": \"Unknown error\",\n \"empty.active.title\": \"No active tasks\",\n \"empty.active.description\": \"Create a task, or switch to All issues to see finished work.\",\n \"empty.backlog.title\": \"The backlog is empty\",\n \"empty.backlog.description\": \"New tasks wait here until someone moves them to Ready.\",\n \"empty.all.title\": \"No tasks yet\",\n \"empty.all.description\": \"Create a task to start tracking delivery in this project.\",\n \"empty.filters.title\": \"No tasks match these filters\",\n \"empty.filters.description\": \"Edit a condition above or clear the filter bar.\",\n \"empty.noSelection.title\": \"No task selected\",\n \"empty.noSelection.description\": \"Choose a card on the board to inspect its persisted state and activity.\",\n \"task.move\": \"Move\",\n \"task.moveTo\": \"Move to {state}\",\n \"task.moveToShort\": \"To {state}\",\n \"task.overview\": \"Overview\",\n \"task.state\": \"State\",\n \"task.stage\": \"Stage\",\n \"task.type\": \"Type\",\n \"task.priority\": \"Priority\",\n \"task.risk\": \"Risk\",\n \"task.noBrief\": \"No brief has been added yet.\",\n \"task.acceptanceCriteria\": \"Acceptance criteria\",\n \"task.noAcceptanceCriteria\": \"No acceptance criteria have been recorded.\",\n \"task.activity\": \"Activity\",\n \"task.loadingActivity\": \"Loading activity…\",\n \"task.noActivity\": \"No activity recorded.\",\n \"task.activityCountMore\": \"{count}+\",\n \"task.loadMoreActivity\": \"Show more\",\n \"workflow.title\": \"Workflow\",\n \"workflow.mockName\": \"Delivery workflow\",\n \"workflow.start\": \"Start workflow\",\n \"workflow.startDescription\":\n \"Run the bounded Discovery → Acceptance workflow. It may stop for a durable question or owner decision before continuing.\",\n \"workflow.readyRequired\": \"Move this task to Ready before starting its workflow.\",\n \"workflow.loading\": \"Loading workflow…\",\n \"workflow.status.RUNNING\": \"Running\",\n \"workflow.status.WAITING_HUMAN\": \"Waiting for you\",\n \"workflow.status.SOFT_PAUSED\": \"Paused\",\n \"workflow.status.HARD_PAUSED\": \"Budget paused\",\n \"workflow.status.INTERRUPTED\": \"Interrupted\",\n \"workflow.status.SUCCEEDED\": \"Completed\",\n \"workflow.status.FAILED\": \"Failed\",\n \"workflow.status.CANCELLED\": \"Cancelled\",\n \"workflow.completed\": \"The bounded delivery workflow completed from its recorded decisions.\",\n \"workflow.stage.QUEUED\": \"Queued\",\n \"workflow.stage.RUNNING\": \"Running\",\n \"workflow.stage.WAITING_HUMAN\": \"Waiting\",\n \"workflow.stage.SOFT_PAUSED\": \"Paused\",\n \"workflow.stage.HARD_PAUSED\": \"Budget paused\",\n \"workflow.stage.INTERRUPTED\": \"Interrupted\",\n \"workflow.stage.CANCELLED\": \"Cancelled\",\n \"workflow.stage.SUCCEEDED\": \"Completed\",\n \"workflow.stage.other\": \"In progress\",\n \"workflow.action.pause\": \"Pause\",\n \"workflow.action.resume\": \"Resume\",\n \"workflow.action.cancel\": \"Cancel run\",\n \"workflow.action.override\": \"Approve {limit} token budget\",\n \"workflow.budget.title\": \"Estimated token budget\",\n \"workflow.budget.usage\": \"{used} of {limit}\",\n \"workflow.budget.revision\": \"Policy revision {revision}\",\n \"workflow.recovery.title\": \"Recovery report\",\n \"workflow.recovery.description\":\n \"A running attempt was interrupted safely after the local daemon restarted.\",\n \"workflow.hardPause.noProgress\": \"Paused: no progress\",\n \"workflow.hardPause.contextFloor\": \"Paused: context too large\",\n \"workflow.hardPause.providerRejected\": \"Paused: provider rejected input\",\n \"workflow.hardPause.providerStartFailed\": \"Paused: provider unavailable\",\n \"workflow.hardPause.sessionLimit\": \"Paused: session limit reached\",\n \"workflow.sessions.title\": \"Sessions\",\n \"workflow.sessions.attemptHeading\": \"Attempt {attempt}\",\n \"workflow.sessions.ordinal\": \"Session {ordinal}\",\n \"workflow.sessions.status.RUNNING\": \"Running\",\n \"workflow.sessions.status.COMPLETED\": \"Completed\",\n \"workflow.sessions.status.HANDOFF\": \"Handed off\",\n \"workflow.sessions.status.CONTEXT_EXHAUSTED\": \"Context exhausted\",\n \"workflow.sessions.status.INTERRUPTED\": \"Interrupted\",\n \"workflow.sessions.status.CANCELLED\": \"Cancelled\",\n \"workflow.sessions.handoffRequested\": \"Handoff requested\",\n \"workflow.sessions.occupancyPeak\": \"Peaked at {percent}% of the window\",\n \"workflow.sessions.occupancyAtHandoff\": \"{percent}% of the window at handoff\",\n \"workflow.sessions.usageQuality.ACTUAL\": \"(measured)\",\n \"workflow.sessions.usageQuality.PROVIDER_ESTIMATE\": \"(provider estimate)\",\n \"workflow.sessions.usageQuality.LOOMRAIL_ESTIMATE\": \"(Loomrail estimate)\",\n \"workflow.sessions.noCheckpointOnRequest\":\n \"This provider cannot wind down on request — losing recent work when a session is cut is expected for it.\",\n \"workflow.checkpoints.empty\": \"No checkpoint was published in this session.\",\n \"workflow.checkpoints.completed\": \"Completed\",\n \"workflow.checkpoints.remaining\": \"Remaining\",\n \"workflow.checkpoints.deadEnds\": \"Dead ends\",\n \"workflow.checkpoints.openQuestions\": \"Open questions\",\n \"workspace.title\": \"Workspace\",\n \"workspace.state\": \"State\",\n \"workspace.status.READY\": \"Ready\",\n \"workspace.status.ORPHANED\": \"Worktree gone\",\n \"workspace.status.REMOVED\": \"Removed\",\n \"workspace.repository\": \"Repository\",\n \"workspace.branch\": \"Branch\",\n \"workspace.worktree\": \"Worktree\",\n \"workspace.baseCommit\": \"Base commit\",\n \"workspace.baseCommit.none\": \"No commit yet\",\n \"workspace.notReady\":\n \"The worktree for this task is no longer on disk. Loomrail does not cut a second one, and nothing returns this workspace to service — the branch still holds whatever was committed to it.\",\n \"workspace.uncommitted\":\n \"Loomrail has committed nothing. The work sits in this worktree, on this branch, until you keep it or discard it.\",\n \"changes.title\": \"Changes\",\n \"changes.empty\": \"This task has changed nothing in its worktree yet.\",\n \"changes.truncated\":\n \"Only the first {count} changed files are listed. This worktree holds more than Loomrail prints here.\",\n \"changes.binary\": \"Binary\",\n \"changes.binaryNoPatch\": \"This is a binary file, so there is no text diff to show for it.\",\n \"changes.renamedFrom\": \"Renamed from {path}\",\n \"changes.lineCounts\": \"Lines added: {insertions}; removed: {deletions}\",\n \"changes.diffPending\": \"Reading this file’s diff…\",\n \"changes.diffUnavailable\": \"This diff cannot be read: the task no longer has a workspace.\",\n \"changes.patchTruncated\":\n \"Loomrail prints only the first part of this diff — {bytes} more bytes are not shown here.\",\n \"changes.status.ADDED\": \"Added\",\n \"changes.status.MODIFIED\": \"Modified\",\n \"changes.status.DELETED\": \"Deleted\",\n \"changes.status.RENAMED\": \"Renamed\",\n \"changes.error.WORKSPACE_WORKTREE_MISSING\":\n \"The worktree for this task is no longer on disk, so there is nothing left to read its changes from.\",\n \"changes.error.WORKSPACE_WORKTREE_UNREADABLE\":\n \"Loomrail cannot enter this task’s worktree, so it cannot say what changed. It may still hold the agent’s work, but Loomrail cannot verify that from here.\",\n \"changes.error.WORKSPACE_HAS_NO_BASELINE\":\n \"This workspace records no commit to compare against, so there is nothing to measure its changes from.\",\n \"changes.error.CHANGES_UNREADABLE\":\n \"Loomrail could not read this worktree against the commit it was cut from, so it is not showing a file list it cannot stand behind.\",\n \"changes.error.GIT_UNAVAILABLE\":\n \"Loomrail could not start git on this machine, so it cannot read what this task changed.\",\n \"changes.error.PATH_OUTSIDE_WORKSPACE\":\n \"That path lies outside this task’s worktree, so Loomrail did not read it.\",\n \"changes.error.PATH_NOT_A_FILE\": \"That path does not name a changed file in this worktree.\",\n \"changes.error.PATH_UNRESOLVABLE\": \"Loomrail could not resolve that path inside this worktree.\",\n \"changes.error.other\": \"Loomrail could not read what this task changed.\",\n \"acceptance.eyebrow\": \"Owner gate\",\n \"acceptance.title\": \"Acceptance package\",\n \"acceptance.evidence\": \"Recorded evidence\",\n \"acceptance.reviewEvidence\": \"Review report\",\n \"acceptance.qaEvidence\": \"QA report\",\n \"acceptance.checks\": \"{count} verified checks\",\n \"acceptance.evidenceCount\": \"{count} evidence records\",\n \"acceptance.matrix\": \"Criterion matrix\",\n \"acceptance.noCriteria\": \"No explicit criteria were recorded; review the evidence and release note.\",\n \"acceptance.accept\": \"Accept delivery\",\n \"acceptance.return\": \"Return to work\",\n \"acceptance.reject\": \"Reject\",\n \"acceptance.status.PENDING\": \"Needs decision\",\n \"acceptance.status.ACCEPTED\": \"Accepted\",\n \"acceptance.status.RETURNED\": \"Returned\",\n \"acceptance.status.REJECTED\": \"Rejected\",\n \"humanRequest.blocking\": \"Blocking request\",\n \"humanRequest.recommendation\": \"Recommendation\",\n \"humanRequest.recommended\": \"Recommended\",\n \"humanRequest.other\": \"Other\",\n \"humanRequest.otherPlaceholder\": \"Describe the direction to use…\",\n \"humanRequest.answerResume\": \"Answer & resume\",\n \"humanRequest.chooseAnswer\": \"Choose an answer before resuming.\",\n \"attention.title\": \"Needs your decision\",\n \"attention.count\": \"{count} blocking request\",\n \"attention.countMany\": \"{count} blocking requests\",\n \"event.created\": \"Task created\",\n \"event.createdDetail\": \"Added to the project backlog.\",\n \"event.updated\": \"Task updated\",\n \"event.updatedDetail\": \"Changed {fields}.\",\n \"event.stateChanged\": \"State changed\",\n \"event.stateChangedDetail\": \"{from} → {to}\",\n \"event.projectRegistered\": \"Project registered\",\n \"event.pipelineStarted\": \"Workflow started\",\n \"event.pipelineStartedDetail\": \"Delivery workflow entered {stage}.\",\n \"event.stageChanged\": \"Stage updated\",\n \"event.stageChangedDetail\": \"{stage}: {status}\",\n \"event.humanRequestOpened\": \"Decision requested\",\n \"event.humanRequestOpenedDetail\": \"{title}\",\n \"event.humanRequestResolved\": \"Decision recorded\",\n \"event.humanRequestResolvedDetail\": \"The owner's answer was recorded durably.\",\n \"event.usageRecorded\": \"Usage recorded\",\n \"event.usageRecordedDetail\": \"+{amount} estimated tokens · {total} total\",\n \"event.budgetThreshold\": \"Budget threshold reached\",\n \"event.budgetThresholdDetail\": \"{threshold}% · {total} estimated tokens\",\n \"event.pipelinePaused\": \"Workflow paused\",\n \"event.pipelinePausedDetail\": \"{kind} pause at {stage}\",\n \"event.pipelineResumed\": \"Workflow resumed\",\n \"event.pipelineResumedDetail\": \"Resumed {stage}\",\n \"event.pipelineCancelled\": \"Workflow cancelled\",\n \"event.pipelineCancelledDetail\": \"Execution stopped at {stage}\",\n \"event.budgetOverride\": \"Budget override approved\",\n \"event.budgetOverrideDetail\": \"Revision {revision} · {limit} estimated tokens\",\n \"event.recoveryCreated\": \"Workflow recovered\",\n \"event.recoveryCreatedDetail\": \"The orphaned {stage} attempt was marked interrupted.\",\n \"event.evidenceRecorded\": \"Evidence recorded\",\n \"event.evidenceRecordedDetail\": \"{title}\",\n \"event.acceptanceRequested\": \"Owner acceptance requested\",\n \"event.acceptanceRequestedDetail\": \"Review and QA evidence are ready for a final decision.\",\n \"event.acceptanceResolved\": \"Acceptance resolved\",\n \"event.acceptanceResolvedDetail\": \"Owner action: {action}\",\n \"event.pipelineCompleted\": \"Workflow completed\",\n \"event.pipelineCompletedDetail\": \"The bounded delivery workflow finished.\",\n \"event.providerSessionStarted\": \"Agent session started\",\n \"event.providerSessionStartedDetail\": \"Session {ordinal}\",\n \"event.checkpointPublished\": \"Checkpoint published\",\n \"event.checkpointPublishedDetail\": \"{summary}\",\n \"event.contextHandoffRequested\": \"Handoff requested\",\n \"event.contextHandoffRequestedDetail\": \"Session {ordinal} is wrapping up\",\n \"event.providerSessionEnded\": \"Agent session ended\",\n \"event.providerSessionEndedDetail\": \"{reason}\",\n \"event.contextFloorExceeded\": \"Required context did not fit\",\n \"event.contextFloorExceededDetail\": \"Session {ordinal} needed {requiredBytes} bytes of {budgetBytes}\",\n \"event.workspaceCreated\": \"Workspace created\",\n \"event.workspaceCreatedDetail\": \"Branch {branch}\",\n \"event.workspaceOrphaned\": \"Workspace orphaned\",\n \"event.workspaceOrphanedDetail\": \"The worktree is gone or prunable\",\n \"field.title\": \"title\",\n \"field.description\": \"description\",\n \"field.priority\": \"priority\",\n \"field.risk\": \"risk\",\n \"field.acceptanceCriteria\": \"acceptance criteria\",\n} as const;\n\nconst ru = {\n \"settings.open\": \"Открыть настройки\",\n \"settings.title\": \"Настройки\",\n \"settings.description\": \"Параметры, сохранённые в этом браузере.\",\n \"settings.appearance\": \"Внешний вид\",\n \"settings.density\": \"Плотность доски\",\n \"settings.density.description\": \"Компактный режим уменьшает отступы внутри карточек и между ними.\",\n \"settings.density.comfortable\": \"Обычная\",\n \"settings.density.compact\": \"Компактная\",\n \"layout.resize.sidebar\": \"Изменить ширину сайдбара\",\n \"layout.resize.inspector\": \"Изменить ширину инспектора\",\n \"settings.layout\": \"Расположение\",\n \"settings.layout.description\": \"Потяните край панели или подвиньте его стрелками на клавиатуре.\",\n \"settings.layout.reset\": \"Сбросить ширину панелей\",\n \"settings.projects\": \"Проекты\",\n \"settings.projects.register.label\": \"Подключить локальный репозиторий\",\n \"settings.projects.register.description\":\n \"Абсолютный путь к Git-репозиторию на этой машине. Имя каталога станет именем проекта.\",\n \"settings.projects.register.placeholder\": \"/absolute/path/to/your-repository\",\n \"settings.projects.register.action\": \"Подключить репозиторий\",\n \"settings.projects.repositoryLabel\": \"Репозиторий\",\n \"settings.projects.unusable\":\n \"Сейчас по этому пути нет Git-репозитория, поэтому любая стадия, изменяющая файлы, здесь отклоняется.\",\n \"settings.projects.repair\": \"Починить demo-репозиторий\",\n \"language.change\": \"Сменить язык\",\n \"language.english\": \"English\",\n \"language.russian\": \"Русский\",\n \"nav.humanRequests\": \"Запросы человеку\",\n \"nav.workspace\": \"Пространство\",\n \"nav.open\": \"Открыть навигацию\",\n \"nav.yourProjects\": \"Ваши проекты\",\n \"nav.currentWork\": \"Текущая работа\",\n \"connection.connecting\": \"Подключение…\",\n \"connection.local\": \"Local daemon\",\n \"connection.offline\": \"Нет подключения\",\n \"connection.recovery.retryTitle\": \"Loomrail временно недоступен\",\n \"connection.recovery.retryDescription\":\n \"Проверьте, что локальный процесс ещё работает. Повторная попытка не затронет сохранённые данные.\",\n \"connection.recovery.reopenTitle\": \"Эта локальная сессия завершилась\",\n \"connection.recovery.reopenDescription\":\n \"При необходимости остановите старый процесс, затем запустите Loomrail из репозитория. Новая авторизованная вкладка откроется автоматически.\",\n \"connection.recovery.command\": \"Выполните в терминале\",\n \"connection.recovery.retryAction\": \"Повторить\",\n \"theme.change\": \"Сменить тему\",\n \"theme.light\": \"Светлая\",\n \"theme.dark\": \"Тёмная\",\n \"theme.system\": \"Системная\",\n \"project.switch\": \"Сменить проект\",\n \"project.loading\": \"Загрузка…\",\n \"project.none\": \"Проектов нет\",\n \"project.noneSingle\": \"Нет проекта\",\n search: \"Поиск\",\n \"task.new\": \"Новая задача\",\n \"task.create.description\":\n \"Сначала создайте задачу. Loomrail предложит конвейер доставки, когда описание станет достаточно ясным.\",\n \"task.create.title\": \"Название\",\n \"task.create.titlePlaceholder\": \"Какой результат должна получить команда?\",\n \"task.create.brief\": \"Описание\",\n \"task.create.briefDescription\":\n \"Добавьте контекст, чтобы планирующие агенты могли задать полезные вопросы.\",\n \"task.create.briefPlaceholder\": \"Результат, ограничения, важные файлы…\",\n \"task.create.project\": \"Проект\",\n \"task.create.priority\": \"Приоритет\",\n \"task.create.submit\": \"Создать задачу\",\n \"task.edit\": \"Редактировать задачу\",\n \"task.edit.description\": \"Обновите сохранённое описание и параметры планирования WorkItem.\",\n \"task.edit.criteriaDescription\": \"Один критерий приёмки на строку, не более 50.\",\n \"task.edit.criteriaError\": \"Не более 50 строк и 500 символов в каждом критерии.\",\n \"task.edit.submit\": \"Сохранить изменения\",\n \"action.cancel\": \"Отмена\",\n \"action.closeDialog\": \"Закрыть окно\",\n \"view.active\": \"Активные\",\n \"view.backlog\": \"Бэклог\",\n \"view.allIssues\": \"Все задачи\",\n \"view.filter\": \"Фильтровать задачи\",\n \"view.display\": \"Настройки отображения\",\n \"view.ordering\": \"Сортировка\",\n \"view.orderBy\": \"Сортировать задачи по\",\n \"view.boardOptions\": \"Настройки доски\",\n \"view.showEmptyColumns\": \"Показывать пустые колонки\",\n \"view.direction.asc\": \"Сортировать по возрастанию\",\n \"view.direction.desc\": \"Сортировать по убыванию\",\n \"view.title\": \"Название\",\n \"view.updated\": \"Обновлено\",\n \"view.created\": \"Создано\",\n \"property.priority\": \"Приоритет\",\n \"work.current\": \"Текущая работа\",\n \"work.boardLabel\": \"Доска текущей работы\",\n \"work.summary.needsYou\": \"Ждут вас\",\n \"work.summary.filter\": \"Быстрый фильтр\",\n \"work.summary.clear\": \"Убрать быстрый фильтр\",\n \"view.actions\": \"Действия представления\",\n \"view.copyLink\": \"Копировать ссылку\",\n \"filter.status\": \"Статус\",\n \"filter.priority\": \"Приоритет\",\n \"filter.risk\": \"Риск\",\n \"filter.rootTitle\": \"Фильтры\",\n \"filter.search\": \"Поиск\",\n \"filter.addPlaceholder\": \"Добавить фильтр…\",\n \"filter.placeholder\": \"Фильтр…\",\n \"filter.noProperties\": \"Подходящих свойств нет\",\n \"filter.noValues\": \"Подходящих значений нет\",\n \"filter.add\": \"Добавить\",\n \"filter.remove\": \"Убрать\",\n \"filter.options\": \"варианты\",\n \"filter.backTo\": \"Назад к\",\n \"filter.close\": \"Закрыть фильтры\",\n \"filter.description\": \"Выберите одно или несколько свойств задачи. Изменения применяются сразу.\",\n \"filter.edit\": \"Изменить\",\n \"filter.is\": \"равно\",\n \"filter.isAnyOf\": \"одно из\",\n \"filter.oneValue\": \"1 значение\",\n \"filter.selectedValues\": \"выбранные значения\",\n \"filter.clear\": \"Очистить\",\n \"state.BACKLOG\": \"Бэклог\",\n \"state.READY\": \"Готово к работе\",\n \"state.IN_PROGRESS\": \"В работе\",\n \"state.BLOCKED\": \"Заблокировано\",\n \"state.DONE\": \"Завершено\",\n \"state.CANCELLED\": \"Отменено\",\n \"priority.LOW\": \"Низкий\",\n \"priority.MEDIUM\": \"Средний\",\n \"priority.HIGH\": \"Высокий\",\n \"priority.URGENT\": \"Срочный\",\n \"risk.LOW\": \"Низкий\",\n \"risk.MEDIUM\": \"Средний\",\n \"risk.HIGH\": \"Высокий\",\n \"risk.CRITICAL\": \"Критический\",\n \"type.EPIC\": \"Эпик\",\n \"type.FEATURE\": \"Функция\",\n \"type.TASK\": \"Задача\",\n \"type.BUG\": \"Ошибка\",\n \"type.SPIKE\": \"Исследование\",\n \"type.SUBTASK\": \"Подзадача\",\n \"stage.DISCOVERY\": \"Исследование\",\n \"stage.PLAN\": \"План\",\n \"stage.IMPLEMENT\": \"Реализация\",\n \"stage.REVIEW\": \"Проверка\",\n \"stage.QA\": \"QA\",\n \"stage.ACCEPTANCE\": \"Приёмка\",\n \"empty.noProjects.title\": \"Локальных проектов пока нет\",\n \"empty.noProjects.description\":\n \"Зарегистрируйте два встроенных безопасных demo-проекта, чтобы получить сохраняемую доску.\",\n \"empty.noProjects.action\": \"Инициализировать demo-пространство\",\n \"loading.board.title\": \"Загружаем доску…\",\n \"loading.inspector.title\": \"Загружаем детали задачи…\",\n \"error.board.title\": \"Не удалось загрузить локальную доску\",\n \"error.unknown\": \"Неизвестная ошибка\",\n \"empty.active.title\": \"Активных задач нет\",\n \"empty.active.description\": \"Создайте задачу или откройте «Все задачи», чтобы увидеть завершённые.\",\n \"empty.backlog.title\": \"Бэклог пуст\",\n \"empty.backlog.description\": \"Новые задачи ждут здесь, пока их не переведут в «Готово к работе».\",\n \"empty.all.title\": \"Задач пока нет\",\n \"empty.all.description\": \"Создайте задачу, чтобы начать вести доставку в этом проекте.\",\n \"empty.filters.title\": \"Нет задач с такими фильтрами\",\n \"empty.filters.description\": \"Измените условие выше или очистите строку фильтров.\",\n \"empty.noSelection.title\": \"Задача не выбрана\",\n \"empty.noSelection.description\": \"Выберите карточку на доске, чтобы посмотреть её состояние и историю.\",\n \"task.move\": \"Переместить\",\n \"task.moveTo\": \"Переместить в «{state}»\",\n \"task.moveToShort\": \"В «{state}»\",\n \"task.overview\": \"Обзор\",\n \"task.state\": \"Состояние\",\n \"task.stage\": \"Этап\",\n \"task.type\": \"Тип\",\n \"task.priority\": \"Приоритет\",\n \"task.risk\": \"Риск\",\n \"task.noBrief\": \"Описание ещё не добавлено.\",\n \"task.acceptanceCriteria\": \"Критерии приёмки\",\n \"task.noAcceptanceCriteria\": \"Критерии приёмки ещё не записаны.\",\n \"task.activity\": \"История\",\n \"task.loadingActivity\": \"Загружаем историю…\",\n \"task.noActivity\": \"История пока пуста.\",\n \"task.activityCountMore\": \"{count}+\",\n \"task.loadMoreActivity\": \"Показать ещё\",\n \"workflow.title\": \"Процесс\",\n \"workflow.mockName\": \"Процесс поставки\",\n \"workflow.start\": \"Запустить процесс\",\n \"workflow.startDescription\":\n \"Запустить ограниченный процесс «Исследование → Приёмка». Перед продолжением он может остановиться на сохранённом вопросе или решении владельца.\",\n \"workflow.readyRequired\": \"Перед запуском переведите задачу в состояние «Готово к работе».\",\n \"workflow.loading\": \"Загружаем процесс…\",\n \"workflow.status.RUNNING\": \"Выполняется\",\n \"workflow.status.WAITING_HUMAN\": \"Ждёт вас\",\n \"workflow.status.SOFT_PAUSED\": \"Приостановлен\",\n \"workflow.status.HARD_PAUSED\": \"Остановлен лимитом\",\n \"workflow.status.INTERRUPTED\": \"Прерван\",\n \"workflow.status.SUCCEEDED\": \"Завершён\",\n \"workflow.status.FAILED\": \"Ошибка\",\n \"workflow.status.CANCELLED\": \"Отменён\",\n \"workflow.completed\": \"Ограниченный процесс поставки завершён на основе сохранённых решений.\",\n \"workflow.stage.QUEUED\": \"В очереди\",\n \"workflow.stage.RUNNING\": \"Выполняется\",\n \"workflow.stage.WAITING_HUMAN\": \"Ожидает\",\n \"workflow.stage.SOFT_PAUSED\": \"Приостановлен\",\n \"workflow.stage.HARD_PAUSED\": \"Остановлен лимитом\",\n \"workflow.stage.INTERRUPTED\": \"Прерван\",\n \"workflow.stage.CANCELLED\": \"Отменён\",\n \"workflow.stage.SUCCEEDED\": \"Завершено\",\n \"workflow.stage.other\": \"Выполняется\",\n \"workflow.action.pause\": \"Приостановить\",\n \"workflow.action.resume\": \"Продолжить\",\n \"workflow.action.cancel\": \"Отменить запуск\",\n \"workflow.action.override\": \"Одобрить лимит {limit} токенов\",\n \"workflow.budget.title\": \"Лимит оценочных токенов\",\n \"workflow.budget.usage\": \"{used} из {limit}\",\n \"workflow.budget.revision\": \"Ревизия политики {revision}\",\n \"workflow.recovery.title\": \"Отчёт о восстановлении\",\n \"workflow.recovery.description\":\n \"Выполнявшаяся попытка безопасно прервана после перезапуска локального демона.\",\n \"workflow.hardPause.noProgress\": \"Остановлен: нет прогресса\",\n \"workflow.hardPause.contextFloor\": \"Остановлен: контекст не помещается\",\n \"workflow.hardPause.providerRejected\": \"Остановлен: провайдер отклонил вход\",\n \"workflow.hardPause.providerStartFailed\": \"Остановлен: провайдер недоступен\",\n \"workflow.hardPause.sessionLimit\": \"Остановлен: достигнут предел сессий\",\n \"workflow.sessions.title\": \"Сессии\",\n \"workflow.sessions.attemptHeading\": \"Попытка {attempt}\",\n \"workflow.sessions.ordinal\": \"Сессия {ordinal}\",\n \"workflow.sessions.status.RUNNING\": \"Выполняется\",\n \"workflow.sessions.status.COMPLETED\": \"Завершена\",\n \"workflow.sessions.status.HANDOFF\": \"Передана дальше\",\n \"workflow.sessions.status.CONTEXT_EXHAUSTED\": \"Контекст исчерпан\",\n \"workflow.sessions.status.INTERRUPTED\": \"Прервана\",\n \"workflow.sessions.status.CANCELLED\": \"Отменена\",\n \"workflow.sessions.handoffRequested\": \"Запрошена передача\",\n \"workflow.sessions.occupancyPeak\": \"Пик — {percent}% окна\",\n \"workflow.sessions.occupancyAtHandoff\": \"{percent}% окна на момент передачи\",\n \"workflow.sessions.usageQuality.ACTUAL\": \"(измерено)\",\n \"workflow.sessions.usageQuality.PROVIDER_ESTIMATE\": \"(оценка провайдера)\",\n \"workflow.sessions.usageQuality.LOOMRAIL_ESTIMATE\": \"(оценка Loomrail)\",\n \"workflow.sessions.noCheckpointOnRequest\":\n \"Этот провайдер не умеет сворачиваться по запросу — для него штатно терять недавнюю работу при обрыве сессии.\",\n \"workflow.checkpoints.empty\": \"В этой сессии checkpoint не публиковался.\",\n \"workflow.checkpoints.completed\": \"Сделано\",\n \"workflow.checkpoints.remaining\": \"Осталось\",\n \"workflow.checkpoints.deadEnds\": \"Тупики\",\n \"workflow.checkpoints.openQuestions\": \"Открытые вопросы\",\n \"workspace.title\": \"Рабочая область\",\n \"workspace.state\": \"Состояние\",\n \"workspace.status.READY\": \"Готова\",\n \"workspace.status.ORPHANED\": \"Worktree исчез\",\n \"workspace.status.REMOVED\": \"Удалена\",\n \"workspace.repository\": \"Репозиторий\",\n \"workspace.branch\": \"Ветка\",\n \"workspace.worktree\": \"Worktree\",\n \"workspace.baseCommit\": \"Базовый коммит\",\n \"workspace.baseCommit.none\": \"Коммитов ещё не было\",\n \"workspace.notReady\":\n \"Каталога worktree этой задачи больше нет на диске. Loomrail не создаёт второй, и вернуть эту рабочую область в строй нечем — ветка по-прежнему хранит всё, что в неё закоммичено.\",\n \"workspace.uncommitted\":\n \"Loomrail ничего не коммитил. Работа лежит в этом worktree, на этой ветке, пока вы её не сохраните или не удалите.\",\n \"changes.title\": \"Изменения\",\n \"changes.empty\": \"Задача пока ничего не изменила в своей рабочей области.\",\n \"changes.truncated\":\n \"Показаны только первые {count} изменённых файлов. В этом worktree их больше, чем Loomrail выводит здесь.\",\n \"changes.binary\": \"Бинарный\",\n \"changes.binaryNoPatch\": \"Это бинарный файл — текстового диффа для него нет.\",\n \"changes.renamedFrom\": \"Переименован из {path}\",\n \"changes.lineCounts\": \"Добавлено строк: {insertions}, удалено: {deletions}\",\n \"changes.diffPending\": \"Читаем дифф этого файла…\",\n \"changes.diffUnavailable\": \"Этот дифф прочитать нечем: у задачи больше нет рабочей области.\",\n \"changes.patchTruncated\":\n \"Loomrail выводит только начало этого диффа — ещё {bytes} байт здесь не показано.\",\n \"changes.status.ADDED\": \"Добавлен\",\n \"changes.status.MODIFIED\": \"Изменён\",\n \"changes.status.DELETED\": \"Удалён\",\n \"changes.status.RENAMED\": \"Переименован\",\n \"changes.error.WORKSPACE_WORKTREE_MISSING\":\n \"Каталога worktree этой задачи больше нет на диске — читать изменения больше не из чего.\",\n \"changes.error.WORKSPACE_WORKTREE_UNREADABLE\":\n \"Loomrail не может войти в worktree этой задачи и поэтому не может сказать, что изменилось. Возможно, работа агента всё ещё там, но Loomrail не может проверить это отсюда.\",\n \"changes.error.WORKSPACE_HAS_NO_BASELINE\":\n \"У этой рабочей области не записан коммит для сравнения, поэтому измерять изменения не от чего.\",\n \"changes.error.CHANGES_UNREADABLE\":\n \"Loomrail не смог прочитать этот worktree относительно коммита, от которого он отрезан, и не показывает список, за который не может отвечать.\",\n \"changes.error.GIT_UNAVAILABLE\":\n \"Loomrail не смог запустить git на этой машине и поэтому не может прочитать, что изменила задача.\",\n \"changes.error.PATH_OUTSIDE_WORKSPACE\":\n \"Этот путь лежит за пределами рабочей области задачи, и Loomrail его не читал.\",\n \"changes.error.PATH_NOT_A_FILE\": \"Этот путь не именует изменённый файл в этом worktree.\",\n \"changes.error.PATH_UNRESOLVABLE\": \"Loomrail не смог разрешить этот путь внутри этого worktree.\",\n \"changes.error.other\": \"Loomrail не смог прочитать, что изменила эта задача.\",\n \"acceptance.eyebrow\": \"Решение владельца\",\n \"acceptance.title\": \"Пакет приёмки\",\n \"acceptance.evidence\": \"Сохранённые доказательства\",\n \"acceptance.reviewEvidence\": \"Отчёт ревью\",\n \"acceptance.qaEvidence\": \"Отчёт QA\",\n \"acceptance.checks\": \"Проверок: {count}\",\n \"acceptance.evidenceCount\": \"Отчётов: {count}\",\n \"acceptance.matrix\": \"Матрица критериев\",\n \"acceptance.noCriteria\": \"Явные критерии не заданы — проверьте отчёты и описание релиза.\",\n \"acceptance.accept\": \"Принять результат\",\n \"acceptance.return\": \"Вернуть в работу\",\n \"acceptance.reject\": \"Отклонить\",\n \"acceptance.status.PENDING\": \"Нужно решение\",\n \"acceptance.status.ACCEPTED\": \"Принято\",\n \"acceptance.status.RETURNED\": \"Возвращено\",\n \"acceptance.status.REJECTED\": \"Отклонено\",\n \"humanRequest.blocking\": \"Блокирующий запрос\",\n \"humanRequest.recommendation\": \"Рекомендация\",\n \"humanRequest.recommended\": \"Рекомендуется\",\n \"humanRequest.other\": \"Другое\",\n \"humanRequest.otherPlaceholder\": \"Опишите, какое направление использовать…\",\n \"humanRequest.answerResume\": \"Ответить и продолжить\",\n \"humanRequest.chooseAnswer\": \"Выберите ответ, чтобы продолжить.\",\n \"attention.title\": \"Нужно ваше решение\",\n \"attention.count\": \"{count} блокирующий запрос\",\n \"attention.countMany\": \"{count} блокирующих запросов\",\n \"event.created\": \"Задача создана\",\n \"event.createdDetail\": \"Добавлена в бэклог проекта.\",\n \"event.updated\": \"Задача обновлена\",\n \"event.updatedDetail\": \"Изменено: {fields}.\",\n \"event.stateChanged\": \"Состояние изменено\",\n \"event.stateChangedDetail\": \"{from} → {to}\",\n \"event.projectRegistered\": \"Проект зарегистрирован\",\n \"event.pipelineStarted\": \"Процесс запущен\",\n \"event.pipelineStartedDetail\": \"Процесс поставки перешёл к этапу «{stage}».\",\n \"event.stageChanged\": \"Этап обновлён\",\n \"event.stageChangedDetail\": \"{stage}: {status}\",\n \"event.humanRequestOpened\": \"Требуется решение\",\n \"event.humanRequestOpenedDetail\": \"{title}\",\n \"event.humanRequestResolved\": \"Решение сохранено\",\n \"event.humanRequestResolvedDetail\": \"Ответ владельца сохранён в журнале.\",\n \"event.usageRecorded\": \"Расход записан\",\n \"event.usageRecordedDetail\": \"+{amount} оценочных токенов · всего {total}\",\n \"event.budgetThreshold\": \"Достигнут порог бюджета\",\n \"event.budgetThresholdDetail\": \"{threshold}% · {total} оценочных токенов\",\n \"event.pipelinePaused\": \"Процесс приостановлен\",\n \"event.pipelinePausedDetail\": \"Пауза {kind} на этапе «{stage}»\",\n \"event.pipelineResumed\": \"Процесс продолжен\",\n \"event.pipelineResumedDetail\": \"Продолжен этап «{stage}»\",\n \"event.pipelineCancelled\": \"Процесс отменён\",\n \"event.pipelineCancelledDetail\": \"Выполнение остановлено на этапе «{stage}»\",\n \"event.budgetOverride\": \"Новый бюджет одобрен\",\n \"event.budgetOverrideDetail\": \"Ревизия {revision} · {limit} оценочных токенов\",\n \"event.recoveryCreated\": \"Процесс восстановлен\",\n \"event.recoveryCreatedDetail\": \"Незавершённая попытка этапа «{stage}» помечена прерванной.\",\n \"event.evidenceRecorded\": \"Доказательство сохранено\",\n \"event.evidenceRecordedDetail\": \"{title}\",\n \"event.acceptanceRequested\": \"Требуется приёмка владельца\",\n \"event.acceptanceRequestedDetail\": \"Отчёты ревью и QA готовы для финального решения.\",\n \"event.acceptanceResolved\": \"Приёмка завершена\",\n \"event.acceptanceResolvedDetail\": \"Решение владельца: {action}\",\n \"event.pipelineCompleted\": \"Процесс завершён\",\n \"event.pipelineCompletedDetail\": \"Ограниченный процесс поставки завершён.\",\n \"event.providerSessionStarted\": \"Сессия агента начата\",\n \"event.providerSessionStartedDetail\": \"Сессия {ordinal}\",\n \"event.checkpointPublished\": \"Checkpoint опубликован\",\n \"event.checkpointPublishedDetail\": \"{summary}\",\n \"event.contextHandoffRequested\": \"Запрошена передача\",\n \"event.contextHandoffRequestedDetail\": \"Сессия {ordinal} сворачивается\",\n \"event.providerSessionEnded\": \"Сессия агента завершена\",\n \"event.providerSessionEndedDetail\": \"{reason}\",\n \"event.contextFloorExceeded\": \"Обязательный контекст не поместился\",\n \"event.contextFloorExceededDetail\": \"Сессии {ordinal} нужно {requiredBytes} байт из {budgetBytes}\",\n \"event.workspaceCreated\": \"Рабочая область создана\",\n \"event.workspaceCreatedDetail\": \"Ветка {branch}\",\n \"event.workspaceOrphaned\": \"Рабочая область осиротела\",\n \"event.workspaceOrphanedDetail\": \"Worktree отсутствует или может быть удалён\",\n \"field.title\": \"название\",\n \"field.description\": \"описание\",\n \"field.priority\": \"приоритет\",\n \"field.risk\": \"риск\",\n \"field.acceptanceCriteria\": \"критерии приёмки\",\n} satisfies Record<keyof typeof en, string>;\n\nexport type Locale = \"en\" | \"ru\";\nexport type TranslationKey = keyof typeof en;\nexport type Translator = (\n key: TranslationKey,\n parameters?: Readonly<Record<string, string | number>>,\n) => string;\n\nconst messages: Record<Locale, Record<TranslationKey, string>> = { en, ru };\n\nexport const isLocale = (value: unknown): value is Locale => value === \"en\" || value === \"ru\";\n\nexport const readLocale = (): Locale => {\n const stored = window.localStorage.getItem(LOCALE_STORAGE_KEY);\n if (isLocale(stored)) return stored;\n return window.navigator.language.toLowerCase().startsWith(\"ru\") ? \"ru\" : \"en\";\n};\n\nexport const applyLocale = (locale: Locale): void => {\n window.localStorage.setItem(LOCALE_STORAGE_KEY, locale);\n document.documentElement.lang = locale;\n};\n\nexport const translate = (\n locale: Locale,\n key: TranslationKey,\n parameters: Readonly<Record<string, string | number>> = {},\n): string =>\n Object.entries(parameters).reduce(\n (message, [name, value]) => message.replaceAll(`{${name}}`, String(value)),\n messages[locale][key],\n );\n\ntype I18nContextValue = {\n locale: Locale;\n setLocale: (locale: Locale) => void;\n t: Translator;\n};\n\nconst I18nContext = createContext<I18nContextValue | null>(null);\n\nexport const I18nProvider = ({ children }: { children: ReactNode }): React.JSX.Element => {\n const [locale, setLocaleState] = useState<Locale>(() => {\n const initialLocale = readLocale();\n applyLocale(initialLocale);\n return initialLocale;\n });\n const value = useMemo<I18nContextValue>(\n () => ({\n locale,\n setLocale: (nextLocale) => {\n applyLocale(nextLocale);\n setLocaleState(nextLocale);\n },\n t: (key, parameters) => translate(locale, key, parameters),\n }),\n [locale],\n );\n\n return <I18nContext.Provider value={value}>{children}</I18nContext.Provider>;\n};\n\nexport const useI18n = (): I18nContextValue => {\n const value = useContext(I18nContext);\n if (!value) throw new Error(\"useI18n must be rendered inside I18nProvider\");\n return value;\n};\n","export const panels = [\"sidebar\", \"inspector\"] as const;\nexport type PanelName = (typeof panels)[number];\n\ntype PanelBounds = { defaultWidth: number; max: number; min: number; property: string };\n\n/**\n * Width limits for the resizable panels.\n *\n * `defaultWidth` mirrors the design token of the same name; a unit test reads `tokens.css` and\n * fails if the two ever disagree, so the stylesheet stays the single source for the default.\n */\nexport const panelBounds: Record<PanelName, PanelBounds> = {\n sidebar: { defaultWidth: 240, max: 360, min: 200, property: \"--lr-size-sidebar\" },\n inspector: { defaultWidth: 344, max: 520, min: 280, property: \"--lr-size-inspector\" },\n};\n\nconst storageKey = (panel: PanelName): string => `loomrail-panel-${panel}`;\n\nexport const clampPanelWidth = (panel: PanelName, width: number): number => {\n const { max, min } = panelBounds[panel];\n if (!Number.isFinite(width)) return panelBounds[panel].defaultWidth;\n return Math.min(max, Math.max(min, Math.round(width)));\n};\n\nexport const readPanelWidth = (panel: PanelName): number => {\n const stored = window.localStorage.getItem(storageKey(panel));\n if (stored === null) return panelBounds[panel].defaultWidth;\n return clampPanelWidth(panel, Number(stored));\n};\n\n/**\n * Applies a panel width as a CSS custom property.\n *\n * The default clears the property and the stored value, so the stylesheet keeps ownership of the\n * default — including the narrower one it uses on smaller desktops.\n */\nexport const applyPanelWidth = (panel: PanelName, width: number): void => {\n const { defaultWidth, property } = panelBounds[panel];\n const clamped = clampPanelWidth(panel, width);\n if (clamped === defaultWidth) {\n document.documentElement.style.removeProperty(property);\n window.localStorage.removeItem(storageKey(panel));\n return;\n }\n\n document.documentElement.style.setProperty(property, `${clamped.toString()}px`);\n window.localStorage.setItem(storageKey(panel), clamped.toString());\n};\n\nexport const resetPanelWidths = (): void => {\n for (const panel of panels) applyPanelWidth(panel, panelBounds[panel].defaultWidth);\n};\n\nexport const hasCustomPanelWidths = (): boolean =>\n panels.some((panel) => window.localStorage.getItem(storageKey(panel)) !== null);\n","import { useEffect, useState } from \"react\";\n\nimport { useI18n } from \"../i18n\";\nimport { applyPanelWidth, clampPanelWidth, panelBounds, readPanelWidth, type PanelName } from \"../layout\";\n\nconst KEYBOARD_STEP = 16;\n\nexport type PanelResizerProps = {\n /** Which edge the handle sits on, which decides how pointer movement maps to width. */\n edge: \"start\" | \"end\";\n panel: PanelName;\n};\n\n/**\n * A draggable divider for a resizable panel.\n *\n * Implemented as a real `separator` with a value, so the panel can be resized from the keyboard as\n * well as by pointer. Width is written straight to the CSS custom property while dragging, which\n * keeps the panel following the pointer without re-rendering the board on every frame.\n */\nexport const PanelResizer = ({ edge, panel }: PanelResizerProps): React.JSX.Element => {\n const { t } = useI18n();\n const [width, setWidth] = useState(() => readPanelWidth(panel));\n const [dragging, setDragging] = useState(false);\n const { max, min } = panelBounds[panel];\n\n useEffect(() => {\n if (!dragging) return undefined;\n\n const move = (event: PointerEvent): void => {\n const next = edge === \"start\" ? event.clientX : window.innerWidth - event.clientX;\n const clamped = clampPanelWidth(panel, next);\n setWidth(clamped);\n applyPanelWidth(panel, clamped);\n };\n const stop = (): void => {\n setDragging(false);\n };\n\n document.body.classList.add(\"is-resizing\");\n window.addEventListener(\"pointermove\", move);\n window.addEventListener(\"pointerup\", stop);\n return () => {\n document.body.classList.remove(\"is-resizing\");\n window.removeEventListener(\"pointermove\", move);\n window.removeEventListener(\"pointerup\", stop);\n };\n }, [dragging, edge, panel]);\n\n const nudge = (delta: number): void => {\n const clamped = clampPanelWidth(panel, width + delta);\n setWidth(clamped);\n applyPanelWidth(panel, clamped);\n };\n\n return (\n <div\n aria-label={t(`layout.resize.${panel}`)}\n aria-orientation=\"vertical\"\n aria-valuemax={max}\n aria-valuemin={min}\n aria-valuenow={width}\n className=\"panel-resizer\"\n onDoubleClick={() => {\n const { defaultWidth } = panelBounds[panel];\n setWidth(defaultWidth);\n applyPanelWidth(panel, defaultWidth);\n }}\n onKeyDown={(event) => {\n const towardsWider = edge === \"start\" ? \"ArrowRight\" : \"ArrowLeft\";\n const towardsNarrower = edge === \"start\" ? \"ArrowLeft\" : \"ArrowRight\";\n if (event.key !== towardsWider && event.key !== towardsNarrower) return;\n event.preventDefault();\n nudge(event.key === towardsWider ? KEYBOARD_STEP : -KEYBOARD_STEP);\n }}\n onPointerDown={(event) => {\n event.preventDefault();\n setWidth(readPanelWidth(panel));\n setDragging(true);\n }}\n role=\"separator\"\n tabIndex={0}\n />\n );\n};\n","import {\n apiErrorResponseSchema,\n eventsResponseSchema,\n humanRequestsResponseSchema,\n projectsResponseSchema,\n providerCapabilitiesResponseSchema,\n providerSessionsResponseSchema,\n stateCommandResultSchema,\n workItemChangesResponseSchema,\n workItemFileDiffResponseSchema,\n workItemsResponseSchema,\n workItemWorkspaceResponseSchema,\n workflowSnapshotSchema,\n type FixtureProjectId,\n type AcceptanceAction,\n type AcceptancePackage,\n type HumanRequest,\n type HumanRequestAnswer,\n type PipelineRun,\n type WorkItem,\n type WorkItemState,\n} from \"@loomrail/contracts\";\n\ntype RuntimeSchema<T> = {\n parse: (value: unknown) => T;\n};\n\nconst CSRF_STORAGE_KEY = \"loomrail.csrf-token\";\n\nexport type LocalApiRecovery = \"none\" | \"reopen\" | \"retry\";\n\ntype LocalApiErrorOptions = {\n code: string;\n correlationId?: string;\n message: string;\n recovery: LocalApiRecovery;\n status: number;\n};\n\nexport class LocalApiError extends Error {\n readonly code: string;\n readonly correlationId: string | undefined;\n readonly recovery: LocalApiRecovery;\n readonly status: number;\n\n constructor({ code, correlationId, message, recovery, status }: LocalApiErrorOptions) {\n super(message);\n this.name = \"LocalApiError\";\n this.code = code;\n this.correlationId = correlationId;\n this.recovery = recovery;\n this.status = status;\n }\n}\n\nconst recoveryFor = (code: string, status: number): LocalApiRecovery => {\n if ([\"BOOTSTRAP_REJECTED\", \"CSRF_REJECTED\", \"SESSION_REQUIRED\"].includes(code)) return \"reopen\";\n return status === 0 || status >= 500 ? \"retry\" : \"none\";\n};\n\nexport const readLocalApiError = async (response: Response): Promise<LocalApiError> => {\n const body: unknown = await response.json().catch(() => undefined);\n const parsed = apiErrorResponseSchema.safeParse(body);\n if (parsed.success) {\n return new LocalApiError({\n code: parsed.data.error.code,\n correlationId: parsed.data.error.correlationId,\n message: parsed.data.error.message,\n recovery: recoveryFor(parsed.data.error.code, response.status),\n status: response.status,\n });\n }\n return new LocalApiError({\n code: \"LOCAL_API_ERROR\",\n message: `Local daemon returned HTTP ${response.status.toString()}`,\n recovery: recoveryFor(\"LOCAL_API_ERROR\", response.status),\n status: response.status,\n });\n};\n\nexport const isLocalApiError = (error: unknown): error is LocalApiError => error instanceof LocalApiError;\n\nexport const createDaemonUnavailableError = (): LocalApiError =>\n new LocalApiError({\n code: \"LOCAL_DAEMON_UNAVAILABLE\",\n message: \"The local Loomrail daemon could not be reached\",\n recovery: \"retry\",\n status: 0,\n });\n\nconst readCsrfToken = (): string | undefined => window.sessionStorage.getItem(CSRF_STORAGE_KEY) ?? undefined;\n\nexport const storeCsrfToken = (csrfToken: string): void => {\n window.sessionStorage.setItem(CSRF_STORAGE_KEY, csrfToken);\n};\n\nexport const requestLocalApi = async <T>(\n path: string,\n schema: RuntimeSchema<T>,\n init: RequestInit = {},\n): Promise<T> => {\n const method = (init.method ?? \"GET\").toUpperCase();\n const headers = new Headers(init.headers);\n headers.set(\"accept\", \"application/json\");\n\n if (init.body !== undefined) {\n headers.set(\"content-type\", \"application/json\");\n }\n\n if (![\"GET\", \"HEAD\", \"OPTIONS\"].includes(method)) {\n const csrfToken = readCsrfToken();\n if (!csrfToken) {\n throw new LocalApiError({\n code: \"LOCAL_SESSION_REQUIRED\",\n message: \"The local session must be reopened before changing data\",\n recovery: \"reopen\",\n status: 0,\n });\n }\n headers.set(\"x-loomrail-csrf\", csrfToken);\n }\n\n let response: Response;\n try {\n response = await fetch(path, {\n ...init,\n credentials: \"same-origin\",\n headers,\n });\n } catch {\n throw createDaemonUnavailableError();\n }\n\n if (!response.ok) {\n throw await readLocalApiError(response);\n }\n\n return schema.parse(await response.json());\n};\n\nexport const listProjects = async () => requestLocalApi(\"/api/v1/projects\", projectsResponseSchema);\n\nexport const listProjectWorkItems = async (projectId: string) =>\n requestLocalApi(`/api/v1/projects/${encodeURIComponent(projectId)}/work-items`, workItemsResponseSchema);\n\nexport const activityPageSize = 30;\n\n/** Reads one page of an item's activity newest first; `before` continues from a page's `nextSequence`. */\nexport const listWorkItemEvents = async (projectId: string, workItemId: string, before?: number) => {\n const query = new URLSearchParams({\n aggregateId: workItemId,\n limit: activityPageSize.toString(),\n order: \"DESC\",\n projectId,\n ...(before === undefined ? {} : { before: before.toString() }),\n });\n return requestLocalApi(`/api/v1/events?${query.toString()}`, eventsResponseSchema);\n};\n\nexport const getWorkItemWorkflow = async (workItemId: string) =>\n requestLocalApi(`/api/v1/work-items/${encodeURIComponent(workItemId)}/workflow`, workflowSnapshotSchema);\n\n/** Where this work item's agent writes (spec §4): repository branch, base commit and worktree path. */\nexport const getWorkItemWorkspace = async (workItemId: string) =>\n requestLocalApi(\n `/api/v1/work-items/${encodeURIComponent(workItemId)}/workspace`,\n workItemWorkspaceResponseSchema,\n );\n\n/**\n * What this work item's agent changed in its worktree (spec E1.5 §5): one record per file, with\n * status and line counts, and the flag saying whether the list itself was cut.\n *\n * Answers `changes: null` -- with 200 -- for a work item that has no workspace, which is the\n * ordinary state of every prose-only stage rather than a failure, exactly as `getWorkItemWorkspace`\n * above answers `workspace: null` for the same condition.\n */\nexport const getWorkItemChanges = async (workItemId: string) =>\n requestLocalApi(\n `/api/v1/work-items/${encodeURIComponent(workItemId)}/changes`,\n workItemChangesResponseSchema,\n );\n\n/**\n * The unified diff of ONE file in that worktree.\n *\n * A second call rather than a field on the summary above, because spec D5 makes them two handles on\n * purpose: the summary is cheap and reread while a stage runs, a body is expensive and wanted only\n * for the file the owner expanded. A client that fetched every body to render a list would undo\n * that split at the one layer it is visible from.\n *\n * The path is a value read out of the summary and sent back, so it is encoded rather than\n * interpolated: a changed path may legally contain `&`, `#`, `+` or a space, and any of those\n * unencoded would arrive at the daemon as a different path -- or as a second query parameter.\n */\nexport const getWorkItemFileDiff = async (workItemId: string, path: string) =>\n requestLocalApi(\n `/api/v1/work-items/${encodeURIComponent(workItemId)}/changes/diff?path=${encodeURIComponent(path)}`,\n workItemFileDiffResponseSchema,\n );\n\nexport const listProviderSessions = async (stageAttemptId: string) =>\n requestLocalApi(\n `/api/v1/stage-attempts/${encodeURIComponent(stageAttemptId)}/sessions`,\n providerSessionsResponseSchema,\n );\n\nexport const getProviderCapabilities = async () =>\n requestLocalApi(\"/api/v1/provider/capabilities\", providerCapabilitiesResponseSchema);\n\nexport const listOpenHumanRequests = async (projectId: string) => {\n const query = new URLSearchParams({ projectId, status: \"OPEN\" });\n return requestLocalApi(`/api/v1/human-requests?${query.toString()}`, humanRequestsResponseSchema);\n};\n\nexport const registerFixtureProject = async (fixtureId: FixtureProjectId): Promise<void> => {\n await requestLocalApi(\"/api/v1/projects/fixtures/register\", stateCommandResultSchema, {\n method: \"POST\",\n body: JSON.stringify({ schemaVersion: 1, commandId: crypto.randomUUID(), fixtureId }),\n });\n};\n\n/**\n * Registers a local Git repository the owner named as a Project (spec §4).\n *\n * Answers nothing on success for the same reason `registerFixtureProject` does not: the caller\n * refetches the Project list, which is where the new Project has to appear anyway. A refusal --\n * the path is not a repository, or it is a directory inside one -- arrives as an Error carrying the\n * daemon's own wording, which names the path and says what to do about it, and the caller shows\n * that rather than a sentence of its own.\n */\nexport const registerRepositoryProject = async (repositoryPath: string): Promise<void> => {\n await requestLocalApi(\"/api/v1/projects/register\", stateCommandResultSchema, {\n method: \"POST\",\n body: JSON.stringify({ schemaVersion: 1, commandId: crypto.randomUUID(), repositoryPath }),\n });\n};\n\nexport type CreateWorkItemInput = {\n description: string;\n priority: WorkItem[\"priority\"];\n projectId: string;\n risk: WorkItem[\"risk\"];\n title: string;\n type: WorkItem[\"type\"];\n};\n\nexport const createWorkItem = async (input: CreateWorkItemInput): Promise<WorkItem> => {\n const result = await requestLocalApi(\"/api/v1/work-items\", stateCommandResultSchema, {\n method: \"POST\",\n body: JSON.stringify({\n schemaVersion: 1,\n commandId: crypto.randomUUID(),\n projectId: input.projectId,\n parentId: null,\n type: input.type,\n title: input.title,\n description: input.description,\n priority: input.priority,\n risk: input.risk,\n acceptanceCriteria: [],\n }),\n });\n\n if (result.type !== \"WORK_ITEM_CREATED\") {\n throw new Error(\"The local daemon returned an unexpected create result\");\n }\n return result.workItem;\n};\n\nexport const moveWorkItem = async (workItem: WorkItem, targetState: WorkItemState): Promise<WorkItem> => {\n const result = await requestLocalApi(\n `/api/v1/work-items/${encodeURIComponent(workItem.id)}/move`,\n stateCommandResultSchema,\n {\n method: \"POST\",\n body: JSON.stringify({\n schemaVersion: 1,\n commandId: crypto.randomUUID(),\n expectedVersion: workItem.version,\n targetState,\n }),\n },\n );\n\n if (result.type !== \"WORK_ITEM_MOVED\") {\n throw new Error(\"The local daemon returned an unexpected move result\");\n }\n return result.workItem;\n};\n\nexport type UpdateWorkItemPatch = Partial<\n Pick<WorkItem, \"acceptanceCriteria\" | \"description\" | \"priority\" | \"risk\" | \"title\">\n>;\n\nexport const updateWorkItem = async (workItem: WorkItem, patch: UpdateWorkItemPatch): Promise<WorkItem> => {\n const result = await requestLocalApi(\n `/api/v1/work-items/${encodeURIComponent(workItem.id)}`,\n stateCommandResultSchema,\n {\n method: \"PATCH\",\n body: JSON.stringify({\n schemaVersion: 1,\n commandId: crypto.randomUUID(),\n expectedVersion: workItem.version,\n patch,\n }),\n },\n );\n\n if (result.type !== \"WORK_ITEM_UPDATED\") {\n throw new Error(\"The local daemon returned an unexpected update result\");\n }\n return result.workItem;\n};\n\nexport const startMockPipeline = async (workItem: WorkItem) =>\n requestLocalApi(\n `/api/v1/work-items/${encodeURIComponent(workItem.id)}/pipeline/start`,\n workflowSnapshotSchema,\n {\n method: \"POST\",\n body: JSON.stringify({\n schemaVersion: 1,\n commandId: crypto.randomUUID(),\n expectedVersion: workItem.version,\n }),\n },\n );\n\nexport const answerHumanRequest = async (request: HumanRequest, answer: HumanRequestAnswer) =>\n requestLocalApi(`/api/v1/human-requests/${encodeURIComponent(request.id)}/answer`, workflowSnapshotSchema, {\n method: \"POST\",\n body: JSON.stringify({\n schemaVersion: 1,\n commandId: crypto.randomUUID(),\n expectedVersion: request.version,\n answer,\n }),\n });\n\nexport type PipelineControlAction = \"pause\" | \"resume\" | \"cancel\";\n\nexport const controlPipeline = async (workItemId: string, run: PipelineRun, action: PipelineControlAction) =>\n requestLocalApi(\n `/api/v1/work-items/${encodeURIComponent(workItemId)}/pipeline/${action}`,\n workflowSnapshotSchema,\n {\n method: \"POST\",\n body: JSON.stringify({\n schemaVersion: 1,\n commandId: crypto.randomUUID(),\n expectedVersion: run.version,\n }),\n },\n );\n\nexport const approveBudgetOverride = async (\n workItemId: string,\n run: PipelineRun,\n maxEstimatedTokens: number,\n) =>\n requestLocalApi(\n `/api/v1/work-items/${encodeURIComponent(workItemId)}/pipeline/budget-override`,\n workflowSnapshotSchema,\n {\n method: \"POST\",\n body: JSON.stringify({\n schemaVersion: 1,\n commandId: crypto.randomUUID(),\n expectedVersion: run.version,\n maxEstimatedTokens,\n }),\n },\n );\n\nexport const resolveAcceptance = async (\n workItemId: string,\n run: PipelineRun,\n acceptancePackage: AcceptancePackage,\n action: AcceptanceAction,\n reason: string | null = null,\n) =>\n requestLocalApi(\n `/api/v1/work-items/${encodeURIComponent(workItemId)}/acceptance/${encodeURIComponent(acceptancePackage.id)}/resolve`,\n workflowSnapshotSchema,\n {\n method: \"POST\",\n body: JSON.stringify({\n schemaVersion: 1,\n commandId: crypto.randomUUID(),\n expectedVersion: acceptancePackage.version,\n expectedRunVersion: run.version,\n action,\n reason,\n }),\n },\n );\n","import { Button, Icon } from \"@loomrail/ui\";\n\nimport { isLocalApiError } from \"../api\";\nimport { useI18n } from \"../i18n\";\n\ntype LocalConnectionRecoveryProps = {\n error: unknown;\n onRetry?: () => void;\n retrying?: boolean;\n};\n\nconst errorMessage = (error: unknown): string =>\n error instanceof Error ? error.message : \"The local operation could not be completed\";\n\nexport const LocalConnectionRecovery = ({\n error,\n onRetry,\n retrying = false,\n}: LocalConnectionRecoveryProps): React.JSX.Element => {\n const { t } = useI18n();\n const recovery = isLocalApiError(error) ? error.recovery : \"none\";\n\n if (recovery === \"none\") {\n return (\n <p className=\"local-operation-error\" role=\"alert\">\n {errorMessage(error)}\n </p>\n );\n }\n\n const reopen = recovery === \"reopen\";\n return (\n <section className=\"local-connection-recovery\" role=\"alert\">\n <span aria-hidden=\"true\" className=\"local-connection-recovery__icon\">\n <Icon name={reopen ? \"terminal\" : \"warning\"} size={16} />\n </span>\n <div>\n <strong>{t(reopen ? \"connection.recovery.reopenTitle\" : \"connection.recovery.retryTitle\")}</strong>\n <p>{t(reopen ? \"connection.recovery.reopenDescription\" : \"connection.recovery.retryDescription\")}</p>\n {reopen ? (\n <div className=\"local-connection-recovery__command\">\n <span>{t(\"connection.recovery.command\")}</span>\n <code>pnpm dev</code>\n </div>\n ) : null}\n </div>\n {!reopen && onRetry ? (\n <Button loading={retrying} onClick={onRetry} size=\"sm\" variant=\"secondary\">\n {t(\"connection.recovery.retryAction\")}\n </Button>\n ) : null}\n </section>\n );\n};\n","export const densityPreferences = [\"comfortable\", \"compact\"] as const;\nexport type DensityPreference = (typeof densityPreferences)[number];\n\nconst DENSITY_STORAGE_KEY = \"loomrail-density\";\n\nexport const isDensityPreference = (value: string | null): value is DensityPreference =>\n value !== null && densityPreferences.some((density) => density === value);\n\nexport const readDensityPreference = (): DensityPreference => {\n const stored = window.localStorage.getItem(DENSITY_STORAGE_KEY);\n return isDensityPreference(stored) ? stored : \"comfortable\";\n};\n\n/**\n * Applies the row density to the document.\n *\n * Comfortable is the default, so it clears the attribute rather than writing one: the stylesheet\n * carries the comfortable sizes as its base and only overrides them under `data-density=\"compact\"`.\n */\nexport const applyDensityPreference = (preference: DensityPreference): void => {\n if (preference === \"comfortable\") {\n document.documentElement.removeAttribute(\"data-density\");\n window.localStorage.removeItem(DENSITY_STORAGE_KEY);\n return;\n }\n\n document.documentElement.dataset[\"density\"] = preference;\n window.localStorage.setItem(DENSITY_STORAGE_KEY, preference);\n};\n","export const themePreferences = [\"light\", \"dark\", \"system\"] as const;\nexport type ThemePreference = (typeof themePreferences)[number];\n\nconst THEME_STORAGE_KEY = \"loomrail-theme\";\n\nexport const isThemePreference = (value: string | null): value is ThemePreference =>\n value !== null && themePreferences.some((theme) => theme === value);\n\nexport const readThemePreference = (): ThemePreference => {\n const stored = window.localStorage.getItem(THEME_STORAGE_KEY);\n return isThemePreference(stored) ? stored : \"system\";\n};\n\nexport const applyThemePreference = (preference: ThemePreference): void => {\n if (preference === \"system\") {\n document.documentElement.removeAttribute(\"data-theme\");\n window.localStorage.removeItem(THEME_STORAGE_KEY);\n return;\n }\n\n document.documentElement.dataset[\"theme\"] = preference;\n window.localStorage.setItem(THEME_STORAGE_KEY, preference);\n};\n","import {\n daemonStatusResponseSchema,\n sessionExchangeResponseSchema,\n type DaemonStatusResponse,\n} from \"@loomrail/contracts\";\nimport { queryOptions } from \"@tanstack/react-query\";\n\nimport {\n createDaemonUnavailableError,\n isLocalApiError,\n readLocalApiError,\n requestLocalApi,\n storeCsrfToken,\n} from \"./api\";\n\nexport type ConnectionResult =\n { status: \"connected\"; daemon: DaemonStatusResponse } | { status: \"error\"; error: Error; message: string };\n\nlet pendingBootstrapToken: string | null = null;\n\nconst exchangeBootstrapToken = async (bootstrapToken: string): Promise<void> => {\n let response: Response;\n try {\n response = await fetch(\"/api/session/exchange\", {\n method: \"POST\",\n credentials: \"same-origin\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ bootstrapToken }),\n });\n } catch {\n throw createDaemonUnavailableError();\n }\n\n if (!response.ok) {\n throw await readLocalApiError(response);\n }\n\n const session = sessionExchangeResponseSchema.parse(await response.json());\n storeCsrfToken(session.csrfToken);\n};\n\nconst fetchDaemonStatus = async (): Promise<DaemonStatusResponse> => {\n return requestLocalApi(\"/api/v1/status\", daemonStatusResponseSchema);\n};\n\nexport const connectToLocalDaemon = async (): Promise<ConnectionResult> => {\n try {\n const fragment = new URLSearchParams(window.location.hash.slice(1));\n const bootstrapToken = fragment.get(\"bootstrap\");\n if (bootstrapToken) {\n pendingBootstrapToken = bootstrapToken;\n window.history.replaceState(null, \"\", `${window.location.pathname}${window.location.search}`);\n }\n if (pendingBootstrapToken) {\n await exchangeBootstrapToken(pendingBootstrapToken);\n pendingBootstrapToken = null;\n }\n\n return { status: \"connected\", daemon: await fetchDaemonStatus() };\n } catch (error: unknown) {\n if (isLocalApiError(error) && error.recovery === \"reopen\") pendingBootstrapToken = null;\n const connectionError = error instanceof Error ? error : new Error(\"Could not connect to Loomrail\");\n return {\n status: \"error\",\n error: connectionError,\n message: connectionError.message,\n };\n }\n};\n\nexport const localConnectionQuery = queryOptions({\n queryKey: [\"local-daemon\", \"connection\"],\n queryFn: connectToLocalDaemon,\n staleTime: Number.POSITIVE_INFINITY,\n});\n","import type { ChangeStatus } from \"@loomrail/contracts\";\nimport type { BadgeTone } from \"@loomrail/ui\";\n\nimport { isLocalApiError } from \"./api\";\nimport type { TranslationKey } from \"./i18n\";\n\n/**\n * The largest measured median of one summary read in Task 7, rounded to a stable millisecond\n * boundary: 1,594 ms over a real 20,000-file repository. The original 750 ms in the plan was an\n * unmeasured working value; keeping it would schedule work faster than that repository can finish\n * it. This window applies only to change reads -- the rest of the event-driven workbench keeps the\n * channel's 50 ms coalescing window.\n */\nexport const SUMMARY_REFRESH_DEBOUNCE_MS = 1_600;\n\nexport type SummaryRefresher = (() => void) & { dispose: () => void };\n\n/**\n * Schedules one read at the end of a fixed window that starts with the first event in a burst.\n *\n * Later events do not move the deadline: a stage that publishes continuously must still refresh\n * while it is running. `dispose` makes closing the card cancel a read nobody can see.\n */\nexport const makeSummaryRefresher = (\n read: () => void | Promise<void>,\n windowMs: number = SUMMARY_REFRESH_DEBOUNCE_MS,\n): SummaryRefresher => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const refresh = (() => {\n timer ??= setTimeout(() => {\n timer = undefined;\n // A query client records its own read failure. Catch the returned promise here so a failed\n // background refresh does not also become an unhandled rejection in the browser.\n void Promise.resolve()\n .then(read)\n .catch(() => undefined);\n }, windowMs);\n }) as SummaryRefresher;\n refresh.dispose = () => {\n if (timer !== undefined) clearTimeout(timer);\n timer = undefined;\n };\n return refresh;\n};\n\n/**\n * How a changed file's status is named and toned.\n *\n * A `Record<ChangeStatus, …>` rather than a switch with a default, so adding a fifth status to the\n * contract fails `pnpm typecheck` here instead of silently rendering as whatever the default was.\n * The tone never carries the meaning on its own -- every row prints the label beside the colour\n * (AGENTS.md, \"Status/priority/severity must not rely on color alone\").\n */\nexport const changeStatusLabelKeys: Record<ChangeStatus, TranslationKey> = {\n ADDED: \"changes.status.ADDED\",\n MODIFIED: \"changes.status.MODIFIED\",\n DELETED: \"changes.status.DELETED\",\n RENAMED: \"changes.status.RENAMED\",\n};\n\nexport const changeStatusTones: Record<ChangeStatus, BadgeTone> = {\n ADDED: \"success\",\n MODIFIED: \"info\",\n DELETED: \"danger\",\n RENAMED: \"accent\",\n};\n\n/**\n * The sentence the card shows instead of a file list, for each refusal the two change handles can\n * answer with.\n *\n * Every code here is raised by `apps/daemon/src/server.ts` and nowhere else: the three a client's\n * own path can earn (400), the two a workspace can earn plus a baseline that is not recorded (409),\n * and the two this machine has to answer for (500). They are mapped to localized sentences rather\n * than shown as the daemon's own message, because that message is English prose built for a log and\n * this text is read by an owner who may have the cockpit in Russian.\n *\n * Each sentence says what happened and stops there. None of them offers an action, because Loomrail\n * has none to offer for any of these: nothing returns a deleted worktree, re-cuts a workspace, or\n * repairs a git installation from inside the cockpit, and a control that could only ever fail is\n * worse than the plain fact.\n */\nconst changesRefusalKeys: Readonly<Record<string, TranslationKey>> = {\n WORKSPACE_WORKTREE_MISSING: \"changes.error.WORKSPACE_WORKTREE_MISSING\",\n WORKSPACE_WORKTREE_UNREADABLE: \"changes.error.WORKSPACE_WORKTREE_UNREADABLE\",\n WORKSPACE_HAS_NO_BASELINE: \"changes.error.WORKSPACE_HAS_NO_BASELINE\",\n CHANGES_UNREADABLE: \"changes.error.CHANGES_UNREADABLE\",\n GIT_UNAVAILABLE: \"changes.error.GIT_UNAVAILABLE\",\n PATH_OUTSIDE_WORKSPACE: \"changes.error.PATH_OUTSIDE_WORKSPACE\",\n PATH_NOT_A_FILE: \"changes.error.PATH_NOT_A_FILE\",\n PATH_UNRESOLVABLE: \"changes.error.PATH_UNRESOLVABLE\",\n};\n\n/**\n * Which of those sentences a failed change read earns.\n *\n * Anything that is not a named refusal -- a daemon that stopped answering, a body that did not\n * parse, a code this build has never heard of -- falls back to one that claims nothing about the\n * cause. It must never fall back to silence or to an empty file list: an empty list is a claim that\n * the worktree is unchanged, and a read that did not happen is not entitled to make it (spec D7).\n */\nexport const changesRefusalKey = (error: unknown): TranslationKey =>\n (isLocalApiError(error) ? changesRefusalKeys[error.code] : undefined) ?? \"changes.error.other\";\n","import { eventSignalSchema, type EventSignal } from \"@loomrail/contracts\";\n\nexport const COALESCE_WINDOW_MS = 50;\n\ntype QueryScope = readonly string[];\n\n/**\n * Which cached scopes a signal makes stale.\n *\n * Query keys are prefix-shaped (workspace.tsx:39-48), so one entry per scope covers everything\n * nested under it. The stage-attempt scope is invalidated whole because events carry no attempt\n * id -- the client holds one or two attempts, so the cost is one refetch.\n *\n * A switch with a `never` check rather than a ternary on `=== \"WORK_ITEM\"`, because a third\n * `aggregateType` would otherwise degrade in silence: `eventSignalSchema` would accept the frame,\n * and everything that is not WORK_ITEM would quietly take the PROJECT branch and invalidate the\n * wrong keys. The daemon side of the same widening is caught by the compiler already -- publishing\n * a `DomainEvent`'s `aggregateType` (broadcasting-state.ts) is an assignment to `EventSignal`, so\n * an event type the frame schema does not list fails to compile there. This closes the other door:\n * widen the schema to match and this function stops compiling until its mapping is decided.\n */\nexport const scopesForSignal = (signal: EventSignal): readonly QueryScope[] => {\n switch (signal.aggregateType) {\n case \"WORK_ITEM\":\n return [[\"projects\", signal.projectId], [\"work-items\", signal.aggregateId], [\"stage-attempts\"]];\n case \"PROJECT\":\n return [[\"projects\", signal.projectId], [\"projects\"]];\n default: {\n const unhandled: never = signal.aggregateType;\n throw new Error(`Unhandled event signal aggregate type: ${String(unhandled)}`);\n }\n }\n};\n\n/**\n * Collects signals arriving inside one window and flushes their union once.\n *\n * A running stage publishes in bursts -- session started, checkpoint, wind-down asked, session\n * ended -- and invalidating per signal would mean a refetch storm and a jumpy board. The deadline\n * is set by the first signal of a burst and never postponed by later ones, so a steadily\n * publishing stage still refreshes on schedule instead of starving.\n */\nexport const createSignalCoalescer = (\n flush: (scopes: readonly QueryScope[]) => void,\n windowMs: number = COALESCE_WINDOW_MS,\n): { push: (signal: EventSignal) => void; dispose: () => void } => {\n const pending = new Map<string, QueryScope>();\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const run = (): void => {\n timer = undefined;\n const scopes = [...pending.values()];\n pending.clear();\n if (scopes.length > 0) flush(scopes);\n };\n\n return {\n push: (signal) => {\n for (const scope of scopesForSignal(signal)) pending.set(scope.join(\"/\"), scope);\n timer ??= setTimeout(run, windowMs);\n },\n dispose: () => {\n if (timer !== undefined) clearTimeout(timer);\n timer = undefined;\n pending.clear();\n },\n };\n};\n\nexport type EventChannelStatus = \"connecting\" | \"live\" | \"closed\";\n\nconst EVENT_SOURCE_CLOSED = 2;\n\n// The connection query's key, named here rather than imported from session.ts so this module stays\n// free of app wiring. That duplication is only safe because eventStream.test.ts asserts this\n// mapping against `localConnectionQuery.queryKey` itself -- the test file is free to import\n// session.ts, so the drift this literal would otherwise invite is caught there.\nconst LOCAL_CONNECTION_SCOPE: QueryScope = [\"local-daemon\", \"connection\"];\n\n/**\n * Which cached scopes a change in channel status makes stale.\n *\n * A permanently closed channel means a non-200 response, which on this route means the session is\n * gone -- the condition the connection query already detects and the recovery panel already\n * explains. A reconnecting channel means nothing yet: the browser is retrying on its own and the\n * board's data is still good.\n */\nexport const scopesForChannelStatus = (status: EventChannelStatus): readonly QueryScope[] =>\n status === \"closed\" ? [LOCAL_CONNECTION_SCOPE] : [];\n\n/**\n * The subset of `EventSource` this module relies on.\n *\n * `EventSource` has no jsdom implementation, so tests drive this shape with a plain object double\n * instead of a real browser API -- keeping the milestone's no-new-dependencies rule intact.\n */\nexport type EventSourceLike = {\n readyState: number;\n onopen: ((event: unknown) => void) | null;\n onmessage: ((event: { data: string }) => void) | null;\n onerror: ((event: unknown) => void) | null;\n close: () => void;\n};\n\n/**\n * Wires an `EventSourceLike` to the coalescer, and turns a change of connection status into the\n * invalidation it implies.\n *\n * Three things here are load bearing (spec D3/D4). `invalidateAll()` on every `open` -- including\n * every reconnect, not only the first -- is what makes a dropped signal harmless: the channel\n * carries no sequence number and never replays, so catching up after any gap is done entirely by\n * refetching. Parsing each frame inside a `try` means a malformed or non-signal frame is dropped\n * rather than thrown, which would otherwise leave the channel silently mute after one bad frame.\n * And `announce` below is the entire mechanism by which a permanently closed channel becomes\n * visible to the app: the status is consumed here, by `scopesForChannelStatus`, and is not reported\n * outward. It used to be handed to the caller as well, threaded through the workspace context and\n * rendered by nothing -- a wire with nothing on the far end, which no test could tell from a broken\n * one. Anything that wants to *show* channel status should start from this function, not from a\n * status value some caller is already receiving.\n */\nexport const connectEventStream = (options: {\n source: EventSourceLike;\n invalidateAll: () => void;\n invalidateScopes: (scopes: readonly (readonly string[])[]) => void;\n windowMs?: number;\n}): (() => void) => {\n const coalescer = createSignalCoalescer(options.invalidateScopes, options.windowMs);\n\n const announce = (status: EventChannelStatus): void => {\n const scopes = scopesForChannelStatus(status);\n if (scopes.length > 0) options.invalidateScopes(scopes);\n };\n\n options.source.onopen = () => {\n announce(\"live\");\n options.invalidateAll();\n };\n\n options.source.onmessage = (message) => {\n let parsed: unknown;\n try {\n parsed = JSON.parse(message.data);\n } catch {\n return;\n }\n const signal = eventSignalSchema.safeParse(parsed);\n if (!signal.success) return;\n coalescer.push(signal.data);\n };\n\n options.source.onerror = () => {\n // Routed through the same invalidateScopes callback the coalescer uses, rather than a branch in\n // the hook: this makes the closed -> \"session is gone\" decision reachable through the\n // injected-double tests in this file, not only by hand-tracing a useEffect.\n announce(options.source.readyState === EVENT_SOURCE_CLOSED ? \"closed\" : \"connecting\");\n };\n\n return () => {\n coalescer.dispose();\n options.source.close();\n };\n};\n","import { useQueryClient, type QueryClient } from \"@tanstack/react-query\";\nimport { useEffect } from \"react\";\n\nimport { makeSummaryRefresher, SUMMARY_REFRESH_DEBOUNCE_MS, type SummaryRefresher } from \"./changesView\";\nimport { connectEventStream, type EventSourceLike } from \"./eventStream\";\n\ntype QueryScope = readonly string[];\n\nconst queryStartsWith = (queryKey: readonly unknown[], scope: QueryScope): boolean =>\n scope.every((part, index) => queryKey[index] === part);\n\nconst isChangesQuery = (queryKey: readonly unknown[], workItemId: string): boolean =>\n queryKey[0] === \"work-items\" && queryKey[1] === workItemId && queryKey[2] === \"changes\";\n\n/** The predicate used for the immediate half of a WORK_ITEM invalidation, exported for mutation tests. */\nexport const shouldInvalidateImmediately = (queryKey: readonly unknown[], scope: QueryScope): boolean => {\n if (!queryStartsWith(queryKey, scope)) return false;\n const workItemId = scope.length === 2 && scope[0] === \"work-items\" ? scope[1] : undefined;\n return workItemId === undefined || !isChangesQuery(queryKey, workItemId);\n};\n\n/**\n * Turns channel scopes into query invalidations while giving expensive change reads their own\n * measured cadence.\n *\n * A WORK_ITEM signal still invalidates workflow, workspace and every other card query immediately.\n * Summary and file-diff queries are excluded from that pass and invalidated together after the\n * measured window. React Query refetches active queries only: the summary is active while its card\n * is open, and a body is active only for the one expanded file. A closed card therefore performs no\n * read at all.\n */\nexport const createEventQueryInvalidator = (\n queryClient: QueryClient,\n summaryWindowMs: number = SUMMARY_REFRESH_DEBOUNCE_MS,\n): {\n invalidateAll: () => void;\n invalidateScopes: (scopes: readonly QueryScope[]) => void;\n dispose: () => void;\n} => {\n const summaryRefreshers = new Map<string, SummaryRefresher>();\n\n const dispose = (): void => {\n for (const refresher of summaryRefreshers.values()) refresher.dispose();\n summaryRefreshers.clear();\n };\n\n const scheduleChanges = (workItemId: string): void => {\n let refresher = summaryRefreshers.get(workItemId);\n if (!refresher) {\n refresher = makeSummaryRefresher(async () => {\n summaryRefreshers.delete(workItemId);\n await queryClient.invalidateQueries({\n queryKey: [\"work-items\", workItemId, \"changes\"],\n refetchType: \"active\",\n });\n }, summaryWindowMs);\n summaryRefreshers.set(workItemId, refresher);\n }\n refresher();\n };\n\n return {\n invalidateAll: () => {\n // Reconnect is a full catch-up read (ADR-0002), so an older delayed change read would only\n // duplicate it. Cancel the delayed work before invalidating the complete cache.\n dispose();\n void queryClient.invalidateQueries();\n },\n invalidateScopes: (scopes) => {\n for (const scope of scopes) {\n const workItemId = scope.length === 2 && scope[0] === \"work-items\" ? scope[1] : undefined;\n if (workItemId !== undefined) {\n void queryClient.invalidateQueries({\n predicate: (query) => shouldInvalidateImmediately(query.queryKey, scope),\n });\n scheduleChanges(workItemId);\n continue;\n }\n void queryClient.invalidateQueries({ queryKey: scope });\n }\n },\n dispose,\n };\n};\n\n/**\n * Follows the daemon's SSE channel while `enabled`.\n *\n * All decision logic lives in `connectEventStream` and `scopesForChannelStatus`, both tested\n * against an injected source double -- see eventStream.test.ts. This hook is deliberately thin: it\n * owns only the real `EventSource`. In particular, what a closed channel means (the session is gone;\n * invalidate the same connection query the app already uses to detect and explain an unreachable\n * daemon) is decided by `scopesForChannelStatus` and reaches the query client through the\n * `invalidateScopes` callback below -- not through a branch here, so that decision stays covered by\n * connectEventStream's tests instead of living only in an untestable effect.\n *\n * Returns nothing on purpose. It used to return a status that the workspace context carried and no\n * component ever read; a value with no reader cannot be told from a broken one by any test, so it\n * is gone rather than left as a wire waiting for an end. Reinstating it is a change to make\n * alongside the component that renders it.\n */\nexport const useEventStream = (enabled: boolean): void => {\n const queryClient = useQueryClient();\n\n useEffect(() => {\n if (!enabled) return;\n // `EventSource`'s handler properties are typed against the DOM `Event`, narrower than the\n // `unknown` `connectEventStream` accepts so it can be driven by a plain-object double in\n // tests (EventSource has no jsdom implementation). The real browser type is a structural\n // superset of EventSourceLike, so this bridges an interop mismatch, not an unsafe widening.\n const source = new EventSource(\"/api/v1/stream\") as unknown as EventSourceLike;\n const invalidator = createEventQueryInvalidator(queryClient);\n const disconnect = connectEventStream({\n source,\n invalidateAll: invalidator.invalidateAll,\n invalidateScopes: invalidator.invalidateScopes,\n });\n return () => {\n disconnect();\n invalidator.dispose();\n };\n }, [enabled, queryClient]);\n};\n","/* eslint-disable react-refresh/only-export-components -- workspace hooks intentionally share their provider module */\nimport { createContext, useContext, useMemo, useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { useInfiniteQuery, useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport type {\n AcceptanceAction,\n AcceptancePackage,\n HumanRequest,\n FixtureProjectId,\n HumanRequestAnswer,\n ListedProject,\n PipelineRun,\n WorkItem,\n WorkItemState,\n} from \"@loomrail/contracts\";\n\nimport {\n approveBudgetOverride,\n answerHumanRequest,\n controlPipeline,\n createWorkItem,\n getProviderCapabilities,\n getWorkItemChanges,\n getWorkItemFileDiff,\n getWorkItemWorkflow,\n getWorkItemWorkspace,\n listOpenHumanRequests,\n listProjects,\n listProjectWorkItems,\n listProviderSessions,\n listWorkItemEvents,\n moveWorkItem,\n registerFixtureProject,\n registerRepositoryProject,\n resolveAcceptance,\n startMockPipeline,\n updateWorkItem,\n type CreateWorkItemInput,\n type PipelineControlAction,\n type UpdateWorkItemPatch,\n} from \"./api\";\nimport { localConnectionQuery, type ConnectionResult } from \"./session\";\nimport { useEventStream } from \"./useEventStream\";\n\nconst projectsKey = [\"projects\"] as const;\nconst projectWorkItemsKey = (projectId: string) => [\"projects\", projectId, \"work-items\"] as const;\nconst workItemEventsKey = (projectId: string, workItemId: string) =>\n [\"projects\", projectId, \"work-items\", workItemId, \"events\"] as const;\nconst workItemWorkflowKey = (workItemId: string) => [\"work-items\", workItemId, \"workflow\"] as const;\n// Nested under the same `[\"work-items\", <id>]` prefix the event channel invalidates for a WORK_ITEM\n// signal (eventStream.ts, scopesForSignal), so a stage that cuts a workspace refreshes the card\n// without a reload and without a second entry in that mapping.\nconst workItemWorkspaceKey = (workItemId: string) => [\"work-items\", workItemId, \"workspace\"] as const;\n// Both change keys sit under that same `[\"work-items\", <id>]` prefix. The event bridge deliberately\n// excludes this subtree from its immediate 50 ms invalidation and refreshes it on the separately\n// measured SUMMARY_REFRESH_DEBOUNCE_MS cadence (useEventStream.ts): an open card rereads the\n// summary, and only the one body query mounted for an expanded file. An inactive query is marked\n// stale but not fetched, so a closed card does no work.\nconst workItemChangesKey = (workItemId: string) => [\"work-items\", workItemId, \"changes\"] as const;\nconst workItemFileDiffKey = (workItemId: string, path: string) =>\n [\"work-items\", workItemId, \"changes\", \"diff\", path] as const;\nconst projectHumanRequestsKey = (projectId: string) =>\n [\"projects\", projectId, \"human-requests\", \"OPEN\"] as const;\nconst stageAttemptSessionsKey = (stageAttemptId: string) =>\n [\"stage-attempts\", stageAttemptId, \"sessions\"] as const;\nconst providerCapabilitiesKey = [\"provider\", \"capabilities\"] as const;\n\ntype WorkspaceContextValue = {\n connection: ConnectionResult | undefined;\n connectionPending: boolean;\n error: Error | null;\n projects: readonly ListedProject[];\n projectsPending: boolean;\n selectedProject: ListedProject | null;\n retryConnection: () => void;\n selectProject: (projectId: string) => void;\n};\n\nconst WorkspaceContext = createContext<WorkspaceContextValue | null>(null);\n\nexport const WorkspaceProvider = ({ children }: { children: ReactNode }): React.JSX.Element => {\n const connectionQuery = useQuery(localConnectionQuery);\n const connected = connectionQuery.data?.status === \"connected\";\n const projectsQuery = useQuery({\n queryKey: projectsKey,\n queryFn: listProjects,\n enabled: connected,\n });\n const [requestedProjectId, setRequestedProjectId] = useState<string | null>(null);\n const projects = projectsQuery.data?.projects ?? [];\n const selectedProject =\n projects.find((project) => project.id === requestedProjectId) ?? projects.at(0) ?? null;\n // Nothing is returned: the channel's only effect on this component tree is the invalidation it\n // performs through the query client (see useEventStream), not a status anything renders.\n useEventStream(connected);\n\n const value = useMemo<WorkspaceContextValue>(\n () => ({\n connection: connectionQuery.data,\n connectionPending: connectionQuery.isPending,\n error:\n connectionQuery.data?.status === \"error\"\n ? connectionQuery.data.error\n : connectionQuery.error instanceof Error\n ? connectionQuery.error\n : projectsQuery.error instanceof Error\n ? projectsQuery.error\n : null,\n projects,\n projectsPending: connected && projectsQuery.isPending,\n retryConnection: () => {\n void connectionQuery.refetch().then((result) => {\n if (result.data?.status === \"connected\") void projectsQuery.refetch();\n });\n },\n selectedProject,\n selectProject: setRequestedProjectId,\n }),\n [\n connected,\n connectionQuery.data,\n connectionQuery.error,\n connectionQuery.isPending,\n connectionQuery.refetch,\n projects,\n projectsQuery.error,\n projectsQuery.isPending,\n projectsQuery.refetch,\n selectedProject,\n ],\n );\n\n return <WorkspaceContext.Provider value={value}>{children}</WorkspaceContext.Provider>;\n};\n\nexport const useWorkspace = (): WorkspaceContextValue => {\n const value = useContext(WorkspaceContext);\n if (!value) throw new Error(\"useWorkspace must be rendered inside WorkspaceProvider\");\n return value;\n};\n\nexport const useProjectWorkItems = (projectId: string | undefined) =>\n useQuery({\n queryKey: projectId ? projectWorkItemsKey(projectId) : [\"projects\", \"none\", \"work-items\"],\n queryFn: () => {\n if (!projectId) throw new Error(\"A project is required to list work items\");\n return listProjectWorkItems(projectId);\n },\n enabled: projectId !== undefined,\n });\n\n/**\n * Activity is append-only and read newest first, so pages are cursors into the past. Refetching\n * re-derives every cursor from the page before it, which keeps Events that arrive while older\n * pages are open from falling into the gap between two page boundaries.\n */\nexport const useWorkItemEvents = (projectId: string | undefined, workItemId: string | undefined) =>\n useInfiniteQuery({\n queryKey:\n projectId && workItemId\n ? workItemEventsKey(projectId, workItemId)\n : [\"projects\", \"none\", \"work-items\", \"none\", \"events\"],\n queryFn: ({ pageParam }) => {\n if (!projectId || !workItemId) throw new Error(\"A project and work item are required to list activity\");\n return listWorkItemEvents(projectId, workItemId, pageParam);\n },\n initialPageParam: undefined as number | undefined,\n getNextPageParam: (lastPage) => (lastPage.hasMore ? lastPage.nextSequence : undefined),\n enabled: projectId !== undefined && workItemId !== undefined,\n });\n\nexport const useWorkItemWorkflow = (workItemId: string | undefined) =>\n useQuery({\n queryKey: workItemId ? workItemWorkflowKey(workItemId) : [\"work-items\", \"none\", \"workflow\"],\n queryFn: () => {\n if (!workItemId) throw new Error(\"A work item is required to load its workflow\");\n return getWorkItemWorkflow(workItemId);\n },\n enabled: workItemId !== undefined,\n });\n\n/**\n * Where this work item's agent writes, or `null` when it has never needed a repository.\n *\n * Separate from `useWorkItemWorkflow` because a workspace outlives the run that cut it: the\n * workflow snapshot is empty once no PipelineRun is current, and folding the workspace into it\n * would make the worktree path disappear from the card exactly when the owner goes looking for it.\n */\nexport const useWorkItemWorkspace = (workItemId: string | undefined) =>\n useQuery({\n queryKey: workItemId ? workItemWorkspaceKey(workItemId) : [\"work-items\", \"none\", \"workspace\"],\n queryFn: () => {\n if (!workItemId) throw new Error(\"A work item is required to load its workspace\");\n return getWorkItemWorkspace(workItemId);\n },\n enabled: workItemId !== undefined,\n });\n\n/**\n * What this work item changed in its worktree, or `null` when it has no workspace to change.\n *\n * Separate from `useWorkItemWorkspace` even though both answer for the same worktree: the workspace\n * row is state the daemon already holds, while this is a reading it performs on demand -- four git\n * processes over a temporary index -- and folding the expensive one into the cheap one would make\n * every card that only wants a worktree path pay for a diff.\n */\nexport const useWorkItemChanges = (workItemId: string) =>\n useQuery({\n queryKey: workItemChangesKey(workItemId),\n queryFn: () => getWorkItemChanges(workItemId),\n });\n\n/**\n * One file's unified diff, kept a query of its own so it is fetched only while that file is\n * expanded (spec D5).\n *\n * Both arguments are required rather than optional-with-`enabled`, unlike the hooks above: the only\n * caller mounts this at all when the owner has expanded a specific file, so there is no \"no file\n * chosen yet\" state for it to represent -- and an `enabled: false` variant would be a way to fetch\n * bodies for files nobody asked for.\n */\nexport const useWorkItemFileDiff = (workItemId: string, path: string) =>\n useQuery({\n queryKey: workItemFileDiffKey(workItemId, path),\n queryFn: () => getWorkItemFileDiff(workItemId, path),\n });\n\n/**\n * Spec §D5's nesting, read back for the Task Cockpit: the sessions inside a stage attempt, the\n * checkpoints published under it, and the highest window occupancy each session was measured at.\n */\nexport const useStageAttemptSessions = (stageAttemptId: string | undefined) =>\n useQuery({\n queryKey: stageAttemptId\n ? stageAttemptSessionsKey(stageAttemptId)\n : [\"stage-attempts\", \"none\", \"sessions\"],\n queryFn: () => {\n if (!stageAttemptId) throw new Error(\"A stage attempt is required to list its sessions\");\n return listProviderSessions(stageAttemptId);\n },\n enabled: stageAttemptId !== undefined,\n });\n\n/** The provider a session would run on right now (spec §7): whether it can wind down on request. */\nexport const useProviderCapabilities = () =>\n useQuery({ queryKey: providerCapabilitiesKey, queryFn: getProviderCapabilities });\n\nexport const useProjectHumanRequests = (projectId: string | undefined) =>\n useQuery({\n queryKey: projectId ? projectHumanRequestsKey(projectId) : [\"projects\", \"none\", \"human-requests\", \"OPEN\"],\n queryFn: () => {\n if (!projectId) throw new Error(\"A project is required to list HumanRequests\");\n return listOpenHumanRequests(projectId);\n },\n enabled: projectId !== undefined,\n });\n\nexport const useInitializeFixtureWorkspace = () => {\n const queryClient = useQueryClient();\n const { projects } = useWorkspace();\n return useMutation({\n mutationFn: async () => {\n // A demo fixture is registered when it is absent, and again when the Project that records it\n // no longer points at a repository. The second half is the one that was missing: this used to\n // skip any `fixtureId` already present, so on a database that predates E1 -- where both demo\n // Projects record a directory inside Loomrail's own checkout, carried across verbatim by\n // migration 0012 -- pressing this did nothing at all, and the repair route it is the only\n // caller of was unreachable from the product.\n const usable = new Set(\n projects\n .filter(({ repositoryStatus }) => repositoryStatus === \"READY\")\n .map(({ fixtureId }) => fixtureId),\n );\n if (!usable.has(\"web-app-a\")) await registerFixtureProject(\"web-app-a\");\n if (!usable.has(\"api-service-b\")) await registerFixtureProject(\"api-service-b\");\n },\n onSuccess: async () => {\n await queryClient.invalidateQueries({ queryKey: projectsKey });\n },\n });\n};\n\n/**\n * Repairs one demo Project whose recorded path is no longer a repository (spec §4).\n *\n * The same route `useInitializeFixtureWorkspace` calls, aimed at a single fixture rather than at\n * both -- because this is reached from the Projects list, where the owner is looking at one\n * Project and its path. `POST /api/v1/projects/fixtures/register` materialises the fixture under\n * the daemon's data directory and moves the Project onto it (REPOINT_FIXTURE_PROJECT), so the\n * button does exactly what \"initialize the demo workspace\" does, for the Project the owner picked.\n *\n * There is deliberately no equivalent for a Project the owner registered by path: Loomrail does not\n * know where they moved their repository to, and inventing a path for them is not a repair. That\n * one is fixed by registering the new path, which the field below already does.\n */\nexport const useRepairFixtureProject = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (fixtureId: FixtureProjectId) => registerFixtureProject(fixtureId),\n onSuccess: async () => {\n await queryClient.invalidateQueries({ queryKey: projectsKey });\n },\n });\n};\n\n/** Spec §4: the owner registers a local Git repository by path, alongside the bundled demo. */\nexport const useRegisterRepositoryProject = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (repositoryPath: string) => registerRepositoryProject(repositoryPath),\n onSuccess: async () => {\n await queryClient.invalidateQueries({ queryKey: projectsKey });\n },\n });\n};\n\nexport const useCreateWorkItem = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (input: CreateWorkItemInput) => createWorkItem(input),\n onSuccess: async (workItem) => {\n await queryClient.invalidateQueries({ queryKey: projectWorkItemsKey(workItem.projectId) });\n },\n });\n};\n\nexport const useMoveWorkItem = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ targetState, workItem }: { targetState: WorkItemState; workItem: WorkItem }) =>\n moveWorkItem(workItem, targetState),\n onSuccess: async (workItem) => {\n await Promise.all([\n queryClient.invalidateQueries({ queryKey: projectWorkItemsKey(workItem.projectId) }),\n queryClient.invalidateQueries({ queryKey: workItemEventsKey(workItem.projectId, workItem.id) }),\n ]);\n },\n });\n};\n\nexport const useUpdateWorkItem = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ patch, workItem }: { patch: UpdateWorkItemPatch; workItem: WorkItem }) =>\n updateWorkItem(workItem, patch),\n onSuccess: async (workItem) => {\n await Promise.all([\n queryClient.invalidateQueries({ queryKey: projectWorkItemsKey(workItem.projectId) }),\n queryClient.invalidateQueries({ queryKey: workItemEventsKey(workItem.projectId, workItem.id) }),\n ]);\n },\n });\n};\n\nexport const useStartMockPipeline = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (workItem: WorkItem) => startMockPipeline(workItem),\n onSuccess: async (_, workItem) => {\n await Promise.all([\n queryClient.invalidateQueries({ queryKey: projectWorkItemsKey(workItem.projectId) }),\n queryClient.invalidateQueries({ queryKey: workItemWorkflowKey(workItem.id) }),\n queryClient.invalidateQueries({ queryKey: workItemEventsKey(workItem.projectId, workItem.id) }),\n queryClient.invalidateQueries({ queryKey: projectHumanRequestsKey(workItem.projectId) }),\n ]);\n },\n });\n};\n\nexport const useAnswerHumanRequest = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ answer, request }: { answer: HumanRequestAnswer; request: HumanRequest }) =>\n answerHumanRequest(request, answer),\n onSuccess: async (_, { request }) => {\n await Promise.all([\n queryClient.invalidateQueries({ queryKey: projectWorkItemsKey(request.projectId) }),\n queryClient.invalidateQueries({ queryKey: workItemWorkflowKey(request.workItemId) }),\n queryClient.invalidateQueries({\n queryKey: workItemEventsKey(request.projectId, request.workItemId),\n }),\n queryClient.invalidateQueries({ queryKey: projectHumanRequestsKey(request.projectId) }),\n queryClient.invalidateQueries({ queryKey: stageAttemptSessionsKey(request.stageAttemptId) }),\n ]);\n },\n });\n};\n\nexport const usePipelineControl = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({\n action,\n run,\n workItem,\n }: {\n action: PipelineControlAction;\n run: PipelineRun;\n workItem: WorkItem;\n }) => controlPipeline(workItem.id, run, action),\n onSuccess: async (_, { run, workItem }) => {\n await Promise.all([\n queryClient.invalidateQueries({ queryKey: projectWorkItemsKey(workItem.projectId) }),\n queryClient.invalidateQueries({ queryKey: workItemWorkflowKey(workItem.id) }),\n queryClient.invalidateQueries({ queryKey: workItemEventsKey(workItem.projectId, workItem.id) }),\n queryClient.invalidateQueries({ queryKey: projectHumanRequestsKey(workItem.projectId) }),\n queryClient.invalidateQueries({ queryKey: stageAttemptSessionsKey(run.currentStageAttemptId) }),\n ]);\n },\n });\n};\n\nexport const useApproveBudgetOverride = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({\n maxEstimatedTokens,\n run,\n workItem,\n }: {\n maxEstimatedTokens: number;\n run: PipelineRun;\n workItem: WorkItem;\n }) => approveBudgetOverride(workItem.id, run, maxEstimatedTokens),\n onSuccess: async (_, { run, workItem }) => {\n await Promise.all([\n queryClient.invalidateQueries({ queryKey: projectWorkItemsKey(workItem.projectId) }),\n queryClient.invalidateQueries({ queryKey: workItemWorkflowKey(workItem.id) }),\n queryClient.invalidateQueries({ queryKey: workItemEventsKey(workItem.projectId, workItem.id) }),\n queryClient.invalidateQueries({ queryKey: projectHumanRequestsKey(workItem.projectId) }),\n queryClient.invalidateQueries({ queryKey: stageAttemptSessionsKey(run.currentStageAttemptId) }),\n ]);\n },\n });\n};\n\nexport const useResolveAcceptance = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({\n acceptancePackage,\n action,\n run,\n workItem,\n }: {\n acceptancePackage: AcceptancePackage;\n action: AcceptanceAction;\n run: PipelineRun;\n workItem: WorkItem;\n }) => resolveAcceptance(workItem.id, run, acceptancePackage, action),\n onSuccess: async (_, { workItem }) => {\n await Promise.all([\n queryClient.invalidateQueries({ queryKey: projectWorkItemsKey(workItem.projectId) }),\n queryClient.invalidateQueries({ queryKey: workItemWorkflowKey(workItem.id) }),\n queryClient.invalidateQueries({ queryKey: workItemEventsKey(workItem.projectId, workItem.id) }),\n queryClient.invalidateQueries({ queryKey: projectHumanRequestsKey(workItem.projectId) }),\n ]);\n },\n });\n};\n","import { Link, Outlet, useLocation } from \"@tanstack/react-router\";\nimport { useEffect, useId, useRef, useState } from \"react\";\nimport type { SyntheticEvent } from \"react\";\nimport { prioritySchema, type ListedProject, type WorkItem } from \"@loomrail/contracts\";\nimport {\n ActionMenu,\n Button,\n cn,\n DialogSurface,\n Field,\n Icon,\n IconButton,\n SelectControl,\n Textarea,\n TextField,\n Tooltip,\n type IconName,\n} from \"@loomrail/ui\";\n\nimport { BrandMark } from \"../components/BrandMark\";\nimport { PanelResizer } from \"../components/PanelResizer\";\nimport { LocalConnectionRecovery } from \"../components/LocalConnectionRecovery\";\nimport { useI18n } from \"../i18n\";\nimport type { WorkbenchSearch } from \"../router\";\nimport { hasCustomPanelWidths, resetPanelWidths } from \"../layout\";\nimport { applyDensityPreference, readDensityPreference, type DensityPreference } from \"../density\";\nimport { applyThemePreference, readThemePreference, type ThemePreference } from \"../theme\";\nimport {\n useCreateWorkItem,\n useProjectHumanRequests,\n useRegisterRepositoryProject,\n useRepairFixtureProject,\n useWorkspace,\n} from \"../workspace\";\n\nconst NewTaskDialog = (): React.JSX.Element => {\n const { t } = useI18n();\n const [open, setOpen] = useState(false);\n const formRef = useRef<HTMLFormElement>(null);\n const { projects, selectedProject } = useWorkspace();\n const createMutation = useCreateWorkItem();\n const [requestedProjectId, setRequestedProjectId] = useState<string | null>(null);\n const [priority, setPriority] = useState<WorkItem[\"priority\"]>(\"MEDIUM\");\n const [title, setTitle] = useState(\"\");\n const projectId =\n projects.find((project) => project.id === requestedProjectId)?.id ?? selectedProject?.id ?? \"\";\n\n const submit = (event: SyntheticEvent<HTMLFormElement, SubmitEvent>): void => {\n event.preventDefault();\n const formElement = event.currentTarget;\n const form = new FormData(formElement);\n const titleValue = form.get(\"title\");\n const descriptionValue = form.get(\"description\");\n const title = typeof titleValue === \"string\" ? titleValue.trim() : \"\";\n const description = typeof descriptionValue === \"string\" ? descriptionValue.trim() : \"\";\n if (!title || !projectId) return;\n\n createMutation.mutate(\n {\n description,\n priority,\n projectId,\n risk: \"MEDIUM\",\n title,\n type: \"TASK\",\n },\n {\n onSuccess: () => {\n formElement.reset();\n setTitle(\"\");\n setOpen(false);\n },\n },\n );\n };\n\n return (\n <DialogSurface\n closeLabel={t(\"action.closeDialog\")}\n description={t(\"task.create.description\")}\n footer={\n <>\n <Button\n disabled={createMutation.isPending}\n onClick={() => {\n setOpen(false);\n }}\n >\n {t(\"action.cancel\")}\n </Button>\n <Button\n disabled={!title.trim() || !projectId}\n loading={createMutation.isPending}\n onClick={() => {\n formRef.current?.requestSubmit();\n }}\n type=\"button\"\n variant=\"primary\"\n >\n {t(\"task.create.submit\")}\n </Button>\n </>\n }\n onOpenChange={setOpen}\n open={open}\n title={t(\"task.new\")}\n trigger={\n <Button disabled={!selectedProject} icon=\"add\" variant=\"primary\">\n {t(\"task.new\")}\n </Button>\n }\n >\n <form className=\"new-task-form\" id=\"new-task-form\" onSubmit={submit} ref={formRef}>\n {createMutation.error ? (\n <LocalConnectionRecovery\n error={createMutation.error}\n onRetry={() => {\n formRef.current?.requestSubmit();\n }}\n retrying={createMutation.isPending}\n />\n ) : null}\n <Field htmlFor=\"new-task-title\" label={t(\"task.create.title\")} required>\n <TextField\n autoFocus\n id=\"new-task-title\"\n name=\"title\"\n onChange={(event) => {\n setTitle(event.currentTarget.value);\n }}\n placeholder={t(\"task.create.titlePlaceholder\")}\n required\n value={title}\n />\n </Field>\n <Field\n description={t(\"task.create.briefDescription\")}\n htmlFor=\"new-task-brief\"\n label={t(\"task.create.brief\")}\n >\n <Textarea\n aria-describedby=\"new-task-brief-description\"\n id=\"new-task-brief\"\n name=\"description\"\n placeholder={t(\"task.create.briefPlaceholder\")}\n rows={5}\n />\n </Field>\n <div className=\"new-task-form__row\">\n <Field htmlFor=\"new-task-project\" label={t(\"task.create.project\")}>\n <SelectControl\n ariaLabel={t(\"task.create.project\")}\n id=\"new-task-project\"\n onValueChange={setRequestedProjectId}\n options={projects.map((project) => ({ label: project.name, value: project.id }))}\n value={projectId}\n />\n </Field>\n <Field htmlFor=\"new-task-priority\" label={t(\"task.create.priority\")}>\n <SelectControl\n ariaLabel={t(\"task.create.priority\")}\n id=\"new-task-priority\"\n onValueChange={(value) => {\n setPriority(prioritySchema.parse(value));\n }}\n options={[\n { label: t(\"priority.LOW\"), value: \"LOW\" },\n { label: t(\"priority.MEDIUM\"), value: \"MEDIUM\" },\n { label: t(\"priority.HIGH\"), value: \"HIGH\" },\n { label: t(\"priority.URGENT\"), value: \"URGENT\" },\n ]}\n value={priority}\n />\n </Field>\n </div>\n </form>\n </DialogSurface>\n );\n};\n\ntype SettingsDialogProps = {\n onOpenChange: (open: boolean) => void;\n open: boolean;\n};\n\ntype SettingChoiceOption<TValue extends string> = {\n icon?: IconName;\n label: string;\n value: TValue;\n};\n\n/**\n * A small set of mutually exclusive options shown as pressable tiles.\n *\n * Preferred over a dropdown here because every choice fits on screen: the reader compares them at a\n * glance and commits in one click, instead of opening a list to see two or three items.\n */\nconst SettingChoice = <TValue extends string>({\n description,\n label,\n onChange,\n options,\n value,\n}: {\n description?: string;\n label: string;\n onChange: (value: TValue) => void;\n options: readonly SettingChoiceOption<TValue>[];\n value: TValue;\n}): React.JSX.Element => {\n // A generated id, because a translated label can contain spaces and would not be a valid IDREF.\n const labelId = useId();\n return (\n <div className=\"setting\">\n <span className=\"setting__label\" id={labelId}>\n {label}\n </span>\n <div aria-labelledby={labelId} className=\"setting__choices\" role=\"group\">\n {options.map((option) => (\n <button\n aria-pressed={value === option.value}\n key={option.value}\n onClick={() => {\n onChange(option.value);\n }}\n type=\"button\"\n >\n {option.icon ? <Icon name={option.icon} size={15} /> : null}\n <span>{option.label}</span>\n </button>\n ))}\n </div>\n {description ? <small className=\"setting__hint\">{description}</small> : null}\n </div>\n );\n};\n\n/**\n * What an owner does about a Project whose recorded path is no longer a repository.\n *\n * Only shown for a Project that has one, and only where the owner is already looking at the path\n * that is wrong. A demo Project gets a button, because Loomrail knows exactly where its repository\n * belongs and can put it there (`useRepairFixtureProject`). A Project the owner registered by path\n * gets the explanation and no button: nothing here knows where they moved their repository to, and\n * offering to \"repair\" it would either do nothing or do the wrong thing -- they register the new\n * path in the field below.\n *\n * This is the reachability half of the repair. `REPOINT_FIXTURE_PROJECT` and its route existed and\n * were tested through HTTP, but the only thing in the product that called the route was \"Initialize\n * demo workspace\", which renders only when there is no selected project at all -- so an owner with\n * two stale demo Projects, which is the shape of the one database that matters, could not reach it\n * by any sequence of clicks.\n */\nconst RepairFixtureProject = ({ project }: { project: ListedProject }): React.JSX.Element => {\n const { t } = useI18n();\n const repairMutation = useRepairFixtureProject();\n const fixtureId = project.fixtureId;\n const error = repairMutation.error instanceof Error ? repairMutation.error.message : null;\n\n return (\n <div className=\"settings__project-repair\">\n <p className=\"settings__note\" role=\"note\">\n {t(\"settings.projects.unusable\")}\n </p>\n {fixtureId === null ? null : (\n <Button\n loading={repairMutation.isPending}\n onClick={() => {\n repairMutation.mutate(fixtureId);\n }}\n >\n {t(\"settings.projects.repair\")}\n </Button>\n )}\n {error === null ? null : (\n <p className=\"settings__project-error\" role=\"alert\">\n {error}\n </p>\n )}\n </div>\n );\n};\n\n/**\n * Where the owner registers a local Git repository of their own as a Project (spec §4).\n *\n * It sits beside the project list rather than in the empty state, because the empty state is gone\n * the moment the demo is initialised, and registering your own repository is exactly the thing you\n * do *after* looking at the demo. The one field is the path: the daemon takes the repository\n * directory's own name, so there is nothing else to ask for.\n *\n * The refusal shown under the field is the daemon's, word for word. It names the path and, when the\n * path is a directory inside another repository, says which repository that is -- a message the\n * domain already writes, and one this form would only make vaguer by paraphrasing.\n */\nconst RegisterRepositoryField = (): React.JSX.Element => {\n const { t } = useI18n();\n const inputId = useId();\n const [path, setPath] = useState(\"\");\n const registerMutation = useRegisterRepositoryProject();\n const error = registerMutation.error instanceof Error ? registerMutation.error.message : null;\n const trimmed = path.trim();\n\n return (\n <form\n className=\"settings__register\"\n onSubmit={(event) => {\n event.preventDefault();\n if (trimmed === \"\") return;\n registerMutation.mutate(trimmed, {\n onSuccess: () => {\n setPath(\"\");\n },\n });\n }}\n >\n <Field\n description={t(\"settings.projects.register.description\")}\n htmlFor={inputId}\n label={t(\"settings.projects.register.label\")}\n {...(error === null ? {} : { error })}\n >\n <TextField\n autoComplete=\"off\"\n id={inputId}\n invalid={error !== null}\n onChange={(event) => {\n setPath(event.target.value);\n }}\n placeholder={t(\"settings.projects.register.placeholder\")}\n size=\"md\"\n spellCheck={false}\n value={path}\n />\n </Field>\n <Button disabled={trimmed === \"\"} loading={registerMutation.isPending} type=\"submit\">\n {t(\"settings.projects.register.action\")}\n </Button>\n </form>\n );\n};\n\n/**\n * Gathers the preferences that belong to this browser.\n *\n * Theme, language and density are stored locally and affect nothing the daemon owns, which is why\n * they live together here. Registering a repository is the one thing in this dialog that is not a\n * local preference: it is a command against domain state, and it lives here because this is where\n * the project list already is -- not because it belongs with the toggles above it.\n */\nconst SettingsDialog = ({ onOpenChange, open }: SettingsDialogProps): React.JSX.Element => {\n const { locale, setLocale, t } = useI18n();\n const { projects, selectedProject, selectProject } = useWorkspace();\n const [theme, setTheme] = useState<ThemePreference>(readThemePreference);\n const [density, setDensity] = useState<DensityPreference>(readDensityPreference);\n const [customWidths, setCustomWidths] = useState(hasCustomPanelWidths);\n\n useEffect(() => {\n if (open) setCustomWidths(hasCustomPanelWidths());\n }, [open]);\n\n return (\n <DialogSurface\n closeLabel={t(\"action.closeDialog\")}\n description={t(\"settings.description\")}\n onOpenChange={onOpenChange}\n open={open}\n title={t(\"settings.title\")}\n >\n <div className=\"settings\">\n <section className=\"settings__section\">\n <h3>{t(\"settings.appearance\")}</h3>\n <SettingChoice\n label={t(\"theme.change\")}\n onChange={(value) => {\n setTheme(value);\n applyThemePreference(value);\n }}\n options={[\n { icon: \"monitor\", label: t(\"theme.system\"), value: \"system\" },\n { icon: \"sun\", label: t(\"theme.light\"), value: \"light\" },\n { icon: \"moon\", label: t(\"theme.dark\"), value: \"dark\" },\n ]}\n value={theme}\n />\n <SettingChoice\n description={t(\"settings.density.description\")}\n label={t(\"settings.density\")}\n onChange={(value) => {\n setDensity(value);\n applyDensityPreference(value);\n }}\n options={[\n { icon: \"list\", label: t(\"settings.density.comfortable\"), value: \"comfortable\" },\n { icon: \"layers\", label: t(\"settings.density.compact\"), value: \"compact\" },\n ]}\n value={density}\n />\n <SettingChoice\n label={t(\"language.change\")}\n onChange={setLocale}\n options={[\n { label: t(\"language.english\"), value: \"en\" },\n { label: t(\"language.russian\"), value: \"ru\" },\n ]}\n value={locale}\n />\n </section>\n\n <section className=\"settings__section\">\n <h3>{t(\"settings.layout\")}</h3>\n <p className=\"settings__note\">{t(\"settings.layout.description\")}</p>\n <Button\n disabled={!customWidths}\n onClick={() => {\n resetPanelWidths();\n setCustomWidths(false);\n }}\n >\n {t(\"settings.layout.reset\")}\n </Button>\n </section>\n\n <section className=\"settings__section\">\n <h3>{t(\"settings.projects\")}</h3>\n {projects.length > 0 ? (\n <ul className=\"settings__projects\">\n {projects.map((project) => (\n <li key={project.id}>\n <button\n aria-pressed={project.id === selectedProject?.id}\n onClick={() => {\n selectProject(project.id);\n }}\n type=\"button\"\n >\n <span>{project.name.slice(0, 1).toUpperCase()}</span>\n <span className=\"settings__project-copy\">\n <strong>{project.name}</strong>\n {/* The path, not only the name. A Project whose repository has moved or was\n never one is otherwise indistinguishable here from a healthy one -- which\n is how two demo Projects stuck at a directory inside Loomrail's own\n checkout stayed invisible while every IMPLEMENT on them was refused. */}\n <small className=\"settings__project-path\" title={project.repositoryPath}>\n {t(\"settings.projects.repositoryLabel\")}: {project.repositoryPath}\n </small>\n </span>\n {project.id === selectedProject?.id ? <Icon name=\"check\" size={14} /> : null}\n </button>\n {project.repositoryStatus === \"UNUSABLE\" ? (\n <RepairFixtureProject project={project} />\n ) : null}\n </li>\n ))}\n </ul>\n ) : (\n <p className=\"settings__note\">{t(\"project.none\")}</p>\n )}\n <RegisterRepositoryField />\n </section>\n </div>\n </DialogSurface>\n );\n};\n\nconst SidebarLink = ({\n active,\n count,\n icon,\n label,\n search,\n}: {\n active: boolean;\n count?: number;\n icon: IconName;\n label: string;\n search: WorkbenchSearch;\n}): React.JSX.Element => (\n <Link className={cn(\"app-nav-link\", active && \"is-active\")} search={search} to=\"/\">\n <Icon name={icon} size={15} />\n <span>{label}</span>\n {count !== undefined && count > 0 ? <em className=\"app-nav-link__count\">{count}</em> : null}\n </Link>\n);\n\n/**\n * Reports whether a single-line label is clipped by the width it was given.\n *\n * The sidebar is resizable and collapses to an icon rail, so the project name only earns a tooltip\n * once it stops fitting; a label the rail hides entirely counts as clipped as well.\n */\nconst useClippedLabel = (label: string): { clipped: boolean; ref: (node: HTMLElement | null) => void } => {\n const [node, setNode] = useState<HTMLElement | null>(null);\n const [clipped, setClipped] = useState(false);\n\n useEffect(() => {\n if (node === null) return undefined;\n\n const measure = (): void => {\n setClipped(node.scrollWidth > node.clientWidth || node.clientWidth === 0);\n };\n\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(node);\n return () => {\n observer.disconnect();\n };\n }, [label, node]);\n\n return { clipped, ref: setNode };\n};\n\nconst WorkspaceNavigation = ({\n onNavigate,\n onOpenSettings,\n}: {\n onNavigate?: () => void;\n onOpenSettings: () => void;\n}): React.JSX.Element => {\n const { t } = useI18n();\n const { connection, projects, selectedProject, selectProject } = useWorkspace();\n const humanRequestsQuery = useProjectHumanRequests(selectedProject?.id);\n const search = useLocation({ select: (location) => location.search });\n const connected = connection?.status === \"connected\";\n const projectInitial = selectedProject?.name.slice(0, 1).toUpperCase() ?? \"–\";\n const projectName = selectedProject?.name ?? \"\";\n const { clipped: projectNameClipped, ref: projectNameRef } = useClippedLabel(projectName);\n const blockingCount = humanRequestsQuery.data?.humanRequests.filter(({ blocking }) => blocking).length ?? 0;\n const onNeedsYou = search.summary === \"needsYou\";\n\n return (\n <>\n <div className=\"app-sidebar__workspace\">\n <BrandMark className=\"app-brand-mark\" size={22} />\n <strong>Loomrail</strong>\n </div>\n\n <div className=\"app-nav-group\">\n <span>{t(\"nav.yourProjects\")}</span>\n {projects.length > 0 ? (\n <ActionMenu\n groups={[\n projects.map((project) => ({\n label: project.name,\n onSelect: () => {\n selectProject(project.id);\n onNavigate?.();\n },\n shortcut: project.id === selectedProject?.id ? \"✓\" : \"\",\n })),\n ]}\n trigger={\n <button aria-label={t(\"project.switch\")} className=\"app-project-label\" type=\"button\">\n <span>{projectInitial}</span>\n <strong ref={projectNameRef}>{projectName}</strong>\n <Icon name=\"chevronDown\" size={12} />\n </button>\n }\n {...(projectNameClipped ? { triggerTooltip: projectName } : {})}\n />\n ) : (\n <div className=\"app-project-label is-empty\">\n <span>–</span>\n <strong>{t(\"project.none\")}</strong>\n </div>\n )}\n <nav aria-label={t(\"nav.workspace\")} className=\"app-nav app-nav--nested\" onClick={onNavigate}>\n <SidebarLink active={!onNeedsYou} icon=\"board\" label={t(\"nav.currentWork\")} search={{}} />\n <SidebarLink\n active={onNeedsYou}\n count={blockingCount}\n icon=\"question\"\n label={t(\"nav.humanRequests\")}\n search={{ summary: \"needsYou\" }}\n />\n </nav>\n </div>\n\n <div className=\"app-sidebar__footer\">\n <span className={connected ? \"app-connection is-online\" : \"app-connection is-offline\"}>\n <span aria-hidden=\"true\" />\n {connected ? t(\"connection.local\") : t(\"connection.offline\")}\n </span>\n <Tooltip label={t(\"settings.open\")}>\n <IconButton\n label={t(\"settings.open\")}\n name=\"settings\"\n onClick={() => {\n onOpenSettings();\n }}\n />\n </Tooltip>\n </div>\n </>\n );\n};\n\nexport const AppFrame = (): React.JSX.Element => {\n const { t } = useI18n();\n const { connectionPending, projectsPending, selectedProject } = useWorkspace();\n const [navigationOpen, setNavigationOpen] = useState(false);\n const [settingsOpen, setSettingsOpen] = useState(false);\n const projectInitial = selectedProject?.name.slice(0, 1).toUpperCase() ?? \"–\";\n\n if (connectionPending || projectsPending) {\n return (\n <div aria-busy=\"true\" className=\"app-shell app-shell--loading\">\n <aside aria-hidden=\"true\" className=\"app-sidebar app-sidebar--loading\" />\n <section className=\"app-surface app-surface--loading\">\n <span aria-label={t(\"connection.connecting\")} className=\"app-loading-mark\" role=\"status\">\n <BrandMark className=\"app-brand-mark\" size={40} />\n </span>\n </section>\n </div>\n );\n }\n\n return (\n <div className=\"app-shell\">\n <aside className=\"app-sidebar\">\n <WorkspaceNavigation\n onOpenSettings={() => {\n setSettingsOpen(true);\n }}\n />\n <PanelResizer edge=\"start\" panel=\"sidebar\" />\n </aside>\n\n <section className=\"app-surface\">\n <header className=\"app-topbar\">\n <div className=\"app-breadcrumbs\">\n <DialogSurface\n className=\"app-navigation-drawer\"\n closeLabel={t(\"action.closeDialog\")}\n onOpenChange={setNavigationOpen}\n open={navigationOpen}\n title={t(\"nav.workspace\")}\n trigger={\n <IconButton className=\"app-navigation-trigger\" label={t(\"nav.open\")} name=\"menu\" size=\"sm\" />\n }\n >\n <WorkspaceNavigation\n onNavigate={() => {\n setNavigationOpen(false);\n }}\n onOpenSettings={() => {\n setNavigationOpen(false);\n setSettingsOpen(true);\n }}\n />\n </DialogSurface>\n <span className=\"app-project-icon\">{projectInitial}</span>\n <span className=\"app-breadcrumbs__project\">\n {selectedProject?.name ?? t(\"project.noneSingle\")}\n </span>\n <Icon name=\"chevronRight\" size={12} />\n <strong>{t(\"work.current\")}</strong>\n </div>\n <div className=\"app-topbar__actions\">\n <NewTaskDialog />\n </div>\n </header>\n <main className=\"app-content\" id=\"main-content\">\n <Outlet />\n </main>\n </section>\n\n <SettingsDialog onOpenChange={setSettingsOpen} open={settingsOpen} />\n </div>\n );\n};\n","import { useState } from \"react\";\nimport type { ChangedFile } from \"@loomrail/contracts\";\nimport { Badge, Icon, InspectorSection } from \"@loomrail/ui\";\n\nimport { changeStatusLabelKeys, changeStatusTones, changesRefusalKey } from \"../changesView\";\nimport { useI18n } from \"../i18n\";\nimport type { Translator } from \"../i18n\";\nimport { useWorkItemChanges, useWorkItemFileDiff } from \"../workspace\";\n\n/**\n * What the row says about one file, shared by the two shapes a row can take.\n *\n * A binary file's row is a plain `<div>` and a text file's row is a `<button>` that expands it, and\n * the only difference between them is that -- so the contents are written once here rather than\n * twice, where the two could drift into naming the same file differently.\n */\nconst ChangedFileRow = ({ file, t }: { file: ChangedFile; t: Translator }): React.JSX.Element => (\n <span className=\"changes-row\">\n <span className=\"changes-row__head\">\n <Badge tone={changeStatusTones[file.status]}>{t(changeStatusLabelKeys[file.status])}</Badge>\n <code className=\"changes-row__path\">{file.path}</code>\n </span>\n <span className=\"changes-row__meta\">\n {/* Spec §10.4: a rename is one file that moved, not a deletion plus an addition, and the row\n is only telling the truth about it if the name it moved from is on screen too. */}\n {file.previousPath === null ? null : (\n <span className=\"changes-row__previous\">{t(\"changes.renamedFrom\", { path: file.previousPath })}</span>\n )}\n {/* Named binary rather than shown as an empty diff (spec D8), and shown INSTEAD of line\n counts rather than beside them: git reports no line counts for a binary file, its\n `insertions`/`deletions` are null, and printing `+0 −0` would read as \"nothing changed in\n it\". The counts below are rendered only when both are really there, for that same reason\n -- there is no zero to fall back on. */}\n {file.binary ? <Badge tone=\"neutral\">{t(\"changes.binary\")}</Badge> : null}\n {file.insertions === null || file.deletions === null ? null : (\n <span\n aria-label={t(\"changes.lineCounts\", {\n insertions: file.insertions,\n deletions: file.deletions,\n })}\n className=\"changes-row__counts\"\n >\n <span className=\"changes-row__insertions\">+{file.insertions}</span>\n <span className=\"changes-row__deletions\">&minus;{file.deletions}</span>\n </span>\n )}\n </span>\n </span>\n);\n\n/**\n * The body of the one file the owner expanded.\n *\n * A component of its own so that the query lives and dies with the disclosure: a body is fetched\n * when this mounts and never before, which is what keeps the file list free of the cost of the\n * patches it lists (spec D5). It is also what makes the measured, debounced reread after a stage\n * event cost one body rather than all of them -- only the mounted query is active when the event\n * bridge invalidates the changes subtree (spec D6).\n *\n * The patch is printed as preformatted text and nothing else. Colouring each line would mean one\n * element per line, and this diff is capped at 512 KiB rather than at a number of lines -- a\n * generated file at that cap is tens of thousands of elements for an effect the leading `+` and `-`\n * of a unified diff already carry. Side-by-side and syntax highlighting are named non-goals of this\n * milestone (spec §11).\n */\nconst ExpandedFileDiff = ({ path, workItemId }: { path: string; workItemId: string }): React.JSX.Element => {\n const { locale, t } = useI18n();\n const diffQuery = useWorkItemFileDiff(workItemId, path);\n\n if (diffQuery.error) {\n return (\n <p className=\"changes-diff__note\" role=\"status\">\n {t(changesRefusalKey(diffQuery.error))}\n </p>\n );\n }\n\n if (diffQuery.isPending) {\n return (\n <p className=\"changes-diff__note\" role=\"status\">\n {t(\"changes.diffPending\")}\n </p>\n );\n }\n\n const diff = diffQuery.data.diff;\n if (diff === null) {\n // The handle answers `null` for a work item with no workspace, and the list this row belongs to\n // could only have been drawn from a workspace that existed a moment ago -- so reaching here\n // means it stopped existing between the two reads. Saying so beats a spinner that never ends.\n return (\n <p className=\"changes-diff__note\" role=\"status\">\n {t(\"changes.diffUnavailable\")}\n </p>\n );\n }\n\n // `patch === null` and `binary` are the same fact from the two sides of the contract, and either\n // one is enough: there is no text to print, and printing \"\" would read as a real but empty diff.\n if (diff.binary || diff.patch === null) {\n return <p className=\"changes-diff__note\">{t(\"changes.binaryNoPatch\")}</p>;\n }\n\n return (\n <div className=\"changes-diff\">\n <pre className=\"changes-diff__patch\">\n <code>{diff.patch}</code>\n </pre>\n {/* Spec D8: a body that was cut says so where the owner is reading it. Silent truncation\n turns \"there are another two hundred lines\" into \"that is all of it\". */}\n {diff.truncated ? (\n <p className=\"changes-diff__note\">\n {t(\"changes.patchTruncated\", { bytes: diff.omittedBytes.toLocaleString(locale) })}\n </p>\n ) : null}\n </div>\n );\n};\n\n/**\n * The files this work item's agent changed, and the diff inside the one the owner expanded\n * (spec §9).\n *\n * Renders nothing at all -- no heading, no shell -- for a work item with no workspace, which is\n * every prose-only stage and every item before its first code stage. That is the same decision\n * `WorkspacePanel` makes next to it and for the same reason: a heading standing over a blank reads\n * as a panel that failed to load rather than as an absence.\n *\n * A refusal, on the other hand, is shown. \"Loomrail could not read this\" and \"there is nothing to\n * read\" are different pieces of news, and collapsing the first into the second would make an\n * unreadable worktree look like an idle one (spec D7).\n *\n * The section is keyed by work item at the call site, so `expandedPath` cannot survive a switch to\n * a different task and reopen a same-named file the owner never asked about.\n */\nexport const ChangesSection = ({ workItemId }: { workItemId: string }): React.JSX.Element | null => {\n const { t } = useI18n();\n const [expandedPath, setExpandedPath] = useState<string | null>(null);\n const changesQuery = useWorkItemChanges(workItemId);\n\n if (changesQuery.error) {\n return (\n <InspectorSection title={t(\"changes.title\")}>\n <p className=\"changes__refusal\" role=\"status\">\n {t(changesRefusalKey(changesQuery.error))}\n </p>\n </InspectorSection>\n );\n }\n\n // Pending and \"no workspace\" both render nothing, deliberately: while the read is in flight there\n // is no honest answer to show, and an empty section that later fills in would move everything\n // below it on the page.\n const summary = changesQuery.data?.changes ?? null;\n if (summary === null) return null;\n\n return (\n <InspectorSection title={t(\"changes.title\")}>\n {summary.files.length === 0 ? (\n // An empty list is a statement about the world -- the worktree is unchanged -- and never\n // the residue of a read that failed, because that arrives as the refusal above (spec D7).\n <p className=\"inspector-copy\">{t(\"changes.empty\")}</p>\n ) : (\n <div className=\"changes\">\n {/* Spec D8 again, for the list rather than a body: the owner is looking at the first N of\n more, and has to be told before they conclude the rest was never changed. */}\n {summary.truncated ? (\n <p className=\"changes__note\">{t(\"changes.truncated\", { count: summary.files.length })}</p>\n ) : null}\n <ul className=\"changes-list\">\n {summary.files.map((file) => {\n const expanded = expandedPath === file.path;\n return (\n <li className=\"changes-list__item\" key={file.path}>\n {file.binary ? (\n // No control at all, rather than one that opens onto \"there is no diff\": the\n // row already says the file is binary, and a disclosure that can only ever\n // disclose that sentence is a button that does nothing.\n <div className=\"changes-list__row\">\n <ChangedFileRow file={file} t={t} />\n </div>\n ) : (\n <button\n aria-expanded={expanded}\n className=\"changes-list__row changes-list__toggle\"\n onClick={() => {\n setExpandedPath(expanded ? null : file.path);\n }}\n type=\"button\"\n >\n {/* Decorative: `aria-expanded` above already tells assistive tech the state,\n and the row's own text is its accessible name. This is the only sign a\n sighted reader has that the row opens at all. */}\n <Icon\n aria-hidden=\"true\"\n className=\"changes-list__chevron\"\n name={expanded ? \"chevronDown\" : \"chevronRight\"}\n size={12}\n />\n <ChangedFileRow file={file} t={t} />\n </button>\n )}\n {expanded ? <ExpandedFileDiff path={file.path} workItemId={workItemId} /> : null}\n </li>\n );\n })}\n </ul>\n </div>\n )}\n </InspectorSection>\n );\n};\n","import type { WorkItemState } from \"@loomrail/contracts\";\n\n/** Manual state changes an owner may apply to a WorkItem that no workflow run currently owns. */\nexport const transitionTargets: Record<WorkItemState, readonly WorkItemState[]> = {\n BACKLOG: [\"READY\", \"CANCELLED\"],\n READY: [\"BACKLOG\", \"IN_PROGRESS\", \"BLOCKED\", \"CANCELLED\"],\n IN_PROGRESS: [\"READY\", \"BLOCKED\", \"CANCELLED\"],\n BLOCKED: [\"READY\", \"IN_PROGRESS\", \"CANCELLED\"],\n DONE: [],\n CANCELLED: [],\n};\n\nexport type MoveShortcuts = {\n /** The move that carries delivery forward, emphasised in the inspector footer. */\n primary: WorkItemState | null;\n /** The most useful remaining move, offered without emphasis. */\n secondary: WorkItemState | null;\n};\n\n/**\n * Footer shortcuts are chosen by meaning, not by the order of `transitionTargets`.\n *\n * `IN_PROGRESS` has no forward shortcut on purpose: `DONE` is reachable only through recorded owner\n * acceptance, so promoting a sideways or backward move would misrepresent it. `CANCELLED` is never a\n * shortcut — it stays behind the explicit Move menu, which always offers the full transition set.\n */\nconst moveShortcuts: Record<WorkItemState, MoveShortcuts> = {\n BACKLOG: { primary: \"READY\", secondary: null },\n READY: { primary: \"IN_PROGRESS\", secondary: \"BACKLOG\" },\n IN_PROGRESS: { primary: null, secondary: \"BLOCKED\" },\n BLOCKED: { primary: \"IN_PROGRESS\", secondary: \"READY\" },\n DONE: { primary: null, secondary: null },\n CANCELLED: { primary: null, secondary: null },\n};\n\nconst allowed = (state: WorkItemState, target: WorkItemState | null): WorkItemState | null =>\n target !== null && transitionTargets[state].includes(target) ? target : null;\n\n/**\n * Resolves the inspector footer shortcuts for a WorkItem. While a workflow run owns the item the\n * owner acts through workflow controls, so no manual shortcut is offered.\n */\nexport const moveShortcutsFor = (state: WorkItemState, workflowActive: boolean): MoveShortcuts => {\n if (workflowActive) return { primary: null, secondary: null };\n const { primary, secondary } = moveShortcuts[state];\n return { primary: allowed(state, primary), secondary: allowed(state, secondary) };\n};\n","import { useEffect, useRef, useState } from \"react\";\nimport type { SyntheticEvent } from \"react\";\nimport { useNavigate, useSearch } from \"@tanstack/react-router\";\nimport {\n isSessionPauseFailureCode,\n prioritySchema,\n riskSchema,\n type AcceptanceAction,\n type AcceptancePackage,\n type Checkpoint,\n type ContextWindowUsage,\n type DomainEvent,\n type EvidenceArtifact,\n type HumanRequest,\n type PipelineRun,\n type ProviderSession,\n type SessionPauseFailureCode,\n type StageAttempt,\n type StageAttemptStatus,\n type WorkItem,\n type WorkItemChangedField,\n type WorkItemState,\n type PublishedWorkItemWorkspace,\n type WorkItemWorkspaceStatus,\n} from \"@loomrail/contracts\";\nimport {\n ActionMenu,\n AppliedFilterBar,\n Button,\n CascadingFilter,\n Checkbox,\n cn,\n DialogSurface,\n FeedbackState,\n Field,\n Icon,\n IconButton,\n InspectorSection,\n KanbanColumn,\n PopoverSurface,\n ProviderSessionTimeline,\n RadioGroup,\n RunSummary,\n SelectControl,\n Skeleton,\n Status,\n Switch,\n TaskCard,\n Textarea,\n TextField,\n TimelineEvent,\n Tooltip,\n type BadgeTone,\n type CheckpointGroup,\n type CheckpointViewModel,\n type FilterMessages,\n type FilterNode,\n type ProviderSessionTimelineAttempt,\n type ProviderSessionViewModel,\n type StatusTone,\n type TimelineEventProps,\n} from \"@loomrail/ui\";\n\nimport { ChangesSection } from \"./ChangesSection\";\nimport {\n defaultBoardView,\n isBoardOrdering,\n orderWorkItems,\n scopeShows,\n type BoardOrdering,\n type BoardScope,\n type BoardView,\n} from \"../boardView\";\nimport { PanelResizer } from \"../components/PanelResizer\";\nimport { LocalConnectionRecovery } from \"../components/LocalConnectionRecovery\";\nimport { useI18n, type Locale, type TranslationKey, type Translator } from \"../i18n\";\nimport type { SummaryFilter } from \"../router\";\nimport { moveShortcutsFor, transitionTargets } from \"../taskMoves\";\nimport {\n useInitializeFixtureWorkspace,\n useApproveBudgetOverride,\n useAnswerHumanRequest,\n useMoveWorkItem,\n usePipelineControl,\n useProjectHumanRequests,\n useProjectWorkItems,\n useProviderCapabilities,\n useResolveAcceptance,\n useStageAttemptSessions,\n useStartMockPipeline,\n useUpdateWorkItem,\n useWorkspace,\n useWorkItemEvents,\n useWorkItemWorkflow,\n useWorkItemWorkspace,\n} from \"../workspace\";\n\nconst viewOrderingOptions = (t: Translator): readonly { label: string; value: BoardOrdering }[] => [\n { label: t(\"property.priority\"), value: \"priority\" },\n { label: t(\"view.created\"), value: \"created\" },\n { label: t(\"view.updated\"), value: \"updated\" },\n { label: t(\"view.title\"), value: \"title\" },\n];\n\ntype ViewSettingsProps = {\n onViewChange: (value: BoardView) => void;\n view: BoardView;\n};\n\nconst ViewSettings = ({ onViewChange, view }: ViewSettingsProps): React.JSX.Element => {\n const { t } = useI18n();\n const nextDirection = view.direction === \"asc\" ? \"desc\" : \"asc\";\n\n return (\n <div className=\"view-settings\">\n <div className=\"view-settings__controls\">\n <div className=\"view-settings__row\">\n <span>{t(\"view.ordering\")}</span>\n <div className=\"view-settings__ordering\">\n <Tooltip label={t(`view.direction.${nextDirection}`)}>\n <IconButton\n className={cn(\"view-settings__direction\", view.direction === \"desc\" && \"is-descending\")}\n label={t(`view.direction.${nextDirection}`)}\n name=\"sortAscending\"\n onClick={() => {\n onViewChange({ ...view, direction: nextDirection });\n }}\n size=\"sm\"\n />\n </Tooltip>\n <SelectControl\n ariaLabel={t(\"view.orderBy\")}\n onValueChange={(value) => {\n if (isBoardOrdering(value)) onViewChange({ ...view, ordering: value });\n }}\n options={viewOrderingOptions(t)}\n size=\"sm\"\n value={view.ordering}\n variant=\"compact\"\n />\n </div>\n </div>\n </div>\n <div className=\"view-settings__section\">\n <span className=\"view-settings__section-title\">{t(\"view.boardOptions\")}</span>\n <Switch\n checked={view.showEmptyColumns}\n label={t(\"view.showEmptyColumns\")}\n onCheckedChange={(checked) => {\n onViewChange({ ...view, showEmptyColumns: checked });\n }}\n />\n </div>\n </div>\n );\n};\n\ntype BoardToolbarProps = {\n filters: readonly string[];\n onClearFilters: () => void;\n onFiltersChange: (value: readonly string[]) => void;\n onScopeChange: (value: BoardScope) => void;\n onSummaryFilterChange: (value: SummaryFilter | null) => void;\n onViewChange: (value: BoardView) => void;\n options: readonly FilterNode[];\n scope: BoardScope;\n summaryFilter: SummaryFilter | null;\n view: BoardView;\n};\n\nconst BoardToolbar = ({\n filters,\n onClearFilters,\n onFiltersChange,\n onScopeChange,\n onSummaryFilterChange,\n onViewChange,\n options,\n scope,\n summaryFilter,\n view,\n}: BoardToolbarProps): React.JSX.Element => {\n const { t } = useI18n();\n const hasActiveFilters = filters.length > 0 || summaryFilter !== null;\n const summaryFilterLabel = summaryFilter ? t(`work.summary.${summaryFilter}`) : null;\n const filterMessages: Partial<FilterMessages> = {\n add: t(\"filter.add\"),\n addFilterPlaceholder: t(\"filter.addPlaceholder\"),\n backTo: t(\"filter.backTo\"),\n clear: t(\"filter.clear\"),\n close: t(\"filter.close\"),\n description: t(\"filter.description\"),\n edit: t(\"filter.edit\"),\n filterPlaceholder: t(\"filter.placeholder\"),\n is: t(\"filter.is\"),\n isAnyOf: t(\"filter.isAnyOf\"),\n noMatchingProperties: t(\"filter.noProperties\"),\n noMatchingValues: t(\"filter.noValues\"),\n oneValue: t(\"filter.oneValue\"),\n options: t(\"filter.options\"),\n remove: t(\"filter.remove\"),\n rootTitle: t(\"filter.rootTitle\"),\n search: t(\"filter.search\"),\n selectedValues: t(\"filter.selectedValues\"),\n };\n\n return (\n <div className=\"board-toolbar-stack\">\n <div className=\"board-toolbar\">\n <div className=\"board-view-tabs\">\n {(\n [\n { labelKey: \"view.active\", value: \"active\" },\n { labelKey: \"view.backlog\", value: \"backlog\" },\n { labelKey: \"view.allIssues\", value: \"all\" },\n ] as const\n ).map(({ labelKey, value }) => (\n <Button\n aria-pressed={scope === value}\n key={value}\n onClick={() => {\n onScopeChange(value);\n }}\n shape=\"pill\"\n variant=\"surface\"\n >\n {t(labelKey)}\n </Button>\n ))}\n </div>\n <div className=\"board-toolbar__actions\">\n <CascadingFilter\n ariaLabel={t(\"view.filter\")}\n messages={filterMessages}\n onValueChange={onFiltersChange}\n options={options}\n trigger={<IconButton label={t(\"view.filter\")} name=\"filter\" variant=\"surface\" />}\n triggerTooltip={t(\"view.filter\")}\n value={filters}\n />\n <PopoverSurface\n className=\"view-settings-popover\"\n label={t(\"view.display\")}\n trigger={<IconButton label={t(\"view.display\")} name=\"settings\" variant=\"surface\" />}\n triggerTooltip={t(\"view.display\")}\n >\n <ViewSettings onViewChange={onViewChange} view={view} />\n </PopoverSurface>\n <ActionMenu\n align=\"end\"\n groups={[\n [\n {\n icon: \"link\",\n label: t(\"view.copyLink\"),\n // Filters, ordering and scope live in the URL, so the address is the shareable view.\n onSelect: () => {\n void navigator.clipboard.writeText(window.location.href);\n },\n },\n ],\n ]}\n trigger={<IconButton label={t(\"view.actions\")} name=\"more\" variant=\"surface\" />}\n triggerTooltip={t(\"view.actions\")}\n />\n </div>\n </div>\n {hasActiveFilters ? (\n <AppliedFilterBar\n addFilter={\n <CascadingFilter\n ariaLabel={t(\"view.filter\")}\n messages={filterMessages}\n onValueChange={onFiltersChange}\n options={options}\n trigger={\n <IconButton className=\"board-add-filter\" label={t(\"view.filter\")} name=\"add\" size=\"sm\" />\n }\n triggerTooltip={t(\"view.filter\")}\n value={filters}\n />\n }\n ariaLabel={t(\"view.filter\")}\n className=\"board-applied-filters\"\n messages={filterMessages}\n onClear={onClearFilters}\n onValueChange={onFiltersChange}\n options={options}\n supplementalConditions={\n summaryFilter && summaryFilterLabel ? (\n <div className=\"lr-applied-filter board-summary-filter\">\n <span className=\"lr-applied-filter__property\">\n <Icon name=\"filter\" size={12} />\n {t(\"work.summary.filter\")}\n </span>\n <span className=\"lr-applied-filter__value\">{summaryFilterLabel}</span>\n <Tooltip label={t(\"work.summary.clear\")}>\n <button\n aria-label={t(\"work.summary.clear\")}\n className=\"lr-applied-filter__remove\"\n onClick={() => {\n onSummaryFilterChange(null);\n }}\n type=\"button\"\n >\n <Icon name=\"close\" size={12} />\n </button>\n </Tooltip>\n </div>\n ) : null\n }\n value={filters}\n />\n ) : null}\n </div>\n );\n};\n\nconst boardColumns = [\n { labelKey: \"state.BACKLOG\", state: \"BACKLOG\", tone: \"queued\" },\n { labelKey: \"state.READY\", state: \"READY\", tone: \"ready\" },\n { labelKey: \"state.IN_PROGRESS\", state: \"IN_PROGRESS\", tone: \"running\" },\n { labelKey: \"state.BLOCKED\", state: \"BLOCKED\", tone: \"waiting\" },\n { labelKey: \"state.DONE\", state: \"DONE\", tone: \"complete\" },\n { labelKey: \"state.CANCELLED\", state: \"CANCELLED\", tone: \"paused\" },\n] as const satisfies readonly {\n labelKey: TranslationKey;\n state: WorkItemState;\n tone: StatusTone;\n}[];\n\nconst columnsFor = (scope: BoardScope): readonly (typeof boardColumns)[number][] =>\n boardColumns.filter((column) => scopeShows(scope, column.state));\n\nconst stateLabelKeys: Record<WorkItemState, TranslationKey> = {\n BACKLOG: \"state.BACKLOG\",\n READY: \"state.READY\",\n IN_PROGRESS: \"state.IN_PROGRESS\",\n BLOCKED: \"state.BLOCKED\",\n DONE: \"state.DONE\",\n CANCELLED: \"state.CANCELLED\",\n};\n\nconst stateLabel = (state: WorkItemState, t: Translator): string => t(stateLabelKeys[state]);\n\nconst priorityLabelKeys: Record<WorkItem[\"priority\"], TranslationKey> = {\n LOW: \"priority.LOW\",\n MEDIUM: \"priority.MEDIUM\",\n HIGH: \"priority.HIGH\",\n URGENT: \"priority.URGENT\",\n};\n\nconst riskLabelKeys: Record<WorkItem[\"risk\"], TranslationKey> = {\n LOW: \"risk.LOW\",\n MEDIUM: \"risk.MEDIUM\",\n HIGH: \"risk.HIGH\",\n CRITICAL: \"risk.CRITICAL\",\n};\n\nconst typeLabelKeys: Record<WorkItem[\"type\"], TranslationKey> = {\n EPIC: \"type.EPIC\",\n FEATURE: \"type.FEATURE\",\n TASK: \"type.TASK\",\n BUG: \"type.BUG\",\n SPIKE: \"type.SPIKE\",\n SUBTASK: \"type.SUBTASK\",\n};\n\nconst stageLabelKeys: Record<NonNullable<WorkItem[\"currentStage\"]>, TranslationKey> = {\n DISCOVERY: \"stage.DISCOVERY\",\n PLAN: \"stage.PLAN\",\n IMPLEMENT: \"stage.IMPLEMENT\",\n REVIEW: \"stage.REVIEW\",\n QA: \"stage.QA\",\n ACCEPTANCE: \"stage.ACCEPTANCE\",\n};\n\nconst stateTones: Record<WorkItemState, StatusTone> = {\n BACKLOG: \"queued\",\n READY: \"ready\",\n IN_PROGRESS: \"running\",\n BLOCKED: \"waiting\",\n DONE: \"complete\",\n CANCELLED: \"paused\",\n};\n\nconst priorityTone = (priority: WorkItem[\"priority\"]): BadgeTone => {\n if (priority === \"URGENT\") return \"danger\";\n if (priority === \"HIGH\") return \"warning\";\n return \"neutral\";\n};\n\nconst displayWorkItemId = (id: string): string => {\n const suffix = id.split(\"-\").at(-1) ?? id;\n return suffix.length > 10 ? suffix.slice(0, 8).toUpperCase() : suffix.toUpperCase();\n};\n\nconst filterOptionsFor = (\n items: readonly WorkItem[],\n columns: readonly (typeof boardColumns)[number][],\n t: Translator,\n): readonly FilterNode[] => {\n const count = (predicate: (item: WorkItem) => boolean): number => items.filter(predicate).length;\n return [\n {\n id: \"status\",\n label: t(\"filter.status\"),\n icon: \"clock\",\n children: columns.map((column) => ({\n id: `status-${column.state.toLowerCase()}`,\n label: t(column.labelKey),\n count: count((item) => item.state === column.state),\n })),\n },\n {\n id: \"priority\",\n label: t(\"filter.priority\"),\n icon: \"filter\",\n children: ([\"URGENT\", \"HIGH\", \"MEDIUM\", \"LOW\"] as const).map((priority) => ({\n id: `priority-${priority.toLowerCase()}`,\n label: t(priorityLabelKeys[priority]),\n count: count((item) => item.priority === priority),\n })),\n },\n {\n id: \"risk\",\n label: t(\"filter.risk\"),\n icon: \"warning\",\n children: ([\"CRITICAL\", \"HIGH\", \"MEDIUM\", \"LOW\"] as const).map((risk) => ({\n id: `risk-${risk.toLowerCase()}`,\n label: t(riskLabelKeys[risk]),\n count: count((item) => item.risk === risk),\n })),\n },\n ];\n};\n\nconst matchesFilters = (item: WorkItem, filters: readonly string[]): boolean =>\n filters.every((filter) => {\n if (filter.startsWith(\"status-\")) return filter === `status-${item.state.toLowerCase()}`;\n if (filter.startsWith(\"priority-\")) return filter === `priority-${item.priority.toLowerCase()}`;\n if (filter.startsWith(\"risk-\")) return filter === `risk-${item.risk.toLowerCase()}`;\n return true;\n });\n\nconst changedFieldLabelKeys: Record<WorkItemChangedField, TranslationKey> = {\n title: \"field.title\",\n description: \"field.description\",\n priority: \"field.priority\",\n risk: \"field.risk\",\n acceptanceCriteria: \"field.acceptanceCriteria\",\n};\n\n// A total Record over the contract's own union, so a new quality cannot arrive without this file\n// failing to compile -- the same discipline `hardPauseLabelKeys` below is written under. Its codes\n// come from @loomrail/contracts rather than a local copy, so the cockpit's reading of \"is this a\n// session pause\" cannot drift from the domain's.\nconst usageQualityLabelKeys: Record<ContextWindowUsage[\"quality\"], TranslationKey> = {\n ACTUAL: \"workflow.sessions.usageQuality.ACTUAL\",\n PROVIDER_ESTIMATE: \"workflow.sessions.usageQuality.PROVIDER_ESTIMATE\",\n LOOMRAIL_ESTIMATE: \"workflow.sessions.usageQuality.LOOMRAIL_ESTIMATE\",\n};\n\nconst hardPauseLabelKeys: Record<SessionPauseFailureCode, TranslationKey> = {\n NO_PROGRESS: \"workflow.hardPause.noProgress\",\n CONTEXT_FLOOR_EXCEEDED: \"workflow.hardPause.contextFloor\",\n PROVIDER_REJECTED_PACK: \"workflow.hardPause.providerRejected\",\n PROVIDER_START_FAILED: \"workflow.hardPause.providerStartFailed\",\n SESSION_LIMIT_REACHED: \"workflow.hardPause.sessionLimit\",\n};\n\n// A HARD_PAUSED attempt is not necessarily budget-paused: the session loop hard-pauses for reasons\n// that have nothing to do with tokens, and decideApproveBudgetOverride refuses a session pause.\n// `failureCode` is what tells the two apart; `budgetFallbackKey` lets both call sites below (the\n// pipeline-level Status badge and the per-stage list label) keep their own text for the\n// genuinely-budget case.\nconst hardPauseLabel = (\n failureCode: string | null,\n budgetFallbackKey: TranslationKey,\n t: Translator,\n): string =>\n isSessionPauseFailureCode(failureCode) ? t(hardPauseLabelKeys[failureCode]) : t(budgetFallbackKey);\n\nconst stageAttemptStatusLabel = (attempt: StageAttempt, t: Translator): string => {\n if (attempt.status === \"QUEUED\") return t(\"workflow.stage.QUEUED\");\n if (attempt.status === \"RUNNING\") return t(\"workflow.stage.RUNNING\");\n if (attempt.status === \"WAITING_HUMAN\") return t(\"workflow.stage.WAITING_HUMAN\");\n if (attempt.status === \"SOFT_PAUSED\") return t(\"workflow.stage.SOFT_PAUSED\");\n if (attempt.status === \"HARD_PAUSED\") {\n return hardPauseLabel(attempt.failureCode, \"workflow.stage.HARD_PAUSED\", t);\n }\n if (attempt.status === \"INTERRUPTED\") return t(\"workflow.stage.INTERRUPTED\");\n if (attempt.status === \"CANCELLED\") return t(\"workflow.stage.CANCELLED\");\n if (attempt.status === \"SUCCEEDED\") return t(\"workflow.stage.SUCCEEDED\");\n return t(\"workflow.stage.other\");\n};\n\n// A total Record over the contract's own union, matching `stateTones` and `pipelineStatusTones`\n// below: a status added to `stageAttemptStatusSchema` without a tone here must fail to compile\n// rather than silently fall through, since the attempt header (D5) is the one place on screen that\n// names which attempt the sessions list belongs to.\nconst stageAttemptStatusTones: Record<StageAttemptStatus, StatusTone> = {\n PENDING: \"queued\",\n QUEUED: \"queued\",\n RUNNING: \"running\",\n WAITING_HUMAN: \"waiting\",\n SOFT_PAUSED: \"paused\",\n HARD_PAUSED: \"waiting\",\n SUCCEEDED: \"complete\",\n FAILED: \"paused\",\n CANCELLED: \"paused\",\n INTERRUPTED: \"paused\",\n RECOVERING: \"running\",\n STALE: \"waiting\",\n};\n\nconst pipelineStatusLabelKeys: Record<PipelineRun[\"status\"], TranslationKey> = {\n RUNNING: \"workflow.status.RUNNING\",\n WAITING_HUMAN: \"workflow.status.WAITING_HUMAN\",\n SOFT_PAUSED: \"workflow.status.SOFT_PAUSED\",\n HARD_PAUSED: \"workflow.status.HARD_PAUSED\",\n INTERRUPTED: \"workflow.status.INTERRUPTED\",\n SUCCEEDED: \"workflow.status.SUCCEEDED\",\n FAILED: \"workflow.status.FAILED\",\n CANCELLED: \"workflow.status.CANCELLED\",\n};\n\nconst pipelineStatusTones: Record<PipelineRun[\"status\"], StatusTone> = {\n RUNNING: \"running\",\n WAITING_HUMAN: \"waiting\",\n SOFT_PAUSED: \"paused\",\n HARD_PAUSED: \"waiting\",\n INTERRUPTED: \"paused\",\n SUCCEEDED: \"complete\",\n FAILED: \"paused\",\n CANCELLED: \"paused\",\n};\n\nconst acceptanceStatusLabelKeys: Record<AcceptancePackage[\"status\"], TranslationKey> = {\n PENDING: \"acceptance.status.PENDING\",\n ACCEPTED: \"acceptance.status.ACCEPTED\",\n RETURNED: \"acceptance.status.RETURNED\",\n REJECTED: \"acceptance.status.REJECTED\",\n};\n\nconst acceptanceStatusTones: Record<AcceptancePackage[\"status\"], StatusTone> = {\n PENDING: \"waiting\",\n ACCEPTED: \"complete\",\n RETURNED: \"paused\",\n REJECTED: \"paused\",\n};\n\nconst eventPresentation = (event: DomainEvent, t: Translator): Omit<TimelineEventProps, \"time\"> => {\n switch (event.type) {\n case \"WORK_ITEM_CREATED\":\n return {\n detail: t(\"event.createdDetail\"),\n icon: \"add\",\n label: t(\"event.created\"),\n tone: \"success\",\n };\n case \"WORK_ITEM_UPDATED\":\n return {\n detail: t(\"event.updatedDetail\", {\n fields: event.data.changedFields.map((field) => t(changedFieldLabelKeys[field])).join(\", \"),\n }),\n icon: \"settings\",\n label: t(\"event.updated\"),\n };\n case \"WORK_ITEM_STATE_CHANGED\":\n return {\n detail: t(\"event.stateChangedDetail\", {\n from: stateLabel(event.data.previousState, t),\n to: stateLabel(event.data.workItem.state, t),\n }),\n icon: event.data.workItem.state === \"BLOCKED\" ? \"pause\" : \"play\",\n label: t(\"event.stateChanged\"),\n tone: event.data.workItem.state === \"BLOCKED\" ? \"warning\" : \"accent\",\n };\n case \"PROJECT_REGISTERED\":\n return { detail: event.data.project.name, icon: \"projects\", label: t(\"event.projectRegistered\") };\n case \"PIPELINE_STARTED\":\n return {\n detail: t(\"event.pipelineStartedDetail\", {\n stage: t(stageLabelKeys[event.data.stageAttempt.stage]),\n }),\n icon: \"play\",\n label: t(\"event.pipelineStarted\"),\n tone: \"accent\",\n };\n case \"STAGE_ATTEMPT_CHANGED\":\n return {\n detail: t(\"event.stageChangedDetail\", {\n stage: t(stageLabelKeys[event.data.stageAttempt.stage]),\n status: stageAttemptStatusLabel(event.data.stageAttempt, t),\n }),\n icon: event.data.stageAttempt.status === \"SUCCEEDED\" ? \"check\" : \"clock\",\n label: t(\"event.stageChanged\"),\n tone: event.data.stageAttempt.status === \"SUCCEEDED\" ? \"success\" : \"accent\",\n };\n case \"HUMAN_REQUEST_OPENED\":\n return {\n detail: t(\"event.humanRequestOpenedDetail\", { title: event.data.request.title }),\n icon: \"question\",\n label: t(\"event.humanRequestOpened\"),\n tone: \"warning\",\n };\n case \"HUMAN_REQUEST_RESOLVED\":\n return {\n detail: t(\"event.humanRequestResolvedDetail\"),\n icon: \"check\",\n label: t(\"event.humanRequestResolved\"),\n tone: \"success\",\n };\n case \"USAGE_RECORDED\":\n return {\n detail: t(\"event.usageRecordedDetail\", {\n amount: event.data.usageRecord.amount,\n total: event.data.cumulativeAmount,\n }),\n icon: \"clock\",\n label: t(\"event.usageRecorded\"),\n };\n case \"BUDGET_THRESHOLD_REACHED\":\n return {\n detail: t(\"event.budgetThresholdDetail\", {\n threshold: Math.round(event.data.threshold * 100),\n total: event.data.cumulativeAmount,\n }),\n icon: \"filter\",\n label: t(\"event.budgetThreshold\"),\n tone: event.data.threshold >= 1 ? \"warning\" : \"accent\",\n };\n case \"PIPELINE_PAUSED\":\n return {\n detail: t(\"event.pipelinePausedDetail\", {\n kind: event.data.kind,\n stage: t(stageLabelKeys[event.data.stageAttempt.stage]),\n }),\n icon: \"pause\",\n label: t(\"event.pipelinePaused\"),\n tone: \"warning\",\n };\n case \"PIPELINE_RESUMED\":\n return {\n detail: t(\"event.pipelineResumedDetail\", {\n stage: t(stageLabelKeys[event.data.stageAttempt.stage]),\n }),\n icon: \"play\",\n label: t(\"event.pipelineResumed\"),\n tone: \"accent\",\n };\n case \"PIPELINE_CANCELLED\":\n return {\n detail: t(\"event.pipelineCancelledDetail\", {\n stage: t(stageLabelKeys[event.data.stageAttempt.stage]),\n }),\n icon: \"pause\",\n label: t(\"event.pipelineCancelled\"),\n tone: \"warning\",\n };\n case \"BUDGET_OVERRIDE_APPROVED\":\n return {\n detail: t(\"event.budgetOverrideDetail\", {\n revision: event.data.budgetPolicy.revision,\n limit: event.data.budgetPolicy.maxEstimatedTokens,\n }),\n icon: \"settings\",\n label: t(\"event.budgetOverride\"),\n tone: \"accent\",\n };\n case \"RECOVERY_REPORT_CREATED\":\n return {\n detail: t(\"event.recoveryCreatedDetail\", {\n stage: t(stageLabelKeys[event.data.stageAttempt.stage]),\n }),\n icon: \"clock\",\n label: t(\"event.recoveryCreated\"),\n tone: \"warning\",\n };\n case \"EVIDENCE_ARTIFACT_RECORDED\":\n return {\n detail: t(\"event.evidenceRecordedDetail\", { title: event.data.artifact.title }),\n icon: \"check\",\n label: t(\"event.evidenceRecorded\"),\n tone: \"success\",\n };\n case \"ACCEPTANCE_REQUESTED\":\n return {\n detail: t(\"event.acceptanceRequestedDetail\"),\n icon: \"question\",\n label: t(\"event.acceptanceRequested\"),\n tone: \"warning\",\n };\n case \"ACCEPTANCE_RESOLVED\":\n return {\n detail: t(\"event.acceptanceResolvedDetail\", { action: event.data.action }),\n icon: event.data.action === \"ACCEPT\" ? \"check\" : \"pause\",\n label: t(\"event.acceptanceResolved\"),\n tone: event.data.action === \"ACCEPT\" ? \"success\" : \"warning\",\n };\n case \"PIPELINE_COMPLETED\":\n return {\n detail: t(\"event.pipelineCompletedDetail\"),\n icon: \"check\",\n label: t(\"event.pipelineCompleted\"),\n tone: \"success\",\n };\n case \"PROVIDER_SESSION_STARTED\":\n return {\n detail: t(\"event.providerSessionStartedDetail\", { ordinal: event.data.session.ordinal }),\n icon: \"sessions\",\n label: t(\"event.providerSessionStarted\"),\n tone: \"accent\",\n };\n case \"CHECKPOINT_PUBLISHED\":\n return {\n detail: t(\"event.checkpointPublishedDetail\", { summary: event.data.checkpoint.summary }),\n icon: \"check\",\n label: t(\"event.checkpointPublished\"),\n tone: \"success\",\n };\n case \"CONTEXT_HANDOFF_REQUESTED\":\n return {\n detail: t(\"event.contextHandoffRequestedDetail\", { ordinal: event.data.session.ordinal }),\n icon: \"clock\",\n label: t(\"event.contextHandoffRequested\"),\n tone: \"warning\",\n };\n case \"PROVIDER_SESSION_ENDED\":\n return {\n detail: t(\"event.providerSessionEndedDetail\", { reason: event.data.session.endReason ?? \"\" }),\n icon: \"sessions\",\n label: t(\"event.providerSessionEnded\"),\n tone: event.data.session.endReason === \"COMPLETED\" ? \"success\" : \"neutral\",\n };\n case \"CONTEXT_FLOOR_EXCEEDED\":\n return {\n detail: t(\"event.contextFloorExceededDetail\", {\n ordinal: event.data.sessionOrdinal,\n requiredBytes: event.data.requiredBytes,\n budgetBytes: event.data.budgetBytes,\n }),\n icon: \"pause\",\n label: t(\"event.contextFloorExceeded\"),\n tone: \"warning\",\n };\n case \"WORK_ITEM_WORKSPACE_CREATED\":\n return {\n detail: t(\"event.workspaceCreatedDetail\", { branch: event.data.workspace.branch }),\n icon: \"branch\",\n label: t(\"event.workspaceCreated\"),\n tone: \"success\",\n };\n case \"WORK_ITEM_WORKSPACE_ORPHANED\":\n return {\n detail: t(\"event.workspaceOrphanedDetail\"),\n icon: \"warning\",\n label: t(\"event.workspaceOrphaned\"),\n tone: \"warning\",\n };\n }\n};\n\nconst eventTime = (occurredAt: string, locale: Locale): string =>\n new Intl.DateTimeFormat(locale === \"ru\" ? \"ru-RU\" : \"en-US\", {\n hour: \"2-digit\",\n minute: \"2-digit\",\n }).format(new Date(occurredAt));\n\nconst WorkItemButton = ({\n item,\n onSelect,\n selected,\n}: {\n item: WorkItem;\n onSelect: (id: string) => void;\n selected: boolean;\n}): React.JSX.Element => {\n const { t } = useI18n();\n const buttonRef = useRef<HTMLButtonElement>(null);\n\n // The board scrolls horizontally, so a selected task can sit in an off-screen column - including\n // after a workflow moves it there. Reveal it instead of leaving the visible columns looking empty.\n useEffect(() => {\n if (!selected) return;\n buttonRef.current?.scrollIntoView({ block: \"nearest\", inline: \"nearest\" });\n }, [selected]);\n\n return (\n <button\n aria-label={item.title}\n aria-pressed={selected}\n className=\"task-card-button\"\n onClick={() => {\n onSelect(item.id);\n }}\n ref={buttonRef}\n type=\"button\"\n >\n <TaskCard\n agent={t(typeLabelKeys[item.type])}\n badge={{ label: t(priorityLabelKeys[item.priority]), tone: priorityTone(item.priority) }}\n description={item.description}\n id={displayWorkItemId(item.id)}\n meta={stateLabel(item.state, t)}\n selected={selected}\n title={item.title}\n />\n </button>\n );\n};\n\nconst criteriaFromText = (value: string): readonly string[] =>\n value\n .split(\"\\n\")\n .map((criterion) => criterion.trim())\n .filter(Boolean);\n\nconst TaskEditDialog = ({ item }: { item: WorkItem }): React.JSX.Element => {\n const { t } = useI18n();\n const updateMutation = useUpdateWorkItem();\n const formRef = useRef<HTMLFormElement>(null);\n const [open, setOpen] = useState(false);\n const [title, setTitle] = useState(item.title);\n const [description, setDescription] = useState(item.description);\n const [priority, setPriority] = useState(item.priority);\n const [risk, setRisk] = useState(item.risk);\n const [criteriaText, setCriteriaText] = useState(item.acceptanceCriteria.join(\"\\n\"));\n const acceptanceCriteria = criteriaFromText(criteriaText);\n const criteriaValid =\n acceptanceCriteria.length <= 50 && acceptanceCriteria.every((criterion) => criterion.length <= 500);\n const changed =\n title.trim() !== item.title ||\n description.trim() !== item.description ||\n priority !== item.priority ||\n risk !== item.risk ||\n acceptanceCriteria.length !== item.acceptanceCriteria.length ||\n acceptanceCriteria.some((criterion, index) => criterion !== item.acceptanceCriteria[index]);\n\n const resetDraft = (): void => {\n setTitle(item.title);\n setDescription(item.description);\n setPriority(item.priority);\n setRisk(item.risk);\n setCriteriaText(item.acceptanceCriteria.join(\"\\n\"));\n updateMutation.reset();\n };\n\n const submit = (event: SyntheticEvent<HTMLFormElement, SubmitEvent>): void => {\n event.preventDefault();\n const normalizedTitle = title.trim();\n const normalizedDescription = description.trim();\n if (!normalizedTitle || !criteriaValid || !changed) return;\n\n const patch = {\n ...(normalizedTitle === item.title ? {} : { title: normalizedTitle }),\n ...(normalizedDescription === item.description ? {} : { description: normalizedDescription }),\n ...(priority === item.priority ? {} : { priority }),\n ...(risk === item.risk ? {} : { risk }),\n ...(acceptanceCriteria.length === item.acceptanceCriteria.length &&\n acceptanceCriteria.every((criterion, index) => criterion === item.acceptanceCriteria[index])\n ? {}\n : { acceptanceCriteria: [...acceptanceCriteria] }),\n };\n\n updateMutation.mutate(\n { patch, workItem: item },\n {\n onSuccess: () => {\n setOpen(false);\n },\n },\n );\n };\n\n return (\n <DialogSurface\n closeLabel={t(\"action.closeDialog\")}\n description={t(\"task.edit.description\")}\n footer={\n <>\n <Button\n disabled={updateMutation.isPending}\n onClick={() => {\n setOpen(false);\n resetDraft();\n }}\n >\n {t(\"action.cancel\")}\n </Button>\n <Button\n disabled={!title.trim() || !criteriaValid || !changed}\n loading={updateMutation.isPending}\n onClick={() => {\n formRef.current?.requestSubmit();\n }}\n type=\"button\"\n variant=\"primary\"\n >\n {t(\"task.edit.submit\")}\n </Button>\n </>\n }\n onOpenChange={(nextOpen) => {\n if (nextOpen) resetDraft();\n setOpen(nextOpen);\n }}\n open={open}\n size=\"lg\"\n title={t(\"task.edit\")}\n trigger={<IconButton label={t(\"task.edit\")} name=\"edit\" size=\"sm\" variant=\"surface\" />}\n triggerTooltip={t(\"task.edit\")}\n >\n <form className=\"edit-task-form\" onSubmit={submit} ref={formRef}>\n {updateMutation.error ? (\n <LocalConnectionRecovery\n error={updateMutation.error}\n onRetry={() => {\n formRef.current?.requestSubmit();\n }}\n retrying={updateMutation.isPending}\n />\n ) : null}\n <Field htmlFor=\"edit-task-title\" label={t(\"task.create.title\")} required>\n <TextField\n autoFocus\n id=\"edit-task-title\"\n maxLength={200}\n onChange={(event) => {\n setTitle(event.currentTarget.value);\n }}\n required\n value={title}\n />\n </Field>\n <Field htmlFor=\"edit-task-description\" label={t(\"task.create.brief\")}>\n <Textarea\n id=\"edit-task-description\"\n maxLength={20_000}\n onChange={(event) => {\n setDescription(event.currentTarget.value);\n }}\n rows={5}\n value={description}\n />\n </Field>\n <div className=\"edit-task-form__row\">\n <Field htmlFor=\"edit-task-priority\" label={t(\"task.priority\")}>\n <SelectControl\n ariaLabel={t(\"task.priority\")}\n id=\"edit-task-priority\"\n onValueChange={(value) => {\n setPriority(prioritySchema.parse(value));\n }}\n options={(Object.keys(priorityLabelKeys) as WorkItem[\"priority\"][]).map((value) => ({\n label: t(priorityLabelKeys[value]),\n value,\n }))}\n value={priority}\n />\n </Field>\n <Field htmlFor=\"edit-task-risk\" label={t(\"task.risk\")}>\n <SelectControl\n ariaLabel={t(\"task.risk\")}\n id=\"edit-task-risk\"\n onValueChange={(value) => {\n setRisk(riskSchema.parse(value));\n }}\n options={(Object.keys(riskLabelKeys) as WorkItem[\"risk\"][]).map((value) => ({\n label: t(riskLabelKeys[value]),\n value,\n }))}\n value={risk}\n />\n </Field>\n </div>\n <Field\n description={t(\"task.edit.criteriaDescription\")}\n htmlFor=\"edit-work-item-criteria\"\n label={t(\"task.acceptanceCriteria\")}\n {...(criteriaValid ? {} : { error: t(\"task.edit.criteriaError\") })}\n >\n <Textarea\n aria-describedby=\"edit-work-item-criteria-description\"\n id=\"edit-work-item-criteria\"\n invalid={!criteriaValid}\n onChange={(event) => {\n setCriteriaText(event.currentTarget.value);\n }}\n rows={5}\n value={criteriaText}\n />\n </Field>\n </form>\n </DialogSurface>\n );\n};\n\nconst HumanRequestPanel = ({ request }: { request: HumanRequest }): React.JSX.Element => {\n const { t } = useI18n();\n const answerMutation = useAnswerHumanRequest();\n const [selection, setSelection] = useState(\"\");\n const [otherText, setOtherText] = useState(\"\");\n const otherSelected = selection === \"__other__\";\n const canSubmit = otherSelected ? otherText.trim().length > 0 : selection.length > 0;\n\n const submit = (): void => {\n if (!canSubmit) return;\n answerMutation.mutate({\n request,\n answer: otherSelected\n ? { type: \"OTHER\", text: otherText.trim() }\n : { type: \"OPTION\", optionIds: [selection] },\n });\n };\n\n return (\n <div className=\"human-request-card\">\n <div className=\"human-request-card__eyebrow\">\n <Icon name=\"question\" size={13} />\n <span>{t(\"humanRequest.blocking\")}</span>\n </div>\n <h3>{request.title}</h3>\n <p>{request.context}</p>\n {request.recommendation ? (\n <div className=\"human-request-card__recommendation\">\n <strong>{t(\"humanRequest.recommendation\")}</strong>\n <span>{request.recommendation}</span>\n </div>\n ) : null}\n <RadioGroup\n aria-label={request.title}\n onValueChange={setSelection}\n options={[\n ...request.options.map((option) => ({\n value: option.id,\n label: option.recommended ? `${option.label} · ${t(\"humanRequest.recommended\")}` : option.label,\n description: option.consequence,\n })),\n ...(request.allowOther ? [{ value: \"__other__\", label: t(\"humanRequest.other\") }] : []),\n ]}\n value={selection}\n />\n {otherSelected ? (\n <TextField\n aria-label={t(\"humanRequest.other\")}\n autoFocus\n maxLength={2_000}\n onChange={(event) => {\n setOtherText(event.currentTarget.value);\n }}\n placeholder={t(\"humanRequest.otherPlaceholder\")}\n value={otherText}\n />\n ) : null}\n {!canSubmit && selection ? (\n <span className=\"human-request-card__hint\">{t(\"humanRequest.chooseAnswer\")}</span>\n ) : null}\n {answerMutation.error ? (\n <LocalConnectionRecovery\n error={answerMutation.error}\n onRetry={submit}\n retrying={answerMutation.isPending}\n />\n ) : null}\n <Button disabled={!canSubmit} loading={answerMutation.isPending} onClick={submit} variant=\"primary\">\n {t(\"humanRequest.answerResume\")}\n </Button>\n </div>\n );\n};\n\nconst AcceptancePanel = ({\n acceptancePackage,\n artifacts,\n item,\n run,\n}: {\n acceptancePackage: AcceptancePackage;\n artifacts: readonly EvidenceArtifact[];\n item: WorkItem;\n run: PipelineRun;\n}): React.JSX.Element => {\n const { t } = useI18n();\n const resolveMutation = useResolveAcceptance();\n const [lastAction, setLastAction] = useState<AcceptanceAction | null>(null);\n const resolve = (action: AcceptanceAction): void => {\n setLastAction(action);\n resolveMutation.mutate({ acceptancePackage, action, run, workItem: item });\n };\n\n return (\n <div className=\"acceptance-package\">\n <div className=\"acceptance-package__heading\">\n <div>\n <span>{t(\"acceptance.eyebrow\")}</span>\n <h3>{t(\"acceptance.title\")}</h3>\n </div>\n <Status\n label={t(acceptanceStatusLabelKeys[acceptancePackage.status])}\n tone={acceptanceStatusTones[acceptancePackage.status]}\n />\n </div>\n <p>{acceptancePackage.releaseNote}</p>\n\n <div className=\"acceptance-evidence\" aria-label={t(\"acceptance.evidence\")}>\n {artifacts.map((artifact) => (\n <article key={artifact.id}>\n <div>\n <Icon name=\"check\" size={13} />\n <strong>\n {artifact.kind === \"REVIEW_REPORT\"\n ? t(\"acceptance.reviewEvidence\")\n : t(\"acceptance.qaEvidence\")}\n </strong>\n </div>\n <span>{artifact.summary}</span>\n <small>{t(\"acceptance.checks\", { count: artifact.checks.length })}</small>\n </article>\n ))}\n </div>\n\n <div className=\"acceptance-matrix\">\n <strong>{t(\"acceptance.matrix\")}</strong>\n {acceptancePackage.criteria.length > 0 ? (\n <ol>\n {acceptancePackage.criteria.map((criterion) => (\n <li key={criterion.criterion}>\n <div>\n <Icon name=\"check\" size={13} />\n <strong>{criterion.criterion}</strong>\n </div>\n <span>{criterion.verification}</span>\n </li>\n ))}\n </ol>\n ) : (\n <span>{t(\"acceptance.noCriteria\")}</span>\n )}\n </div>\n\n {resolveMutation.error ? (\n <LocalConnectionRecovery\n error={resolveMutation.error}\n onRetry={() => {\n if (lastAction) resolve(lastAction);\n }}\n retrying={resolveMutation.isPending}\n />\n ) : null}\n {acceptancePackage.status === \"PENDING\" ? (\n <div className=\"acceptance-package__actions\">\n <Button\n disabled={resolveMutation.isPending}\n loading={resolveMutation.isPending && lastAction === \"ACCEPT\"}\n onClick={() => {\n resolve(\"ACCEPT\");\n }}\n variant=\"primary\"\n >\n {t(\"acceptance.accept\")}\n </Button>\n <Button\n disabled={resolveMutation.isPending}\n loading={resolveMutation.isPending && lastAction === \"RETURN_TO_WORK\"}\n onClick={() => {\n resolve(\"RETURN_TO_WORK\");\n }}\n >\n {t(\"acceptance.return\")}\n </Button>\n <Button\n disabled={resolveMutation.isPending}\n loading={resolveMutation.isPending && lastAction === \"REJECT\"}\n onClick={() => {\n resolve(\"REJECT\");\n }}\n >\n {t(\"acceptance.reject\")}\n </Button>\n </div>\n ) : null}\n </div>\n );\n};\n\n// The skeleton is shared by the workflow section and by the whole-inspector loading state; only the\n// outermost loading container announces itself, so the label - and with it the live region - is optional.\nconst WorkflowSkeleton = ({ label }: { label?: string }): React.JSX.Element => (\n <div\n aria-label={label}\n className=\"inspector-workflow-skeleton\"\n role={label === undefined ? undefined : \"status\"}\n >\n <div className=\"inspector-workflow-skeleton__status\">\n <Skeleton width=\"42%\" />\n <Skeleton width=\"68px\" />\n </div>\n <div className=\"inspector-workflow-skeleton__panel\">\n <div>\n <Skeleton width=\"48%\" />\n <Skeleton width=\"54px\" />\n </div>\n <Skeleton className=\"inspector-workflow-skeleton__meter\" width=\"100%\" />\n <Skeleton width=\"36%\" />\n </div>\n <div className=\"inspector-workflow-skeleton__steps\">\n <Skeleton width=\"58%\" />\n <Skeleton width=\"44%\" />\n </div>\n </div>\n);\n\n// Spec D5's accepted price: splitting the attempt from its execution unit means a healthy long\n// stage no longer looks like a series of failures, but only if the cockpit shows the nesting it\n// introduced. `session.status === \"RUNNING\"` is checked first because a running session always\n// carries a null endReason, which the switch below still has to type-check against.\nconst sessionStatusPresentation = (\n session: ProviderSession,\n t: Translator,\n): { label: string; tone: StatusTone } => {\n if (session.status === \"RUNNING\") return { label: t(\"workflow.sessions.status.RUNNING\"), tone: \"running\" };\n switch (session.endReason) {\n case \"COMPLETED\":\n return { label: t(\"workflow.sessions.status.COMPLETED\"), tone: \"complete\" };\n case \"HANDOFF\":\n return { label: t(\"workflow.sessions.status.HANDOFF\"), tone: \"waiting\" };\n case \"CONTEXT_EXHAUSTED\":\n return { label: t(\"workflow.sessions.status.CONTEXT_EXHAUSTED\"), tone: \"paused\" };\n case \"INTERRUPTED\":\n return { label: t(\"workflow.sessions.status.INTERRUPTED\"), tone: \"paused\" };\n case \"CANCELLED\":\n return { label: t(\"workflow.sessions.status.CANCELLED\"), tone: \"queued\" };\n case null:\n return { label: t(\"workflow.stage.other\"), tone: \"queued\" };\n }\n};\n\n// Spec §8: a checkpoint is provider output Loomrail feeds into the next session's context, and it\n// mitigates a High-rated threat only if the owner can read what is actually being carried forward\n// -- so every list renders here, not just a summary line, and an empty list is left out rather than\n// shown as a hollow heading.\nconst checkpointGroups = (checkpoint: Checkpoint, t: Translator): readonly CheckpointGroup[] => [\n { label: t(\"workflow.checkpoints.completed\"), items: checkpoint.completed },\n { label: t(\"workflow.checkpoints.remaining\"), items: checkpoint.remaining },\n { label: t(\"workflow.checkpoints.deadEnds\"), items: checkpoint.deadEnds },\n { label: t(\"workflow.checkpoints.openQuestions\"), items: checkpoint.openQuestions },\n];\n\n/**\n * The sessions inside the current stage attempt (spec §D5), with the highest window occupancy each\n * session reached, whether a handoff was requested, and the full text of every checkpoint it\n * published.\n * Renders nothing while there is no attempt to nest sessions under, or once it has none yet -- a\n * brand-new attempt has not started its first session, and an empty \"Sessions\" heading would just\n * be noise.\n */\nconst AttemptSessionsPanel = ({ attempt }: { attempt: StageAttempt }): React.JSX.Element | null => {\n const { locale, t } = useI18n();\n const sessionsQuery = useStageAttemptSessions(attempt.id);\n const capabilitiesQuery = useProviderCapabilities();\n const sessions = sessionsQuery.data?.sessions ?? [];\n const checkpoints = sessionsQuery.data?.checkpoints ?? [];\n const peakContextWindowUsage = sessionsQuery.data?.peakContextWindowUsage ?? {};\n\n if (sessions.length === 0) return null;\n\n // The single most recently published checkpoint across the whole attempt -- the one that would\n // feed the next session's context right now -- opens by default; every earlier one stays\n // collapsed behind its own summary rather than crowding the panel.\n const mostRecentCheckpointId = checkpoints.reduce<{ id: string; createdAt: string } | null>(\n (latest, checkpoint) =>\n latest === null || checkpoint.createdAt > latest.createdAt\n ? { id: checkpoint.id, createdAt: checkpoint.createdAt }\n : latest,\n null,\n )?.id;\n\n const sessionViewModels: ProviderSessionViewModel[] = [...sessions]\n .sort((a, b) => a.ordinal - b.ordinal)\n .map((session) => {\n const presentation = sessionStatusPresentation(session, t);\n const usage = peakContextWindowUsage[session.id];\n const occupancyPercent = usage ? Math.round((usage.usedTokens / usage.windowTokens) * 100) : undefined;\n const sessionCheckpoints: CheckpointViewModel[] = checkpoints\n .filter((checkpoint) => checkpoint.providerSessionId === session.id)\n .sort((a, b) => a.ordinal - b.ordinal)\n .map((checkpoint) => ({\n id: checkpoint.id,\n summary: checkpoint.summary,\n timeLabel: eventTime(checkpoint.createdAt, locale),\n defaultOpen: checkpoint.id === mostRecentCheckpointId,\n groups: checkpointGroups(checkpoint, t),\n }));\n\n return {\n id: session.id,\n ordinal: session.ordinal,\n ariaLabel: t(\"workflow.sessions.ordinal\", { ordinal: session.ordinal }),\n statusLabel: presentation.label,\n tone: presentation.tone,\n checkpoints: sessionCheckpoints,\n // exactOptionalPropertyTypes: an optional field left undefined must be omitted, not set to\n // undefined, so each one is spread in only when it has a real value.\n ...(session.handoffRequestedAt !== null\n ? { handoffRequestedLabel: t(\"workflow.sessions.handoffRequested\") }\n : {}),\n // Spec §4.3 and §5.2 make `usageQuality` the thing that separates a measured occupancy from\n // a guessed one; dropping it here rendered a measured 92% and an estimated 92% identically.\n //\n // Occupancy is saved on every report, not only on the one that crosses the threshold, so\n // the number no longer implies a handoff and the label must not claim one -- a session\n // still running at 40% would have read as having handed off. A session that did ask for a\n // handoff stopped reporting at that moment, so its peak really is the reading at handoff\n // and keeps saying so; for every other session the honest thing to name is the peak.\n // e2e/attempt-nesting.spec.ts renders both branches.\n ...(occupancyPercent === undefined || usage === undefined\n ? {}\n : {\n occupancyPercent,\n occupancyLabel: t(\n session.handoffRequestedAt === null\n ? \"workflow.sessions.occupancyPeak\"\n : \"workflow.sessions.occupancyAtHandoff\",\n { percent: occupancyPercent },\n ),\n occupancyQualityLabel: t(usageQualityLabelKeys[usage.quality]),\n }),\n ...(sessionCheckpoints.length === 0\n ? { emptyCheckpointsLabel: t(\"workflow.checkpoints.empty\") }\n : {}),\n };\n });\n\n const attemptHeader: ProviderSessionTimelineAttempt = {\n heading: t(\"workflow.sessions.attemptHeading\", { attempt: attempt.attempt }),\n statusLabel: stageAttemptStatusLabel(attempt, t),\n tone: stageAttemptStatusTones[attempt.status],\n };\n\n return (\n <ProviderSessionTimeline\n attempt={attemptHeader}\n {...(capabilitiesQuery.data?.checkpointOnRequest === false\n ? { note: t(\"workflow.sessions.noCheckpointOnRequest\") }\n : {})}\n sessions={sessionViewModels}\n title={t(\"workflow.sessions.title\")}\n />\n );\n};\n\nconst workspaceStatusLabelKeys: Record<WorkItemWorkspaceStatus, TranslationKey> = {\n READY: \"workspace.status.READY\",\n ORPHANED: \"workspace.status.ORPHANED\",\n REMOVED: \"workspace.status.REMOVED\",\n};\n\nconst workspaceStatusTones: Record<WorkItemWorkspaceStatus, StatusTone> = {\n READY: \"ready\",\n ORPHANED: \"paused\",\n REMOVED: \"queued\",\n};\n\n/**\n * How much of the base commit the card prints.\n *\n * Twelve hex characters, not forty and not seven. The owner's use for this value is pasting it into\n * `git show`, and git resolves any unambiguous prefix, so the question is only how long a prefix\n * stays unambiguous. Seven -- git's own `--oneline` default -- collides in large repositories;\n * twelve is what `core.abbrev=auto` grows towards well past a million objects. The full forty\n * characters would wrap to a second line in a 320px inspector column and buy nothing, since a\n * prefix and the full id resolve identically.\n *\n * The complete sha is still on the element's `title`, so nothing is hidden -- only unprinted.\n */\nconst baseCommitDisplayLength = 12;\n\n/**\n * Where this work item's agent writes: the repository, the branch, the base commit it was cut from,\n * and the worktree path.\n *\n * Returns null rather than an empty panel when the item has no workspace. A prose-only stage and an\n * item before its first code stage both genuinely have none, and headings standing over blanks read\n * as a load that failed rather than as an absence -- so the section itself lives in here, not\n * around the call site.\n *\n * The paths are deliberately not in the `RunSummary` grid the overview above uses. That grid gives\n * a value roughly half the inspector's width and clips what does not fit, which for the one field\n * the owner is here to copy -- the worktree path -- would mean an ellipsis where an actionable\n * directory should be. They get full-width rows that wrap instead, so the whole path is on screen\n * and selectable in one drag.\n */\nconst WorkspacePanel = ({ item }: { item: WorkItem }): React.JSX.Element | null => {\n const { t } = useI18n();\n const { projects } = useWorkspace();\n // The published shape, not the stored one: the route deliberately does not send `leaseHolder`, and\n // the card has no use for it.\n const workspace: PublishedWorkItemWorkspace | null = useWorkItemWorkspace(item.id).data?.workspace ?? null;\n\n if (!workspace) return null;\n\n // The Project names the repository the branch actually lives in -- the worktree is a checkout of\n // it, not a repository of its own -- which is where an owner goes to delete the branch or merge\n // it. Read from the Project list the app already holds rather than added to the workspace\n // response, since the workspace row records no repository path of its own.\n const project = projects.find((candidate) => candidate.id === item.projectId) ?? null;\n\n return (\n <InspectorSection title={t(\"workspace.title\")}>\n <div className=\"workspace-identity\">\n <RunSummary\n properties={[\n {\n label: t(\"workspace.state\"),\n value: (\n <Status\n label={t(workspaceStatusLabelKeys[workspace.status])}\n tone={workspaceStatusTones[workspace.status]}\n />\n ),\n },\n {\n label: t(\"workspace.baseCommit\"),\n value:\n workspace.baseCommit === null ? (\n t(\"workspace.baseCommit.none\")\n ) : (\n <code className=\"workspace-identity__sha\" title={workspace.baseCommit}>\n {workspace.baseCommit.slice(0, baseCommitDisplayLength)}\n </code>\n ),\n },\n ]}\n />\n <dl className=\"workspace-identity__locations\">\n {project ? (\n <div>\n <dt>{t(\"workspace.repository\")}</dt>\n <dd>{project.repositoryPath}</dd>\n </div>\n ) : null}\n <div>\n <dt>{t(\"workspace.branch\")}</dt>\n <dd>{workspace.branch}</dd>\n </div>\n <div>\n <dt>{t(\"workspace.worktree\")}</dt>\n <dd>{workspace.worktreePath}</dd>\n </div>\n </dl>\n {workspace.status === \"READY\" ? null : (\n // No action offered, because there is none: ORPHANED is terminal -- nothing in Loomrail\n // returns a workspace to READY (session-loop.ts, workspaceNotReadyRefusal) -- and a\n // button that cannot work is worse than the plain fact.\n <p className=\"workspace-identity__note\" role=\"status\">\n {t(\"workspace.notReady\")}\n </p>\n )}\n <p className=\"inspector-copy\">{t(\"workspace.uncommitted\")}</p>\n </div>\n </InspectorSection>\n );\n};\n\nconst WorkflowPanel = ({ item }: { item: WorkItem }): React.JSX.Element => {\n const { t } = useI18n();\n const workflowQuery = useWorkItemWorkflow(item.id);\n const startMutation = useStartMockPipeline();\n const controlMutation = usePipelineControl();\n const overrideMutation = useApproveBudgetOverride();\n const [lastAction, setLastAction] = useState<\"pause\" | \"resume\" | \"cancel\" | \"override\" | null>(null);\n const snapshot = workflowQuery.data;\n const openRequest =\n snapshot?.humanRequests.find(\n ({ id, status }) => status === \"OPEN\" && id !== snapshot.acceptancePackage?.humanRequestId,\n ) ?? null;\n\n if (workflowQuery.isPending) {\n return <WorkflowSkeleton label={t(\"workflow.loading\")} />;\n }\n\n if (!snapshot?.run) {\n return (\n <div className=\"workflow-start\">\n <p className=\"inspector-copy\">\n {item.state === \"READY\" ? t(\"workflow.startDescription\") : t(\"workflow.readyRequired\")}\n </p>\n {startMutation.error ? (\n <LocalConnectionRecovery\n error={startMutation.error}\n onRetry={() => {\n startMutation.mutate(item);\n }}\n retrying={startMutation.isPending}\n />\n ) : null}\n <Button\n disabled={item.state !== \"READY\"}\n loading={startMutation.isPending}\n onClick={() => {\n startMutation.mutate(item);\n }}\n variant=\"primary\"\n >\n {t(\"workflow.start\")}\n </Button>\n </div>\n );\n }\n\n const run = snapshot.run;\n const currentAttempt =\n snapshot.stageAttempts.find((attempt) => attempt.id === run.currentStageAttemptId) ?? null;\n const budgetPolicy = snapshot.budgetPolicies.at(-1) ?? null;\n const used = snapshot.usageRecords.reduce((total, record) => total + record.amount, 0);\n const budgetPercent = budgetPolicy\n ? Math.min(100, Math.round((used / budgetPolicy.maxEstimatedTokens) * 100))\n : 0;\n const overrideLimit = budgetPolicy ? Math.max(budgetPolicy.maxEstimatedTokens * 2, used + 100) : used + 100;\n const controlPending = controlMutation.isPending || overrideMutation.isPending;\n const runControl = (action: \"pause\" | \"resume\" | \"cancel\"): void => {\n controlMutation.reset();\n overrideMutation.reset();\n setLastAction(action);\n controlMutation.mutate({ action, run, workItem: item });\n };\n const approveOverride = (): void => {\n controlMutation.reset();\n overrideMutation.reset();\n setLastAction(\"override\");\n overrideMutation.mutate({ maxEstimatedTokens: overrideLimit, run, workItem: item });\n };\n\n return (\n <div className=\"workflow-panel\">\n <div className=\"workflow-panel__status\">\n <span>{t(\"workflow.mockName\")}</span>\n <Status\n label={\n snapshot.run.status === \"HARD_PAUSED\"\n ? hardPauseLabel(currentAttempt?.failureCode ?? null, \"workflow.status.HARD_PAUSED\", t)\n : t(pipelineStatusLabelKeys[snapshot.run.status])\n }\n tone={pipelineStatusTones[snapshot.run.status]}\n />\n </div>\n {budgetPolicy ? (\n <div className=\"workflow-budget\">\n <div className=\"workflow-budget__heading\">\n <span>{t(\"workflow.budget.title\")}</span>\n <strong>\n {t(\"workflow.budget.usage\", {\n used,\n limit: budgetPolicy.maxEstimatedTokens,\n })}\n </strong>\n </div>\n <progress\n aria-label={t(\"workflow.budget.title\")}\n max={budgetPolicy.maxEstimatedTokens}\n value={Math.min(used, budgetPolicy.maxEstimatedTokens)}\n />\n <div className=\"workflow-budget__meta\">\n <span>{t(\"workflow.budget.revision\", { revision: budgetPolicy.revision })}</span>\n <span>{budgetPercent}%</span>\n </div>\n </div>\n ) : null}\n <ol className=\"workflow-stage-list\">\n {snapshot.stageAttempts.map((attempt) => (\n <li className={`is-${attempt.status.toLowerCase()}`} key={attempt.id}>\n <span aria-hidden=\"true\" />\n <div>\n <strong>{t(stageLabelKeys[attempt.stage])}</strong>\n <small>{stageAttemptStatusLabel(attempt, t)}</small>\n </div>\n </li>\n ))}\n </ol>\n {currentAttempt ? <AttemptSessionsPanel attempt={currentAttempt} /> : null}\n {snapshot.acceptancePackage ? (\n <AcceptancePanel\n acceptancePackage={snapshot.acceptancePackage}\n artifacts={snapshot.artifacts}\n item={item}\n run={run}\n />\n ) : snapshot.artifacts.length > 0 ? (\n <div className=\"workflow-artifact-summary\">\n <strong>{t(\"acceptance.evidence\")}</strong>\n <span>{t(\"acceptance.evidenceCount\", { count: snapshot.artifacts.length })}</span>\n </div>\n ) : null}\n {openRequest ? <HumanRequestPanel request={openRequest} /> : null}\n {snapshot.recoveryReports.at(-1) ? (\n <div className=\"workflow-recovery\" role=\"status\">\n <strong>{t(\"workflow.recovery.title\")}</strong>\n <span>{t(\"workflow.recovery.description\")}</span>\n </div>\n ) : null}\n {controlMutation.error || overrideMutation.error ? (\n <LocalConnectionRecovery\n error={controlMutation.error ?? overrideMutation.error}\n onRetry={() => {\n if (lastAction === \"override\") approveOverride();\n else if (lastAction) runControl(lastAction);\n }}\n retrying={controlPending}\n />\n ) : null}\n {[\"RUNNING\", \"WAITING_HUMAN\", \"SOFT_PAUSED\", \"HARD_PAUSED\", \"INTERRUPTED\"].includes(run.status) &&\n snapshot.acceptancePackage?.status !== \"PENDING\" ? (\n <div className=\"workflow-panel__actions\">\n {run.status === \"RUNNING\" ? (\n <Button\n disabled={controlPending}\n loading={controlMutation.isPending && lastAction === \"pause\"}\n onClick={() => {\n runControl(\"pause\");\n }}\n >\n {t(\"workflow.action.pause\")}\n </Button>\n ) : null}\n {run.status === \"SOFT_PAUSED\" || run.status === \"INTERRUPTED\" ? (\n <Button\n disabled={controlPending}\n loading={controlMutation.isPending && lastAction === \"resume\"}\n onClick={() => {\n runControl(\"resume\");\n }}\n variant=\"primary\"\n >\n {t(\"workflow.action.resume\")}\n </Button>\n ) : null}\n {run.status === \"HARD_PAUSED\" && !isSessionPauseFailureCode(currentAttempt?.failureCode ?? null) ? (\n <Button\n disabled={controlPending}\n loading={overrideMutation.isPending}\n onClick={approveOverride}\n variant=\"primary\"\n >\n {t(\"workflow.action.override\", { limit: overrideLimit })}\n </Button>\n ) : null}\n <Button\n disabled={controlPending}\n loading={controlMutation.isPending && lastAction === \"cancel\"}\n onClick={() => {\n runControl(\"cancel\");\n }}\n variant=\"secondary\"\n >\n {t(\"workflow.action.cancel\")}\n </Button>\n </div>\n ) : null}\n {snapshot.run.status === \"SUCCEEDED\" ? (\n <p className=\"workflow-panel__completed\">{t(\"workflow.completed\")}</p>\n ) : null}\n </div>\n );\n};\n\nconst ActivitySkeleton = ({ label }: { label?: string }): React.JSX.Element => (\n <div\n aria-label={label}\n className=\"inspector-activity-skeleton\"\n role={label === undefined ? undefined : \"status\"}\n >\n {[\"first\", \"second\", \"third\"].map((row, index) => (\n <div className=\"inspector-activity-skeleton__row\" key={row}>\n <Skeleton className=\"inspector-activity-skeleton__icon\" />\n <span>\n <Skeleton width={index === 1 ? \"52%\" : \"68%\"} />\n <Skeleton width={index === 2 ? \"64%\" : \"82%\"} />\n </span>\n <Skeleton width=\"28px\" />\n </div>\n ))}\n </div>\n);\n\n/**\n * An item's activity grows without bound, so it is read newest first, one page at a time, rather\n * than rendering the whole log. The count stays honest about that: it reads \"30+\" while more pages\n * remain instead of claiming the loaded rows are all there is.\n */\nconst TaskActivitySection = ({ item }: { item: WorkItem }): React.JSX.Element => {\n const { locale, t } = useI18n();\n const eventsQuery = useWorkItemEvents(item.projectId, item.id);\n const events = eventsQuery.data?.pages.flatMap((page) => page.events) ?? [];\n const loadMore = (): void => {\n void eventsQuery.fetchNextPage();\n };\n\n return (\n <InspectorSection\n action={\n eventsQuery.data ? (\n <span className=\"inspector-step-count\">\n {eventsQuery.hasNextPage ? t(\"task.activityCountMore\", { count: events.length }) : events.length}\n </span>\n ) : undefined\n }\n title={t(\"task.activity\")}\n >\n {events.length > 0 ? (\n <ol aria-busy={eventsQuery.isFetchingNextPage} className=\"inspector-activity\">\n {events.map((event) => (\n <li key={event.id}>\n <TimelineEvent {...eventPresentation(event, t)} time={eventTime(event.occurredAt, locale)} />\n </li>\n ))}\n </ol>\n ) : null}\n {eventsQuery.hasNextPage ? (\n <Button\n className=\"inspector-activity__more\"\n disabled={eventsQuery.isFetchingNextPage}\n loading={eventsQuery.isFetchingNextPage}\n onClick={loadMore}\n size=\"sm\"\n >\n {t(\"task.loadMoreActivity\")}\n </Button>\n ) : null}\n {eventsQuery.isPending ? <ActivitySkeleton label={t(\"task.loadingActivity\")} /> : null}\n {eventsQuery.data && events.length === 0 ? (\n <p className=\"inspector-copy\">{t(\"task.noActivity\")}</p>\n ) : null}\n </InspectorSection>\n );\n};\n\n/**\n * While the board loads there is nothing to select yet, so the inspector must not claim the reader\n * made no selection. It mirrors the real panel - header, overview grid, workflow and activity - so\n * the layout holds still once the first task lands.\n */\nconst TaskInspectorSkeleton = (): React.JSX.Element => {\n const { t } = useI18n();\n\n return (\n <aside\n aria-busy=\"true\"\n aria-label={t(\"loading.inspector.title\")}\n className=\"task-inspector\"\n role=\"status\"\n >\n <div className=\"task-inspector__header\">\n <div className=\"task-inspector__identity\">\n <Skeleton width=\"68px\" />\n <div className=\"inspector-skeleton__actions\">\n <Skeleton className=\"inspector-skeleton__control\" width=\"28px\" />\n <Skeleton className=\"inspector-skeleton__control\" width=\"112px\" />\n </div>\n </div>\n <Skeleton className=\"inspector-skeleton__title\" width=\"72%\" />\n </div>\n\n <section className=\"lr-inspector-section\">\n <header>\n <Skeleton width=\"64px\" />\n </header>\n <div className=\"lr-inspector-section__body\">\n <div className=\"inspector-skeleton__summary\">\n {[\"state\", \"stage\", \"type\", \"priority\", \"risk\"].map((property, index) => (\n <div key={property}>\n <Skeleton width=\"48%\" />\n <Skeleton width={index % 2 === 0 ? \"74%\" : \"56%\"} />\n </div>\n ))}\n </div>\n <div className=\"inspector-skeleton__copy\">\n <Skeleton width=\"100%\" />\n <Skeleton width=\"84%\" />\n </div>\n </div>\n </section>\n\n <section className=\"lr-inspector-section\">\n <header>\n <Skeleton width=\"76px\" />\n <Skeleton width=\"20px\" />\n </header>\n <div className=\"lr-inspector-section__body\">\n <WorkflowSkeleton />\n </div>\n </section>\n\n <section className=\"lr-inspector-section\">\n <header>\n <Skeleton width=\"120px\" />\n <Skeleton width=\"16px\" />\n </header>\n <div className=\"lr-inspector-section__body\">\n <ActivitySkeleton />\n </div>\n </section>\n </aside>\n );\n};\n\nconst TaskInspector = ({ item }: { item: WorkItem | null }): React.JSX.Element => {\n const { t } = useI18n();\n const moveMutation = useMoveWorkItem();\n const workflowQuery = useWorkItemWorkflow(item?.id);\n const [lastTarget, setLastTarget] = useState<WorkItemState | null>(null);\n\n if (!item) {\n return (\n <aside className=\"task-inspector is-empty\" aria-label={t(\"empty.noSelection.title\")}>\n <FeedbackState\n className=\"inspector-empty-feedback\"\n description={t(\"empty.noSelection.description\")}\n title={t(\"empty.noSelection.title\")}\n />\n </aside>\n );\n }\n\n const workflowActive = [\"RUNNING\", \"WAITING_HUMAN\", \"SOFT_PAUSED\", \"HARD_PAUSED\", \"INTERRUPTED\"].includes(\n workflowQuery.data?.run?.status ?? \"\",\n );\n const targets = workflowActive ? [] : transitionTargets[item.state];\n const move = (targetState: WorkItemState): void => {\n setLastTarget(targetState);\n moveMutation.mutate({ targetState, workItem: item });\n };\n const { primary: primaryTarget, secondary: secondaryTarget } = moveShortcutsFor(item.state, workflowActive);\n\n return (\n <aside className=\"task-inspector\" aria-label={item.title}>\n <header className=\"task-inspector__header\">\n <div className=\"task-inspector__identity\">\n <span className=\"task-inspector__id\">{displayWorkItemId(item.id)}</span>\n <div className=\"task-inspector__actions\">\n <TaskEditDialog key={`${item.id}-${item.version.toString()}`} item={item} />\n <ActionMenu\n align=\"end\"\n groups={[\n targets.map((targetState) => ({\n danger: targetState === \"CANCELLED\",\n label: t(\"task.moveTo\", { state: stateLabel(targetState, t) }),\n onSelect: () => {\n move(targetState);\n },\n })),\n ]}\n trigger={\n <Button disabled={targets.length === 0} shape=\"pill\" trailingIcon=\"chevronDown\">\n {t(\"task.move\")}\n </Button>\n }\n />\n </div>\n </div>\n <h2>{item.title}</h2>\n </header>\n\n <InspectorSection title={t(\"task.overview\")}>\n <RunSummary\n properties={[\n {\n label: t(\"task.state\"),\n value: <Status label={stateLabel(item.state, t)} tone={stateTones[item.state]} />,\n },\n {\n label: t(\"task.stage\"),\n value: item.currentStage ? t(stageLabelKeys[item.currentStage]) : \"—\",\n },\n { label: t(\"task.type\"), value: t(typeLabelKeys[item.type]) },\n { label: t(\"task.priority\"), value: t(priorityLabelKeys[item.priority]) },\n { label: t(\"task.risk\"), value: t(riskLabelKeys[item.risk]) },\n ]}\n />\n <p className=\"inspector-copy\">{item.description || t(\"task.noBrief\")}</p>\n </InspectorSection>\n\n <InspectorSection\n action={\n workflowQuery.data?.run ? (\n <span className=\"inspector-step-count\">\n {workflowQuery.data.stageAttempts.length.toString().padStart(2, \"0\")}\n </span>\n ) : undefined\n }\n title={t(\"workflow.title\")}\n >\n <WorkflowPanel item={item} />\n </InspectorSection>\n\n <WorkspacePanel item={item} />\n\n {/* Keyed by work item, unlike its siblings, because this one holds state: which file the\n owner expanded. Without the key React would reconcile the same component across a switch\n to a different task and carry that path over, reopening a same-named file in a card the\n owner never asked it about. */}\n <ChangesSection key={item.id} workItemId={item.id} />\n\n <InspectorSection title={t(\"task.acceptanceCriteria\")}>\n {item.acceptanceCriteria.length > 0 ? (\n <div className=\"inspector-checklist\">\n {item.acceptanceCriteria.map((criterion) => (\n <Checkbox disabled key={criterion} label={criterion} />\n ))}\n </div>\n ) : (\n <p className=\"inspector-copy\">{t(\"task.noAcceptanceCriteria\")}</p>\n )}\n </InspectorSection>\n\n <TaskActivitySection item={item} />\n\n {moveMutation.error ? (\n <div className=\"task-inspector__error\">\n <LocalConnectionRecovery\n error={moveMutation.error}\n onRetry={() => {\n if (lastTarget) move(lastTarget);\n }}\n retrying={moveMutation.isPending}\n />\n </div>\n ) : null}\n\n {primaryTarget !== null || secondaryTarget !== null ? (\n <footer className=\"task-inspector__footer\">\n {secondaryTarget ? (\n <Button\n aria-label={t(\"task.moveTo\", { state: stateLabel(secondaryTarget, t) })}\n loading={moveMutation.isPending}\n onClick={() => {\n move(secondaryTarget);\n }}\n variant=\"secondary\"\n >\n {t(\"task.moveToShort\", { state: stateLabel(secondaryTarget, t) })}\n </Button>\n ) : null}\n {primaryTarget ? (\n <Button\n aria-label={t(\"task.moveTo\", { state: stateLabel(primaryTarget, t) })}\n loading={moveMutation.isPending}\n onClick={() => {\n move(primaryTarget);\n }}\n variant=\"primary\"\n >\n {t(\"task.moveToShort\", { state: stateLabel(primaryTarget, t) })}\n </Button>\n ) : null}\n </footer>\n ) : null}\n </aside>\n );\n};\n\nexport const WorkbenchPage = (): React.JSX.Element => {\n const { t } = useI18n();\n const navigate = useNavigate({ from: \"/\" });\n const search = useSearch({ from: \"/\" });\n const { connectionPending, error, projectsPending, retryConnection, selectedProject } = useWorkspace();\n const workItemsQuery = useProjectWorkItems(selectedProject?.id);\n const humanRequestsQuery = useProjectHumanRequests(selectedProject?.id);\n const initializeMutation = useInitializeFixtureWorkspace();\n const [selectedWorkItemId, setSelectedWorkItemId] = useState<string | null>(null);\n const filters = search.filters?.split(\",\") ?? [];\n const summaryFilter = search.summary ?? null;\n const setFilters = (value: readonly string[]): void => {\n void navigate({\n replace: true,\n resetScroll: false,\n search: (current) => ({\n ...current,\n filters: value.length > 0 ? value.join(\",\") : undefined,\n }),\n });\n };\n const setSummaryFilter = (value: SummaryFilter | null): void => {\n void navigate({\n replace: true,\n resetScroll: false,\n search: (current) => ({\n ...current,\n summary: value ?? undefined,\n }),\n });\n };\n const view: BoardView = {\n direction: search.dir ?? defaultBoardView.direction,\n ordering: search.order ?? defaultBoardView.ordering,\n showEmptyColumns: search.hideEmpty !== true,\n };\n const setView = (value: BoardView): void => {\n void navigate({\n replace: true,\n resetScroll: false,\n search: (current) => ({\n ...current,\n dir: value.direction === defaultBoardView.direction ? undefined : value.direction,\n order: value.ordering === defaultBoardView.ordering ? undefined : value.ordering,\n hideEmpty: value.showEmptyColumns ? undefined : true,\n }),\n });\n };\n const scope: BoardScope = search.scope ?? \"active\";\n const setScope = (value: BoardScope): void => {\n void navigate({\n replace: true,\n resetScroll: false,\n search: (current) => ({\n ...current,\n scope: value === \"active\" ? undefined : value,\n // Status filters name columns that a different scope may not show.\n filters: undefined,\n }),\n });\n };\n const clearFilters = (): void => {\n void navigate({\n replace: true,\n resetScroll: false,\n search: (current) => ({\n ...current,\n filters: undefined,\n summary: undefined,\n }),\n });\n };\n const boardPending = projectsPending || (selectedProject !== null && workItemsQuery.isPending);\n const workItems = workItemsQuery.data?.workItems ?? [];\n const columns = columnsFor(scope);\n const scopedItems = workItems.filter((item) => scopeShows(scope, item.state));\n const blockingRequests = humanRequestsQuery.data?.humanRequests.filter(({ blocking }) => blocking) ?? [];\n const blockingWorkItemIds = new Set(blockingRequests.map(({ workItemId }) => workItemId));\n const summaryFilteredItems = scopedItems.filter((item) => {\n if (summaryFilter === \"needsYou\") return blockingWorkItemIds.has(item.id);\n return true;\n });\n const visibleItems = orderWorkItems(\n summaryFilteredItems.filter((item) => matchesFilters(item, filters)),\n view,\n );\n const selectedItem =\n visibleItems.find((item) => item.id === selectedWorkItemId) ?? visibleItems.at(0) ?? null;\n const filterOptions = filterOptionsFor(scopedItems, columns, t);\n\n return (\n <div className=\"workbench\">\n <section\n aria-label={t(\"work.boardLabel\")}\n className=\"workbench-board\"\n aria-labelledby=\"current-work-title\"\n >\n <h1 className=\"lr-visually-hidden\" id=\"current-work-title\">\n {t(\"work.current\")}\n </h1>\n <BoardToolbar\n filters={filters}\n onClearFilters={clearFilters}\n onFiltersChange={setFilters}\n onScopeChange={setScope}\n onSummaryFilterChange={setSummaryFilter}\n onViewChange={setView}\n options={filterOptions}\n scope={scope}\n summaryFilter={summaryFilter}\n view={view}\n />\n {blockingRequests[0] ? (\n <button\n className=\"attention-banner\"\n onClick={() => {\n clearFilters();\n setSelectedWorkItemId(blockingRequests[0]?.workItemId ?? null);\n }}\n type=\"button\"\n >\n <span className=\"attention-banner__icon\">\n <Icon name=\"question\" size={14} />\n </span>\n <span>\n <strong>{t(\"attention.title\")}</strong>\n <small>{blockingRequests[0].title}</small>\n </span>\n <span className=\"attention-banner__count\">\n {t(blockingRequests.length === 1 ? \"attention.count\" : \"attention.countMany\", {\n count: blockingRequests.length,\n })}\n </span>\n <Icon name=\"chevronRight\" size={14} />\n </button>\n ) : null}\n\n {!selectedProject && !projectsPending && !error ? (\n <div className=\"workbench-state\">\n <FeedbackState\n action={\n <Button\n loading={initializeMutation.isPending}\n onClick={() => {\n initializeMutation.mutate();\n }}\n variant=\"primary\"\n >\n {t(\"empty.noProjects.action\")}\n </Button>\n }\n description={t(\"empty.noProjects.description\")}\n title={t(\"empty.noProjects.title\")}\n />\n {initializeMutation.error instanceof Error ? (\n <p className=\"workbench-state__error\" role=\"alert\">\n {initializeMutation.error.message}\n </p>\n ) : null}\n </div>\n ) : null}\n\n {boardPending ? (\n <div\n aria-busy=\"true\"\n aria-label={t(\"loading.board.title\")}\n className=\"board-skeleton\"\n role=\"status\"\n >\n {columns.map((column) => (\n <div className=\"board-skeleton__column\" key={column.labelKey}>\n <header>\n <Skeleton width=\"72px\" />\n <Skeleton width=\"16px\" />\n </header>\n {[0, 1].map((card) => (\n <div className=\"board-skeleton__card\" key={card}>\n <Skeleton width=\"54px\" />\n <Skeleton width={card === 0 ? \"88%\" : \"64%\"} />\n <Skeleton width=\"46%\" />\n </div>\n ))}\n </div>\n ))}\n </div>\n ) : null}\n\n {error || workItemsQuery.error ? (\n <div className=\"workbench-state\">\n <LocalConnectionRecovery\n error={workItemsQuery.error ?? error ?? new Error(t(\"error.unknown\"))}\n onRetry={() => {\n if (workItemsQuery.error) {\n void workItemsQuery.refetch();\n } else {\n retryConnection();\n }\n }}\n retrying={connectionPending || workItemsQuery.isFetching}\n />\n </div>\n ) : null}\n\n {selectedProject && workItemsQuery.data ? (\n <>\n <div className=\"kanban-board-scroll\">\n <div className=\"kanban-board\">\n {columns.map((column) => {\n const columnItems = visibleItems.filter((item) => item.state === column.state);\n if (columnItems.length === 0 && !view.showEmptyColumns) return null;\n return (\n <KanbanColumn\n count={columnItems.length}\n key={column.labelKey}\n label={t(column.labelKey)}\n tone={column.tone}\n >\n {columnItems.map((item) => (\n <WorkItemButton\n item={item}\n key={item.id}\n onSelect={setSelectedWorkItemId}\n selected={selectedItem?.id === item.id}\n />\n ))}\n </KanbanColumn>\n );\n })}\n </div>\n </div>\n {scopedItems.length === 0 ? (\n <div className=\"board-filter-empty\" role=\"status\">\n <span>\n <Icon name=\"inbox\" size={18} />\n </span>\n <strong>{t(`empty.${scope}.title`)}</strong>\n <p>{t(`empty.${scope}.description`)}</p>\n </div>\n ) : null}\n {(filters.length > 0 || summaryFilter !== null) && visibleItems.length === 0 ? (\n <div className=\"board-filter-empty\" role=\"status\">\n <span>\n <Icon name=\"filter\" size={18} />\n </span>\n <strong>{t(\"empty.filters.title\")}</strong>\n <p>{t(\"empty.filters.description\")}</p>\n </div>\n ) : null}\n </>\n ) : null}\n </section>\n\n <PanelResizer edge=\"end\" panel=\"inspector\" />\n {boardPending ? (\n <TaskInspectorSkeleton />\n ) : (\n <TaskInspector item={selectedItem} key={selectedItem?.id ?? \"empty\"} />\n )}\n </div>\n );\n};\n","import { createRootRoute, createRoute, createRouter } from \"@tanstack/react-router\";\n\nimport {\n defaultBoardView,\n isBoardDirection,\n isBoardOrdering,\n isBoardScope,\n type BoardDirection,\n type BoardOrdering,\n type BoardScope,\n} from \"./boardView\";\nimport { AppFrame } from \"./shell/AppFrame\";\nimport { WorkbenchPage } from \"./views/WorkbenchPage\";\n\nconst rootRoute = createRootRoute({ component: AppFrame });\n\n// The only quick filter on the board is the workspace navigation's Human requests destination.\nconst summaryFilters = new Set([\"needsYou\"]);\nconst workItemFilters = new Set([\n \"priority-high\",\n \"priority-low\",\n \"priority-medium\",\n \"priority-urgent\",\n \"risk-critical\",\n \"risk-high\",\n \"risk-low\",\n \"risk-medium\",\n \"status-backlog\",\n \"status-blocked\",\n \"status-cancelled\",\n \"status-done\",\n \"status-in_progress\",\n \"status-ready\",\n]);\n\nexport type SummaryFilter = \"needsYou\";\n\nexport type WorkbenchSearch = {\n dir?: BoardDirection;\n filters?: string;\n hideEmpty?: true;\n order?: BoardOrdering;\n scope?: Exclude<BoardScope, \"active\">;\n summary?: SummaryFilter;\n};\n\nconst validateWorkbenchSearch = (search: Record<string, unknown>): WorkbenchSearch => {\n const rawFilters = search[\"filters\"];\n const rawSummary = search[\"summary\"];\n const filters =\n typeof rawFilters === \"string\"\n ? rawFilters\n .split(\",\")\n .filter((filter) => workItemFilters.has(filter))\n .join(\",\")\n : \"\";\n const summary =\n typeof rawSummary === \"string\" && summaryFilters.has(rawSummary)\n ? (rawSummary as SummaryFilter)\n : undefined;\n\n const rawOrder = search[\"order\"];\n const rawDirection = search[\"dir\"];\n const order = isBoardOrdering(rawOrder) && rawOrder !== defaultBoardView.ordering ? rawOrder : undefined;\n const dir =\n isBoardDirection(rawDirection) && rawDirection !== defaultBoardView.direction ? rawDirection : undefined;\n const hideEmpty = search[\"hideEmpty\"] === true || search[\"hideEmpty\"] === \"true\" ? true : undefined;\n const rawScope = search[\"scope\"];\n const scope = isBoardScope(rawScope) && rawScope !== \"active\" ? rawScope : undefined;\n\n return {\n ...(filters.length > 0 ? { filters } : {}),\n ...(summary === undefined ? {} : { summary }),\n ...(order === undefined ? {} : { order }),\n ...(dir === undefined ? {} : { dir }),\n ...(hideEmpty === undefined ? {} : { hideEmpty }),\n ...(scope === undefined ? {} : { scope }),\n };\n};\n\nconst workbenchRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: \"/\",\n component: WorkbenchPage,\n validateSearch: validateWorkbenchSearch,\n});\n\nconst routeTree = rootRoute.addChildren([workbenchRoute]);\n\nexport const router = createRouter({\n routeTree,\n defaultPreload: \"intent\",\n scrollRestoration: true,\n});\n\ndeclare module \"@tanstack/react-router\" {\n // Interface merging is the registration mechanism required by TanStack Router.\n // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n interface Register {\n router: typeof router;\n }\n}\n","import { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { RouterProvider } from \"@tanstack/react-router\";\n\nimport { router } from \"./router\";\nimport { I18nProvider } from \"./i18n\";\nimport { WorkspaceProvider } from \"./workspace\";\n\nconst queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n refetchOnWindowFocus: false,\n retry: false,\n staleTime: 30_000,\n },\n },\n});\n\nexport const App = (): React.JSX.Element => (\n <QueryClientProvider client={queryClient}>\n <I18nProvider>\n <WorkspaceProvider>\n <RouterProvider router={router} />\n </WorkspaceProvider>\n </I18nProvider>\n </QueryClientProvider>\n);\n","import { StrictMode } from \"react\";\nimport { createRoot } from \"react-dom/client\";\n\nimport \"@loomrail/ui/styles.css\";\nimport \"./styles.css\";\n\nimport { App } from \"./App\";\nimport { applyThemePreference, readThemePreference } from \"./theme\";\n\nconst rootElement = document.getElementById(\"root\");\nif (!rootElement) {\n throw new Error(\"Loomrail root element is missing\");\n}\n\napplyThemePreference(readThemePreference());\n\ncreateRoot(rootElement).render(\n <StrictMode>\n <App />\n </StrictMode>,\n);\n"],"mappings":"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"}