clinkx 0.2.3 → 1.0.0

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 (574) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/LICENSE +10 -0
  3. package/README.md +113 -18
  4. package/clinkx-workflows/dist/allowed-roots.d.ts +1 -0
  5. package/clinkx-workflows/dist/allowed-roots.js +5 -0
  6. package/clinkx-workflows/dist/allowed-roots.js.map +1 -0
  7. package/clinkx-workflows/dist/artifacts.d.ts +20 -1
  8. package/clinkx-workflows/dist/artifacts.js +38 -9
  9. package/clinkx-workflows/dist/artifacts.js.map +1 -1
  10. package/clinkx-workflows/dist/backend.d.ts +4 -0
  11. package/clinkx-workflows/dist/citation-check.d.ts +40 -0
  12. package/clinkx-workflows/dist/citation-check.js +348 -0
  13. package/clinkx-workflows/dist/citation-check.js.map +1 -0
  14. package/clinkx-workflows/dist/clink-client.d.ts +2 -1
  15. package/clinkx-workflows/dist/clink-client.js +17 -4
  16. package/clinkx-workflows/dist/clink-client.js.map +1 -1
  17. package/clinkx-workflows/dist/config.d.ts +145 -16
  18. package/clinkx-workflows/dist/config.js +384 -26
  19. package/clinkx-workflows/dist/config.js.map +1 -1
  20. package/clinkx-workflows/dist/contained-file.d.ts +172 -0
  21. package/clinkx-workflows/dist/contained-file.js +483 -0
  22. package/clinkx-workflows/dist/contained-file.js.map +1 -0
  23. package/clinkx-workflows/dist/context-builder-lifecycle-contract.d.ts +416 -0
  24. package/clinkx-workflows/dist/context-builder-lifecycle-contract.js +328 -0
  25. package/clinkx-workflows/dist/context-builder-lifecycle-contract.js.map +1 -0
  26. package/clinkx-workflows/dist/context-builder-lifecycle-router.d.ts +24 -0
  27. package/clinkx-workflows/dist/context-builder-lifecycle-router.js +39 -0
  28. package/clinkx-workflows/dist/context-builder-lifecycle-router.js.map +1 -0
  29. package/clinkx-workflows/dist/context-cache-key.d.ts +53 -0
  30. package/clinkx-workflows/dist/context-cache-key.js +91 -0
  31. package/clinkx-workflows/dist/context-cache-key.js.map +1 -0
  32. package/clinkx-workflows/dist/context-mode-resolver.d.ts +27 -0
  33. package/clinkx-workflows/dist/context-mode-resolver.js +126 -0
  34. package/clinkx-workflows/dist/context-mode-resolver.js.map +1 -0
  35. package/clinkx-workflows/dist/context-preflight.d.ts +184 -0
  36. package/clinkx-workflows/dist/context-preflight.js +91 -0
  37. package/clinkx-workflows/dist/context-preflight.js.map +1 -0
  38. package/clinkx-workflows/dist/council-expander.d.ts +1 -1
  39. package/clinkx-workflows/dist/council-expander.js +2 -1
  40. package/clinkx-workflows/dist/council-expander.js.map +1 -1
  41. package/clinkx-workflows/dist/dashboard/activity-contract.d.ts +165 -0
  42. package/clinkx-workflows/dist/dashboard/activity-contract.js +105 -0
  43. package/clinkx-workflows/dist/dashboard/activity-contract.js.map +1 -0
  44. package/clinkx-workflows/dist/dashboard/activity-lease.d.ts +25 -0
  45. package/clinkx-workflows/dist/dashboard/activity-lease.js +34 -0
  46. package/clinkx-workflows/dist/dashboard/activity-lease.js.map +1 -0
  47. package/clinkx-workflows/dist/dashboard/activity-reader.d.ts +86 -0
  48. package/clinkx-workflows/dist/dashboard/activity-reader.js +480 -0
  49. package/clinkx-workflows/dist/dashboard/activity-reader.js.map +1 -0
  50. package/clinkx-workflows/dist/dashboard/api-routes.d.ts +36 -0
  51. package/clinkx-workflows/dist/dashboard/api-routes.js +1047 -0
  52. package/clinkx-workflows/dist/dashboard/api-routes.js.map +1 -0
  53. package/clinkx-workflows/dist/dashboard/artifact-index.d.ts +37 -0
  54. package/clinkx-workflows/dist/dashboard/artifact-index.js +145 -0
  55. package/clinkx-workflows/dist/dashboard/artifact-index.js.map +1 -0
  56. package/clinkx-workflows/dist/dashboard/auth/challenge-store.d.ts +31 -0
  57. package/clinkx-workflows/dist/dashboard/auth/challenge-store.js +65 -0
  58. package/clinkx-workflows/dist/dashboard/auth/challenge-store.js.map +1 -0
  59. package/clinkx-workflows/dist/dashboard/auth/controller.d.ts +26 -0
  60. package/clinkx-workflows/dist/dashboard/auth/controller.js +596 -0
  61. package/clinkx-workflows/dist/dashboard/auth/controller.js.map +1 -0
  62. package/clinkx-workflows/dist/dashboard/auth/credential-store.d.ts +60 -0
  63. package/clinkx-workflows/dist/dashboard/auth/credential-store.js +776 -0
  64. package/clinkx-workflows/dist/dashboard/auth/credential-store.js.map +1 -0
  65. package/clinkx-workflows/dist/dashboard/auth/enrollment-gate.d.ts +9 -0
  66. package/clinkx-workflows/dist/dashboard/auth/enrollment-gate.js +44 -0
  67. package/clinkx-workflows/dist/dashboard/auth/enrollment-gate.js.map +1 -0
  68. package/clinkx-workflows/dist/dashboard/auth/session-store.d.ts +17 -0
  69. package/clinkx-workflows/dist/dashboard/auth/session-store.js +77 -0
  70. package/clinkx-workflows/dist/dashboard/auth/session-store.js.map +1 -0
  71. package/clinkx-workflows/dist/dashboard/auth/webauthn-service.d.ts +25 -0
  72. package/clinkx-workflows/dist/dashboard/auth/webauthn-service.js +71 -0
  73. package/clinkx-workflows/dist/dashboard/auth/webauthn-service.js.map +1 -0
  74. package/clinkx-workflows/dist/dashboard/context-run-liveness.d.ts +37 -0
  75. package/clinkx-workflows/dist/dashboard/context-run-liveness.js +49 -0
  76. package/clinkx-workflows/dist/dashboard/context-run-liveness.js.map +1 -0
  77. package/clinkx-workflows/dist/dashboard/context-run-reader.d.ts +222 -0
  78. package/clinkx-workflows/dist/dashboard/context-run-reader.js +1178 -0
  79. package/clinkx-workflows/dist/dashboard/context-run-reader.js.map +1 -0
  80. package/clinkx-workflows/dist/dashboard/contracts.d.ts +8936 -0
  81. package/clinkx-workflows/dist/dashboard/contracts.js +1157 -0
  82. package/clinkx-workflows/dist/dashboard/contracts.js.map +1 -0
  83. package/clinkx-workflows/dist/dashboard/generation.d.ts +14 -0
  84. package/clinkx-workflows/dist/dashboard/generation.js +41 -0
  85. package/clinkx-workflows/dist/dashboard/generation.js.map +1 -0
  86. package/clinkx-workflows/dist/dashboard/index.d.ts +28 -0
  87. package/clinkx-workflows/dist/dashboard/index.js +16 -0
  88. package/clinkx-workflows/dist/dashboard/index.js.map +1 -0
  89. package/clinkx-workflows/dist/dashboard/lazy-content.d.ts +101 -0
  90. package/clinkx-workflows/dist/dashboard/lazy-content.js +748 -0
  91. package/clinkx-workflows/dist/dashboard/lazy-content.js.map +1 -0
  92. package/clinkx-workflows/dist/dashboard/progress-report-contract.d.ts +303 -0
  93. package/clinkx-workflows/dist/dashboard/progress-report-contract.js +221 -0
  94. package/clinkx-workflows/dist/dashboard/progress-report-contract.js.map +1 -0
  95. package/clinkx-workflows/dist/dashboard/progress-report-reader.d.ts +50 -0
  96. package/clinkx-workflows/dist/dashboard/progress-report-reader.js +581 -0
  97. package/clinkx-workflows/dist/dashboard/progress-report-reader.js.map +1 -0
  98. package/clinkx-workflows/dist/dashboard/progress-report-status-overlay.d.ts +89 -0
  99. package/clinkx-workflows/dist/dashboard/progress-report-status-overlay.js +71 -0
  100. package/clinkx-workflows/dist/dashboard/progress-report-status-overlay.js.map +1 -0
  101. package/clinkx-workflows/dist/dashboard/progress-report-status-store.d.ts +28 -0
  102. package/clinkx-workflows/dist/dashboard/progress-report-status-store.js +110 -0
  103. package/clinkx-workflows/dist/dashboard/progress-report-status-store.js.map +1 -0
  104. package/clinkx-workflows/dist/dashboard/read-model.d.ts +86 -0
  105. package/clinkx-workflows/dist/dashboard/read-model.js +440 -0
  106. package/clinkx-workflows/dist/dashboard/read-model.js.map +1 -0
  107. package/clinkx-workflows/dist/dashboard/request-admission.d.ts +31 -0
  108. package/clinkx-workflows/dist/dashboard/request-admission.js +126 -0
  109. package/clinkx-workflows/dist/dashboard/request-admission.js.map +1 -0
  110. package/clinkx-workflows/dist/dashboard/scanner.d.ts +75 -0
  111. package/clinkx-workflows/dist/dashboard/scanner.js +1110 -0
  112. package/clinkx-workflows/dist/dashboard/scanner.js.map +1 -0
  113. package/clinkx-workflows/dist/dashboard/server-factory.d.ts +50 -0
  114. package/clinkx-workflows/dist/dashboard/server-factory.js +431 -0
  115. package/clinkx-workflows/dist/dashboard/server-factory.js.map +1 -0
  116. package/clinkx-workflows/dist/dashboard/session-log-contract.d.ts +2611 -0
  117. package/clinkx-workflows/dist/dashboard/session-log-contract.js +480 -0
  118. package/clinkx-workflows/dist/dashboard/session-log-contract.js.map +1 -0
  119. package/clinkx-workflows/dist/dashboard/session-log-identity.d.ts +21 -0
  120. package/clinkx-workflows/dist/dashboard/session-log-identity.js +101 -0
  121. package/clinkx-workflows/dist/dashboard/session-log-identity.js.map +1 -0
  122. package/clinkx-workflows/dist/dashboard/session-log-journal.d.ts +43 -0
  123. package/clinkx-workflows/dist/dashboard/session-log-journal.js +522 -0
  124. package/clinkx-workflows/dist/dashboard/session-log-journal.js.map +1 -0
  125. package/clinkx-workflows/dist/dashboard/session-log-reader.d.ts +61 -0
  126. package/clinkx-workflows/dist/dashboard/session-log-reader.js +378 -0
  127. package/clinkx-workflows/dist/dashboard/session-log-reader.js.map +1 -0
  128. package/clinkx-workflows/dist/dashboard/session-log-redaction.d.ts +6 -0
  129. package/clinkx-workflows/dist/dashboard/session-log-redaction.js +367 -0
  130. package/clinkx-workflows/dist/dashboard/session-log-redaction.js.map +1 -0
  131. package/clinkx-workflows/dist/dashboard/session-log-retention.d.ts +23 -0
  132. package/clinkx-workflows/dist/dashboard/session-log-retention.js +212 -0
  133. package/clinkx-workflows/dist/dashboard/session-log-retention.js.map +1 -0
  134. package/clinkx-workflows/dist/dashboard/static-responses.d.ts +10 -0
  135. package/clinkx-workflows/dist/dashboard/static-responses.js +94 -0
  136. package/clinkx-workflows/dist/dashboard/static-responses.js.map +1 -0
  137. package/clinkx-workflows/dist/dashboard/worker-lock-observer.d.ts +28 -0
  138. package/clinkx-workflows/dist/dashboard/worker-lock-observer.js +241 -0
  139. package/clinkx-workflows/dist/dashboard/worker-lock-observer.js.map +1 -0
  140. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  141. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  142. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  143. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  144. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  145. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  146. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  147. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  148. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  149. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  150. package/clinkx-workflows/dist/dashboard-ui/assets/index-DOkMXTfB.js +25 -0
  151. package/clinkx-workflows/dist/dashboard-ui/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
  152. package/clinkx-workflows/dist/dashboard-ui/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  153. package/clinkx-workflows/dist/dashboard-ui/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
  154. package/clinkx-workflows/dist/dashboard-ui/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
  155. package/clinkx-workflows/dist/dashboard-ui/assets/style-ChJsn0KD.css +1 -0
  156. package/clinkx-workflows/dist/dashboard-ui/contracts/council-plan-review-input-v1.json +158 -0
  157. package/clinkx-workflows/dist/dashboard-ui/index.html +15 -0
  158. package/clinkx-workflows/dist/dashboard-ui/licenses/IBM-Plex-Mono-OFL.txt +93 -0
  159. package/clinkx-workflows/dist/dashboard-ui/licenses/IBM-Plex-Sans-OFL.txt +93 -0
  160. package/clinkx-workflows/dist/dashboard-ui/licenses/JetBrains-Mono-OFL.txt +93 -0
  161. package/clinkx-workflows/dist/dashboard-ui/licenses/NOTICE.md +32 -0
  162. package/clinkx-workflows/dist/dashboard-ui/theme-init.js +8 -0
  163. package/clinkx-workflows/dist/definition-normalizer.d.ts +19 -0
  164. package/clinkx-workflows/dist/definition-normalizer.js.map +1 -1
  165. package/clinkx-workflows/dist/delegate-validate.d.ts +78 -0
  166. package/clinkx-workflows/dist/delegate-validate.js +97 -0
  167. package/clinkx-workflows/dist/delegate-validate.js.map +1 -0
  168. package/clinkx-workflows/dist/engine.d.ts +141 -0
  169. package/clinkx-workflows/dist/engine.js +882 -28
  170. package/clinkx-workflows/dist/engine.js.map +1 -1
  171. package/clinkx-workflows/dist/errors.d.ts +2 -0
  172. package/clinkx-workflows/dist/errors.js.map +1 -1
  173. package/clinkx-workflows/dist/fingerprint.d.ts +1 -1
  174. package/clinkx-workflows/dist/fingerprint.js +1 -1
  175. package/clinkx-workflows/dist/index.d.ts +19 -0
  176. package/clinkx-workflows/dist/index.js +15 -0
  177. package/clinkx-workflows/dist/index.js.map +1 -1
  178. package/clinkx-workflows/dist/loader.d.ts +9 -3
  179. package/clinkx-workflows/dist/loader.js +92 -21
  180. package/clinkx-workflows/dist/loader.js.map +1 -1
  181. package/clinkx-workflows/dist/plan-review/admission.d.ts +160 -0
  182. package/clinkx-workflows/dist/plan-review/admission.js +290 -0
  183. package/clinkx-workflows/dist/plan-review/admission.js.map +1 -0
  184. package/clinkx-workflows/dist/plan-review/context-policy.d.ts +55 -0
  185. package/clinkx-workflows/dist/plan-review/context-policy.js +146 -0
  186. package/clinkx-workflows/dist/plan-review/context-policy.js.map +1 -0
  187. package/clinkx-workflows/dist/plan-review/contract.d.ts +763 -0
  188. package/clinkx-workflows/dist/plan-review/contract.js +289 -0
  189. package/clinkx-workflows/dist/plan-review/contract.js.map +1 -0
  190. package/clinkx-workflows/dist/plan-review/digest.d.ts +68 -0
  191. package/clinkx-workflows/dist/plan-review/digest.js +241 -0
  192. package/clinkx-workflows/dist/plan-review/digest.js.map +1 -0
  193. package/clinkx-workflows/dist/plan-review/discovery.d.ts +45 -0
  194. package/clinkx-workflows/dist/plan-review/discovery.js +36 -0
  195. package/clinkx-workflows/dist/plan-review/discovery.js.map +1 -0
  196. package/clinkx-workflows/dist/plan-review/execution-contract.d.ts +298 -0
  197. package/clinkx-workflows/dist/plan-review/execution-contract.js +194 -0
  198. package/clinkx-workflows/dist/plan-review/execution-contract.js.map +1 -0
  199. package/clinkx-workflows/dist/plan-review/expander.d.ts +48 -0
  200. package/clinkx-workflows/dist/plan-review/expander.js +243 -0
  201. package/clinkx-workflows/dist/plan-review/expander.js.map +1 -0
  202. package/clinkx-workflows/dist/plan-review/projector.d.ts +126 -0
  203. package/clinkx-workflows/dist/plan-review/projector.js +437 -0
  204. package/clinkx-workflows/dist/plan-review/projector.js.map +1 -0
  205. package/clinkx-workflows/dist/plan-review/publication.d.ts +95 -0
  206. package/clinkx-workflows/dist/plan-review/publication.js +182 -0
  207. package/clinkx-workflows/dist/plan-review/publication.js.map +1 -0
  208. package/clinkx-workflows/dist/plan-review/ranking-reducer.d.ts +34 -0
  209. package/clinkx-workflows/dist/plan-review/ranking-reducer.js +139 -0
  210. package/clinkx-workflows/dist/plan-review/ranking-reducer.js.map +1 -0
  211. package/clinkx-workflows/dist/plan-review/resume.d.ts +38 -0
  212. package/clinkx-workflows/dist/plan-review/resume.js +122 -0
  213. package/clinkx-workflows/dist/plan-review/resume.js.map +1 -0
  214. package/clinkx-workflows/dist/plan-review/rubric.d.ts +7 -0
  215. package/clinkx-workflows/dist/plan-review/rubric.js +24 -0
  216. package/clinkx-workflows/dist/plan-review/rubric.js.map +1 -0
  217. package/clinkx-workflows/dist/plan-review/run-state.d.ts +398 -0
  218. package/clinkx-workflows/dist/plan-review/run-state.js +183 -0
  219. package/clinkx-workflows/dist/plan-review/run-state.js.map +1 -0
  220. package/clinkx-workflows/dist/plan-review/runtime-policy.d.ts +74 -0
  221. package/clinkx-workflows/dist/plan-review/runtime-policy.js +186 -0
  222. package/clinkx-workflows/dist/plan-review/runtime-policy.js.map +1 -0
  223. package/clinkx-workflows/dist/plan-review/snapshot.d.ts +81 -0
  224. package/clinkx-workflows/dist/plan-review/snapshot.js +170 -0
  225. package/clinkx-workflows/dist/plan-review/snapshot.js.map +1 -0
  226. package/clinkx-workflows/dist/plan-review/stage-error.d.ts +19 -0
  227. package/clinkx-workflows/dist/plan-review/stage-error.js +20 -0
  228. package/clinkx-workflows/dist/plan-review/stage-error.js.map +1 -0
  229. package/clinkx-workflows/dist/post-processors/index.d.ts +20 -0
  230. package/clinkx-workflows/dist/post-processors/index.js +21 -0
  231. package/clinkx-workflows/dist/post-processors/index.js.map +1 -0
  232. package/clinkx-workflows/dist/prompt-budget.d.ts +7 -0
  233. package/clinkx-workflows/dist/prompt-budget.js +7 -1
  234. package/clinkx-workflows/dist/prompt-budget.js.map +1 -1
  235. package/clinkx-workflows/dist/reducers/index.js +2 -0
  236. package/clinkx-workflows/dist/reducers/index.js.map +1 -1
  237. package/clinkx-workflows/dist/run-lock-heartbeat.d.ts +2 -0
  238. package/clinkx-workflows/dist/run-lock-heartbeat.js +3 -0
  239. package/clinkx-workflows/dist/run-lock-heartbeat.js.map +1 -0
  240. package/clinkx-workflows/dist/run-summary/cards/council-plan-review.d.ts +34 -0
  241. package/clinkx-workflows/dist/run-summary/cards/council-plan-review.js +74 -0
  242. package/clinkx-workflows/dist/run-summary/cards/council-plan-review.js.map +1 -0
  243. package/clinkx-workflows/dist/run-summary/cards/index.js +5 -0
  244. package/clinkx-workflows/dist/run-summary/cards/index.js.map +1 -1
  245. package/clinkx-workflows/dist/run-summary.d.ts +13 -0
  246. package/clinkx-workflows/dist/run-summary.js +29 -1
  247. package/clinkx-workflows/dist/run-summary.js.map +1 -1
  248. package/clinkx-workflows/dist/schema.d.ts +76 -21
  249. package/clinkx-workflows/dist/schema.js +10 -1
  250. package/clinkx-workflows/dist/schema.js.map +1 -1
  251. package/clinkx-workflows/dist/seed-terms.d.ts +30 -0
  252. package/clinkx-workflows/dist/seed-terms.js +176 -0
  253. package/clinkx-workflows/dist/seed-terms.js.map +1 -0
  254. package/clinkx-workflows/dist/server.d.ts +5 -2
  255. package/clinkx-workflows/dist/server.js +82 -52
  256. package/clinkx-workflows/dist/server.js.map +1 -1
  257. package/clinkx-workflows/dist/shutdown.d.ts +18 -20
  258. package/clinkx-workflows/dist/shutdown.js +43 -61
  259. package/clinkx-workflows/dist/shutdown.js.map +1 -1
  260. package/clinkx-workflows/dist/state-schema.d.ts +38 -0
  261. package/clinkx-workflows/dist/state.d.ts +170 -3
  262. package/clinkx-workflows/dist/state.js +1275 -28
  263. package/clinkx-workflows/dist/state.js.map +1 -1
  264. package/clinkx-workflows/dist/transport.d.ts +15 -0
  265. package/clinkx-workflows/dist/transport.js +19 -10
  266. package/clinkx-workflows/dist/transport.js.map +1 -1
  267. package/clinkx-workflows/dist/types.d.ts +14 -2
  268. package/clinkx-workflows/dist/validators/council.d.ts +318 -85
  269. package/clinkx-workflows/dist/validators/council.js +52 -13
  270. package/clinkx-workflows/dist/validators/council.js.map +1 -1
  271. package/clinkx-workflows/dist/validators/index.d.ts +1 -0
  272. package/clinkx-workflows/dist/validators/index.js +3 -0
  273. package/clinkx-workflows/dist/validators/index.js.map +1 -1
  274. package/clinkx-workflows/dist/validators/plan-review.d.ts +398 -0
  275. package/clinkx-workflows/dist/validators/plan-review.js +316 -0
  276. package/clinkx-workflows/dist/validators/plan-review.js.map +1 -0
  277. package/clinkx-workflows/dist/workflow-receipt.js +188 -4
  278. package/clinkx-workflows/dist/workflow-receipt.js.map +1 -1
  279. package/clinkx-workflows/dist/workflow-tools.d.ts +48 -3
  280. package/clinkx-workflows/dist/workflow-tools.js +1402 -59
  281. package/clinkx-workflows/dist/workflow-tools.js.map +1 -1
  282. package/clinkx-workflows/dist/workspace-signature.d.ts +16 -0
  283. package/clinkx-workflows/dist/workspace-signature.js +388 -0
  284. package/clinkx-workflows/dist/workspace-signature.js.map +1 -0
  285. package/clinkx-workflows/templates/council/answer-specialist.txt +2 -1
  286. package/clinkx-workflows/templates/council/code-review-chairman.txt +13 -0
  287. package/clinkx-workflows/templates/council/code-review-cross-reviewer.txt +4 -1
  288. package/clinkx-workflows/templates/council/code-review-reviewer.txt +19 -3
  289. package/clinkx-workflows/templates/council/debug-debugger.txt +2 -1
  290. package/clinkx-workflows/templates/council/discover-analyst.txt +2 -1
  291. package/clinkx-workflows/templates/council/member.txt +2 -1
  292. package/clinkx-workflows/templates/council/plan-review-chairman.txt +68 -0
  293. package/clinkx-workflows/templates/council/plan-review-cross-reviewer.txt +51 -0
  294. package/clinkx-workflows/templates/council/plan-review-reviewer.txt +60 -0
  295. package/clinkx-workflows/templates/plan-review/chairman.txt +48 -0
  296. package/clinkx-workflows/templates/plan-review/cross-review.txt +52 -0
  297. package/clinkx-workflows/templates/plan-review/ranking.txt +16 -0
  298. package/clinkx-workflows/templates/plan-review/reviewer.txt +57 -0
  299. package/clinkx-workflows/workflows/council-answer.yaml +97 -8
  300. package/clinkx-workflows/workflows/council-code-review.yaml +103 -8
  301. package/clinkx-workflows/workflows/council-debug.yaml +97 -8
  302. package/clinkx-workflows/workflows/council-default.yaml +97 -8
  303. package/clinkx-workflows/workflows/council-discover.yaml +97 -8
  304. package/clinkx-workflows/workflows/council-plan-review.yaml +250 -0
  305. package/clinkx-workflows/workflows/plan-review-receipts.yaml +230 -0
  306. package/conf/adapters/agy.json +49 -0
  307. package/conf/adapters/claude.json +5 -0
  308. package/conf/adapters/codex-app-server.json +44 -0
  309. package/conf/adapters/codex.json +7 -2
  310. package/conf/adapters/glm.json +5 -0
  311. package/conf/adapters/grok.json +60 -0
  312. package/conf/adapters/hapi/agy.json +52 -0
  313. package/conf/adapters/hapi/claude.json +5 -0
  314. package/conf/adapters/hapi/codex.json +7 -2
  315. package/conf/adapters/hapi/glm.json +5 -0
  316. package/conf/prompts/json-codereviewer.txt +1 -0
  317. package/conf/prompts/json.txt +1 -0
  318. package/dist/activity-journal.d.ts +42 -0
  319. package/dist/activity-journal.js +381 -0
  320. package/dist/activity-journal.js.map +1 -0
  321. package/dist/allowed-roots.d.ts +53 -0
  322. package/dist/allowed-roots.js +216 -0
  323. package/dist/allowed-roots.js.map +1 -0
  324. package/dist/codex/activity-session-log.d.ts +14 -0
  325. package/dist/codex/activity-session-log.js +206 -0
  326. package/dist/codex/activity-session-log.js.map +1 -0
  327. package/dist/codex/agent-tools.d.ts +23 -0
  328. package/dist/codex/agent-tools.js +1270 -0
  329. package/dist/codex/agent-tools.js.map +1 -0
  330. package/dist/codex/app-server-client.d.ts +76 -0
  331. package/dist/codex/app-server-client.js +582 -0
  332. package/dist/codex/app-server-client.js.map +1 -0
  333. package/dist/codex/app-server-registry.d.ts +389 -0
  334. package/dist/codex/app-server-registry.js +1407 -0
  335. package/dist/codex/app-server-registry.js.map +1 -0
  336. package/dist/codex/client-types.d.ts +109 -0
  337. package/dist/codex/client-types.js +2 -0
  338. package/dist/codex/client-types.js.map +1 -0
  339. package/dist/codex/protocol.d.ts +5375 -0
  340. package/dist/codex/protocol.js +614 -0
  341. package/dist/codex/protocol.js.map +1 -0
  342. package/dist/codex/session.d.ts +263 -0
  343. package/dist/codex/session.js +466 -0
  344. package/dist/codex/session.js.map +1 -0
  345. package/dist/config.d.ts +185 -19
  346. package/dist/config.js +82 -16
  347. package/dist/config.js.map +1 -1
  348. package/dist/context-builder/anchors.d.ts +12 -0
  349. package/dist/context-builder/anchors.js +22 -0
  350. package/dist/context-builder/anchors.js.map +1 -0
  351. package/dist/context-builder/bundle.d.ts +109 -0
  352. package/dist/context-builder/bundle.js +1498 -0
  353. package/dist/context-builder/bundle.js.map +1 -0
  354. package/dist/context-builder/codemap.d.ts +22 -0
  355. package/dist/context-builder/codemap.js +675 -0
  356. package/dist/context-builder/codemap.js.map +1 -0
  357. package/dist/context-builder/config.d.ts +61 -0
  358. package/dist/context-builder/config.js +216 -0
  359. package/dist/context-builder/config.js.map +1 -0
  360. package/dist/context-builder/context-run-catalog.d.ts +17 -0
  361. package/dist/context-builder/context-run-catalog.js +99 -0
  362. package/dist/context-builder/context-run-catalog.js.map +1 -0
  363. package/dist/context-builder/delegate-packet.d.ts +219 -0
  364. package/dist/context-builder/delegate-packet.js +1190 -0
  365. package/dist/context-builder/delegate-packet.js.map +1 -0
  366. package/dist/context-builder/delegate-reconstruction.d.ts +13 -0
  367. package/dist/context-builder/delegate-reconstruction.js +220 -0
  368. package/dist/context-builder/delegate-reconstruction.js.map +1 -0
  369. package/dist/context-builder/delegate-validation.d.ts +27 -0
  370. package/dist/context-builder/delegate-validation.js +479 -0
  371. package/dist/context-builder/delegate-validation.js.map +1 -0
  372. package/dist/context-builder/delegate.d.ts +26 -0
  373. package/dist/context-builder/delegate.js +134 -0
  374. package/dist/context-builder/delegate.js.map +1 -0
  375. package/dist/context-builder/diagnostics.d.ts +36 -0
  376. package/dist/context-builder/diagnostics.js +107 -0
  377. package/dist/context-builder/diagnostics.js.map +1 -0
  378. package/dist/context-builder/discovery.d.ts +146 -0
  379. package/dist/context-builder/discovery.js +2129 -0
  380. package/dist/context-builder/discovery.js.map +1 -0
  381. package/dist/context-builder/globs.d.ts +14 -0
  382. package/dist/context-builder/globs.js +175 -0
  383. package/dist/context-builder/globs.js.map +1 -0
  384. package/dist/context-builder/handler.d.ts +41 -0
  385. package/dist/context-builder/handler.js +2590 -0
  386. package/dist/context-builder/handler.js.map +1 -0
  387. package/dist/context-builder/lifecycle-contract.d.ts +424 -0
  388. package/dist/context-builder/lifecycle-contract.js +523 -0
  389. package/dist/context-builder/lifecycle-contract.js.map +1 -0
  390. package/dist/context-builder/lifecycle-journal.d.ts +62 -0
  391. package/dist/context-builder/lifecycle-journal.js +88 -0
  392. package/dist/context-builder/lifecycle-journal.js.map +1 -0
  393. package/dist/context-builder/lifecycle-observer.d.ts +102 -0
  394. package/dist/context-builder/lifecycle-observer.js +258 -0
  395. package/dist/context-builder/lifecycle-observer.js.map +1 -0
  396. package/dist/context-builder/lifecycle-reconcile.d.ts +32 -0
  397. package/dist/context-builder/lifecycle-reconcile.js +191 -0
  398. package/dist/context-builder/lifecycle-reconcile.js.map +1 -0
  399. package/dist/context-builder/lifecycle-recovery.d.ts +2 -0
  400. package/dist/context-builder/lifecycle-recovery.js +14 -0
  401. package/dist/context-builder/lifecycle-recovery.js.map +1 -0
  402. package/dist/context-builder/path-signals.d.ts +7 -0
  403. package/dist/context-builder/path-signals.js +70 -0
  404. package/dist/context-builder/path-signals.js.map +1 -0
  405. package/dist/context-builder/paths.d.ts +30 -0
  406. package/dist/context-builder/paths.js +153 -0
  407. package/dist/context-builder/paths.js.map +1 -0
  408. package/dist/context-builder/progress.d.ts +17 -0
  409. package/dist/context-builder/progress.js +93 -0
  410. package/dist/context-builder/progress.js.map +1 -0
  411. package/dist/context-builder/receipt.d.ts +91 -0
  412. package/dist/context-builder/receipt.js +180 -0
  413. package/dist/context-builder/receipt.js.map +1 -0
  414. package/dist/context-builder/refine-handler.d.ts +14 -0
  415. package/dist/context-builder/refine-handler.js +790 -0
  416. package/dist/context-builder/refine-handler.js.map +1 -0
  417. package/dist/context-builder/review-coverage.d.ts +84 -0
  418. package/dist/context-builder/review-coverage.js +437 -0
  419. package/dist/context-builder/review-coverage.js.map +1 -0
  420. package/dist/context-builder/run-id.d.ts +7 -0
  421. package/dist/context-builder/run-id.js +31 -0
  422. package/dist/context-builder/run-id.js.map +1 -0
  423. package/dist/context-builder/schema.d.ts +669 -0
  424. package/dist/context-builder/schema.js +399 -0
  425. package/dist/context-builder/schema.js.map +1 -0
  426. package/dist/context-builder/secrets.d.ts +41 -0
  427. package/dist/context-builder/secrets.js +1651 -0
  428. package/dist/context-builder/secrets.js.map +1 -0
  429. package/dist/context-builder/selection.d.ts +56 -0
  430. package/dist/context-builder/selection.js +1111 -0
  431. package/dist/context-builder/selection.js.map +1 -0
  432. package/dist/context-builder/session-log-identity.d.ts +1 -0
  433. package/dist/context-builder/session-log-identity.js +66 -0
  434. package/dist/context-builder/session-log-identity.js.map +1 -0
  435. package/dist/context-builder/slice-range-math.d.ts +16 -0
  436. package/dist/context-builder/slice-range-math.js +137 -0
  437. package/dist/context-builder/slice-range-math.js.map +1 -0
  438. package/dist/context-builder/status.d.ts +66 -0
  439. package/dist/context-builder/status.js +160 -0
  440. package/dist/context-builder/status.js.map +1 -0
  441. package/dist/context-builder/storage.d.ts +118 -0
  442. package/dist/context-builder/storage.js +1003 -0
  443. package/dist/context-builder/storage.js.map +1 -0
  444. package/dist/context-builder/token-estimate.d.ts +19 -0
  445. package/dist/context-builder/token-estimate.js +90 -0
  446. package/dist/context-builder/token-estimate.js.map +1 -0
  447. package/dist/context-builder/versions.d.ts +29 -0
  448. package/dist/context-builder/versions.js +30 -0
  449. package/dist/context-builder/versions.js.map +1 -0
  450. package/dist/context-builder/workflow-runner.d.ts +69 -0
  451. package/dist/context-builder/workflow-runner.js +1051 -0
  452. package/dist/context-builder/workflow-runner.js.map +1 -0
  453. package/dist/context-builder/write-watchdog.d.ts +14 -0
  454. package/dist/context-builder/write-watchdog.js +38 -0
  455. package/dist/context-builder/write-watchdog.js.map +1 -0
  456. package/dist/dashboard-adapter-catalog.d.ts +9 -0
  457. package/dist/dashboard-adapter-catalog.js +46 -0
  458. package/dist/dashboard-adapter-catalog.js.map +1 -0
  459. package/dist/dashboard-cli.d.ts +79 -0
  460. package/dist/dashboard-cli.js +585 -0
  461. package/dist/dashboard-cli.js.map +1 -0
  462. package/dist/dashboard-companion/client.d.ts +36 -0
  463. package/dist/dashboard-companion/client.js +210 -0
  464. package/dist/dashboard-companion/client.js.map +1 -0
  465. package/dist/dashboard-companion/config.d.ts +8 -0
  466. package/dist/dashboard-companion/config.js +52 -0
  467. package/dist/dashboard-companion/config.js.map +1 -0
  468. package/dist/dashboard-companion/http-proxy.d.ts +10 -0
  469. package/dist/dashboard-companion/http-proxy.js +234 -0
  470. package/dist/dashboard-companion/http-proxy.js.map +1 -0
  471. package/dist/dashboard-companion/protocol.d.ts +80 -0
  472. package/dist/dashboard-companion/protocol.js +455 -0
  473. package/dist/dashboard-companion/protocol.js.map +1 -0
  474. package/dist/dashboard-companion/standalone-assets.d.ts +12 -0
  475. package/dist/dashboard-companion/standalone-assets.js +72 -0
  476. package/dist/dashboard-companion/standalone-assets.js.map +1 -0
  477. package/dist/dashboard-companion/standalone-entry.d.ts +1 -0
  478. package/dist/dashboard-companion/standalone-entry.js +17 -0
  479. package/dist/dashboard-companion/standalone-entry.js.map +1 -0
  480. package/dist/dashboard-gateway/config.d.ts +9 -0
  481. package/dist/dashboard-gateway/config.js +44 -0
  482. package/dist/dashboard-gateway/config.js.map +1 -0
  483. package/dist/dashboard-gateway/index.d.ts +11 -0
  484. package/dist/dashboard-gateway/index.js +755 -0
  485. package/dist/dashboard-gateway/index.js.map +1 -0
  486. package/dist/dashboard-gateway/main.d.ts +1 -0
  487. package/dist/dashboard-gateway/main.js +25 -0
  488. package/dist/dashboard-gateway/main.js.map +1 -0
  489. package/dist/dashboard-pairing-token.d.ts +1 -0
  490. package/dist/dashboard-pairing-token.js +5 -0
  491. package/dist/dashboard-pairing-token.js.map +1 -0
  492. package/dist/elaris/client.d.ts +73 -0
  493. package/dist/elaris/client.js +825 -0
  494. package/dist/elaris/client.js.map +1 -0
  495. package/dist/elaris/config.d.ts +18 -0
  496. package/dist/elaris/config.js +75 -0
  497. package/dist/elaris/config.js.map +1 -0
  498. package/dist/elaris/errors.d.ts +41 -0
  499. package/dist/elaris/errors.js +205 -0
  500. package/dist/elaris/errors.js.map +1 -0
  501. package/dist/elaris/github-repo.d.ts +18 -0
  502. package/dist/elaris/github-repo.js +89 -0
  503. package/dist/elaris/github-repo.js.map +1 -0
  504. package/dist/elaris/index.d.ts +10 -0
  505. package/dist/elaris/index.js +11 -0
  506. package/dist/elaris/index.js.map +1 -0
  507. package/dist/elaris/redact.d.ts +89 -0
  508. package/dist/elaris/redact.js +423 -0
  509. package/dist/elaris/redact.js.map +1 -0
  510. package/dist/elaris/run-id.d.ts +5 -0
  511. package/dist/elaris/run-id.js +20 -0
  512. package/dist/elaris/run-id.js.map +1 -0
  513. package/dist/elaris/status.d.ts +45 -0
  514. package/dist/elaris/status.js +122 -0
  515. package/dist/elaris/status.js.map +1 -0
  516. package/dist/elaris/tool-schemas.d.ts +314 -0
  517. package/dist/elaris/tool-schemas.js +208 -0
  518. package/dist/elaris/tool-schemas.js.map +1 -0
  519. package/dist/elaris/tools.d.ts +73 -0
  520. package/dist/elaris/tools.js +1065 -0
  521. package/dist/elaris/tools.js.map +1 -0
  522. package/dist/elaris/types.d.ts +1541 -0
  523. package/dist/elaris/types.js +252 -0
  524. package/dist/elaris/types.js.map +1 -0
  525. package/dist/errors.d.ts +16 -0
  526. package/dist/errors.js +19 -0
  527. package/dist/errors.js.map +1 -1
  528. package/dist/handler.d.ts +4 -0
  529. package/dist/handler.js +10 -1
  530. package/dist/handler.js.map +1 -1
  531. package/dist/index.d.ts +2 -1
  532. package/dist/index.js +13 -3
  533. package/dist/index.js.map +1 -1
  534. package/dist/local-clink-backend.d.ts +3 -0
  535. package/dist/local-clink-backend.js +4 -0
  536. package/dist/local-clink-backend.js.map +1 -1
  537. package/dist/package-info.d.ts +2 -0
  538. package/dist/package-info.js +18 -0
  539. package/dist/package-info.js.map +1 -0
  540. package/dist/parsers/codex-jsonl.js +48 -3
  541. package/dist/parsers/codex-jsonl.js.map +1 -1
  542. package/dist/parsers/extract.d.ts +10 -1
  543. package/dist/parsers/extract.js +11 -3
  544. package/dist/parsers/extract.js.map +1 -1
  545. package/dist/paths.d.ts +8 -0
  546. package/dist/paths.js +31 -43
  547. package/dist/paths.js.map +1 -1
  548. package/dist/pipeline.d.ts +51 -3
  549. package/dist/pipeline.js +264 -47
  550. package/dist/pipeline.js.map +1 -1
  551. package/dist/run-dir.d.ts +24 -0
  552. package/dist/run-dir.js +201 -2
  553. package/dist/run-dir.js.map +1 -1
  554. package/dist/runner.d.ts +13 -0
  555. package/dist/runner.js +184 -15
  556. package/dist/runner.js.map +1 -1
  557. package/dist/safety.d.ts +4 -4
  558. package/dist/safety.js +4 -4
  559. package/dist/schema.d.ts +7 -7
  560. package/dist/server.d.ts +2 -0
  561. package/dist/server.js +396 -24
  562. package/dist/server.js.map +1 -1
  563. package/dist/session-log-stream.d.ts +18 -0
  564. package/dist/session-log-stream.js +319 -0
  565. package/dist/session-log-stream.js.map +1 -0
  566. package/package.json +47 -5
  567. package/conf/adapters/gemini.json +0 -44
  568. package/conf/adapters/hapi/gemini.json +0 -47
  569. package/dist/artifacts.d.ts +0 -9
  570. package/dist/artifacts.js +0 -24
  571. package/dist/artifacts.js.map +0 -1
  572. package/dist/parsers/gemini-json.d.ts +0 -2
  573. package/dist/parsers/gemini-json.js +0 -72
  574. package/dist/parsers/gemini-json.js.map +0 -1
@@ -0,0 +1,1157 @@
1
+ import { z } from "zod";
2
+ import { PLAN_REVIEW_RESULT_RELPATH } from "../plan-review/publication.js";
3
+ import { IdSchema } from "../schema.js";
4
+ import { CONTEXT_BUILDER_EXECUTION_STATUSES, CONTEXT_BUILDER_FALLBACK_STATUSES, CONTEXT_BUILDER_LIFECYCLE_PHASES, CONTEXT_BUILDER_LIFECYCLE_REASON_CODES, CONTEXT_BUILDER_LIFECYCLE_STATUSES, CONTEXT_BUILDER_OPERATION_KINDS, ContextBuilderLifecycleStateV1Schema, isContextBuilderOperationId, } from "../context-builder-lifecycle-contract.js";
5
+ import { ActivityIdSchema, ActivityKindSchema, ActivityOutcomeKindSchema, ActivityPhaseSchema, } from "./activity-contract.js";
6
+ import { SESSION_LOG_V1_SCHEMA_VERSION, parseSessionLogEventV1, } from "./session-log-contract.js";
7
+ import { PROGRESS_REPORT_SCHEMA_VERSION, BoundedIdSchema, BoundedMessageSchema, BoundedTitleSchema, NonnegativeSafeIntegerSchema, ProjectFolderPathSchema, ProgressReportSessionIdSchema, StrictRfc3339TimestampSchema, } from "./progress-report-contract.js";
8
+ export const MAX_DASHBOARD_STAGE_CALL_RECORDS = 2_000;
9
+ export const MAX_DASHBOARD_ID_CHARS = 128;
10
+ export const MAX_DASHBOARD_PATH_CHARS = 4_096;
11
+ export const MAX_DASHBOARD_RAW_TEXT_CHARS = 2 * 1_024 * 1_024;
12
+ export const MAX_DASHBOARD_STATE_TEXT_CHARS = 64 * 1_024 * 1_024;
13
+ export const MAX_DASHBOARD_WORKFLOW_INPUT_CHARS = 1_024 * 1_024;
14
+ export const MAX_DASHBOARD_WORKFLOW_INPUT_PATHS = 2_048;
15
+ export const MAX_DASHBOARD_ADAPTERS = 256;
16
+ export const DashboardCanonicalHttpsOriginSchema = z.string().superRefine((value, context) => {
17
+ let parsed;
18
+ try {
19
+ parsed = new URL(value);
20
+ }
21
+ catch {
22
+ context.addIssue({
23
+ code: z.ZodIssueCode.custom,
24
+ message: "must be a canonical absolute HTTPS origin",
25
+ });
26
+ return;
27
+ }
28
+ if (parsed.protocol !== "https:" ||
29
+ parsed.username !== "" ||
30
+ parsed.password !== "" ||
31
+ parsed.pathname !== "/" ||
32
+ parsed.search !== "" ||
33
+ parsed.hash !== "" ||
34
+ parsed.origin !== value) {
35
+ context.addIssue({
36
+ code: z.ZodIssueCode.custom,
37
+ message: "must be a canonical absolute HTTPS origin",
38
+ });
39
+ }
40
+ });
41
+ export const DashboardAgentInstanceIdSchema = z.string().regex(/^[A-Za-z0-9_-]{22}$/);
42
+ export const DashboardBearerCapabilitySchema = z.string().regex(/^[A-Za-z0-9_-]{43}$/);
43
+ export const DashboardRemoteAccessConfigSchema = z.object({
44
+ apiOrigin: DashboardCanonicalHttpsOriginSchema,
45
+ uiOrigin: DashboardCanonicalHttpsOriginSchema,
46
+ }).strict();
47
+ export const DashboardConnectionResponseSchema = z.object({
48
+ schemaVersion: z.literal("dashboard-connection-v1"),
49
+ agentInstanceId: DashboardAgentInstanceIdSchema,
50
+ }).strict();
51
+ export const DashboardRemoteFragmentInputSchema = z.object({
52
+ apiOrigin: DashboardCanonicalHttpsOriginSchema,
53
+ agentInstanceId: DashboardAgentInstanceIdSchema,
54
+ token: DashboardBearerCapabilitySchema,
55
+ }).strict();
56
+ export function formatDashboardRemoteFragment(input) {
57
+ const parsed = DashboardRemoteFragmentInputSchema.parse(input);
58
+ return [
59
+ "#v=1",
60
+ `apiOrigin=${encodeURIComponent(parsed.apiOrigin)}`,
61
+ `agentInstanceId=${parsed.agentInstanceId}`,
62
+ `token=${parsed.token}`,
63
+ ].join("&");
64
+ }
65
+ const RUN_ID_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
66
+ const SHA256_PATTERN = /^[0-9a-f]{64}$/;
67
+ const COMPLEXITY_ISSUE = "dashboard_stage_call_limit_exceeded";
68
+ const RunIdSchema = z.string().max(64).regex(RUN_ID_PATTERN);
69
+ const DashboardIdSchema = IdSchema.max(MAX_DASHBOARD_ID_CHARS);
70
+ const TimestampSchema = z.string().max(64).datetime({ offset: true });
71
+ const RelativePathSchema = z.string().min(1).max(MAX_DASHBOARD_PATH_CHARS);
72
+ const DashboardCallStateSchema = z.enum([
73
+ "pending",
74
+ "running",
75
+ "succeeded",
76
+ "failed",
77
+ "cancelled",
78
+ ]);
79
+ const DashboardFailureClassSchema = z.enum(["transient", "permanent"]);
80
+ /**
81
+ * `heartbeat_live` is appended, never reordered: a producer on a foreign host
82
+ * refreshed its `run.lock` mtime within the declared staleness window. It is
83
+ * weaker evidence than `live` (a same-host PID probe) and is reported as a
84
+ * distinct value rather than folded into `live`.
85
+ */
86
+ export const WorkerLockObservationSchema = z.enum([
87
+ "live",
88
+ "orphaned",
89
+ "unknown",
90
+ "heartbeat_live",
91
+ ]);
92
+ /** Strict display contract for the exact persisted pre-dispatch Clink input. */
93
+ export const DashboardWorkflowInputSchema = z.object({
94
+ prompt: z.string().max(MAX_DASHBOARD_WORKFLOW_INPUT_CHARS),
95
+ cli_name: z.string().min(1).max(MAX_DASHBOARD_ID_CHARS).optional(),
96
+ role: z.string().min(1).max(MAX_DASHBOARD_ID_CHARS).optional(),
97
+ absolute_file_paths: z
98
+ .array(z.string().min(1).max(MAX_DASHBOARD_PATH_CHARS))
99
+ .max(MAX_DASHBOARD_WORKFLOW_INPUT_PATHS)
100
+ .optional(),
101
+ images: z
102
+ .array(z.string().min(1).max(MAX_DASHBOARD_PATH_CHARS))
103
+ .max(MAX_DASHBOARD_WORKFLOW_INPUT_PATHS)
104
+ .optional(),
105
+ context: z.string().max(MAX_DASHBOARD_WORKFLOW_INPUT_CHARS).optional(),
106
+ continuation_id: z.string().min(1).max(256).optional(),
107
+ timeout_seconds: z.number().finite().positive().optional(),
108
+ max_response_chars: z.number().int().positive().max(Number.MAX_SAFE_INTEGER).optional(),
109
+ expect_json: z.boolean().optional(),
110
+ debug: z.boolean().optional(),
111
+ debug_keep_artifacts: z.boolean().optional(),
112
+ }).strict();
113
+ const SortedUniqueStringsSchema = z
114
+ .array(z.string().min(1).max(MAX_DASHBOARD_ID_CHARS))
115
+ .max(256)
116
+ .refine((values) => values.every((value, index) => index === 0 || values[index - 1] < value), "must be sorted and unique");
117
+ /** Positive allowlist for root-injected adapter metadata. */
118
+ export const SafeAdapterDescriptorSchema = z.object({
119
+ name: z.string().min(1).max(MAX_DASHBOARD_ID_CHARS),
120
+ command: z
121
+ .string()
122
+ .min(1)
123
+ .max(256)
124
+ .refine((value) => !value.includes("/") && !value.includes("\\"), "command must be a basename"),
125
+ parser: z.enum(["text", "json_extract", "codex_jsonl", "claude_json", "claude_stream_json"]),
126
+ promptMode: z.enum(["stdin", "arg", "file"]),
127
+ timeoutSeconds: z.number().finite().positive(),
128
+ idleTimeoutSeconds: z.number().finite().min(0).optional(),
129
+ idleTimeoutStartupSeconds: z.number().finite().min(0).optional(),
130
+ roleNames: SortedUniqueStringsSchema,
131
+ environmentKeys: SortedUniqueStringsSchema,
132
+ supportsImages: z.boolean(),
133
+ resultContract: z.object({
134
+ enabled: z.boolean(),
135
+ filename: z.enum(["RESULT.md", "RESULT.json"]),
136
+ }).strict(),
137
+ backend: z.enum(["subprocess", "app_server"]),
138
+ workflowEligible: z.boolean().optional(),
139
+ usableVia: z.array(z.enum([
140
+ "clink",
141
+ "context_builder",
142
+ "run_workflow",
143
+ "clink_agent_run",
144
+ "clink_agent_manage",
145
+ ])).max(5).optional(),
146
+ }).strict();
147
+ export const MAX_DASHBOARD_PAGE_SIZE = 500;
148
+ const OpaqueCursorSchema = z.string().min(1).max(1_024).regex(/^[A-Za-z0-9_-]+$/);
149
+ const OpaqueGenerationSchema = z.string().min(16).max(128).regex(/^[A-Za-z0-9_-]+$/);
150
+ const SingleCursorValuesSchema = z.array(OpaqueCursorSchema).length(1).transform(([value]) => value);
151
+ const SingleGenerationValuesSchema = z
152
+ .array(OpaqueGenerationSchema)
153
+ .length(1)
154
+ .transform(([value]) => value);
155
+ const SingleLimitValuesSchema = z
156
+ .array(z.string().regex(/^[1-9][0-9]{0,2}$/))
157
+ .length(1)
158
+ .transform(([value]) => Number(value))
159
+ .refine((value) => value <= MAX_DASHBOARD_PAGE_SIZE, `limit must be <= ${String(MAX_DASHBOARD_PAGE_SIZE)}`);
160
+ /** Query contracts consume a multimap so duplicate security fields stay visible. */
161
+ export const PaginationQuerySchema = z.object({
162
+ limit: SingleLimitValuesSchema.optional(),
163
+ before: SingleCursorValuesSchema.optional(),
164
+ }).strict().transform((query) => ({
165
+ limit: query.limit ?? 100,
166
+ ...(query.before === undefined ? {} : { before: query.before }),
167
+ }));
168
+ export const GenerationQuerySchema = z.object({
169
+ generation: SingleGenerationValuesSchema,
170
+ }).strict().transform((query) => ({ generation: query.generation }));
171
+ const SingleSessionLogSequenceValuesSchema = z
172
+ .array(z.string().regex(/^(?:0|[1-9][0-9]{0,15})$/))
173
+ .length(1)
174
+ .transform(([value]) => Number(value))
175
+ .refine(Number.isSafeInteger, "sequence must be a safe integer");
176
+ export const SessionLogLaneIndexQuerySchema = z.object({
177
+ generation: SingleGenerationValuesSchema,
178
+ }).strict().transform((query) => ({ generation: query.generation }));
179
+ export const SessionLogPageQuerySchema = z.object({
180
+ generation: SingleGenerationValuesSchema,
181
+ sequence: SingleSessionLogSequenceValuesSchema.optional(),
182
+ limit: SingleLimitValuesSchema.optional(),
183
+ }).strict().transform((query) => ({
184
+ generation: query.generation,
185
+ sequence: query.sequence ?? 0,
186
+ limit: query.limit ?? 100,
187
+ }));
188
+ const SessionLogLaneDescriptorResponseSchema = z.object({
189
+ owner: z.record(z.unknown()),
190
+ lane: z.object({
191
+ laneId: z.string().min(1).max(160).regex(/^[A-Za-z0-9_:-]+$/),
192
+ }).strict(),
193
+ nextSequence: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER),
194
+ }).strict().superRefine((descriptor, context) => {
195
+ try {
196
+ parseSessionLogEventV1({
197
+ schemaVersion: SESSION_LOG_V1_SCHEMA_VERSION,
198
+ sequence: 0,
199
+ timestamp: "2000-01-01T00:00:00.000Z",
200
+ producerFamily: descriptor.owner.family,
201
+ owner: descriptor.owner,
202
+ lane: descriptor.lane,
203
+ authority: "observability_only",
204
+ redaction: { ran: true, status: "no_matches", count: 0 },
205
+ truncation: "none",
206
+ completeness: "complete",
207
+ parseWarnings: [],
208
+ event: { kind: "lifecycle", state: "pending" },
209
+ });
210
+ }
211
+ catch {
212
+ context.addIssue({
213
+ code: z.ZodIssueCode.custom,
214
+ message: "invalid session-log lane descriptor",
215
+ });
216
+ }
217
+ });
218
+ export const SessionLogLaneIndexResponseSchema = z.object({
219
+ schemaVersion: z.literal("session-log-index-v1"),
220
+ availability: z.discriminatedUnion("availability", [
221
+ z.object({ availability: z.literal("available") }).strict(),
222
+ z.object({
223
+ availability: z.literal("not_retained"),
224
+ reason: z.literal("producer_did_not_retain"),
225
+ }).strict(),
226
+ ]),
227
+ lanes: z.array(SessionLogLaneDescriptorResponseSchema).max(2_000),
228
+ }).strict().superRefine((response, context) => {
229
+ if ((response.availability.availability === "available") !==
230
+ (response.lanes.length > 0)) {
231
+ context.addIssue({
232
+ code: z.ZodIssueCode.custom,
233
+ message: "session-log lane availability must match discovered lanes",
234
+ path: ["availability"],
235
+ });
236
+ }
237
+ });
238
+ export const StructuredDetailQuerySchema = z.object({
239
+ generation: SingleGenerationValuesSchema.optional(),
240
+ }).strict().transform((query) => query.generation === undefined ? {} : { generation: query.generation });
241
+ /** Detail routes resolve the current incarnation and admit no query fields. */
242
+ export const EmptyQuerySchema = z.object({}).strict();
243
+ export const ContextRunListQuerySchema = z.object({
244
+ limit: SingleLimitValuesSchema.optional(),
245
+ }).strict().transform((query) => ({ limit: query.limit ?? 100 }));
246
+ const ContextRunRouteIdSchema = z.string()
247
+ .max(64)
248
+ .regex(/^[A-Za-z0-9_-]{1,64}$/)
249
+ .refine((id) => !id.startsWith("wfctx") && !id.startsWith("wfpre"), "workflow-owned context records are not context runs");
250
+ export const ContextRunRouteParamsSchema = z.object({
251
+ id: ContextRunRouteIdSchema,
252
+ }).strict();
253
+ /**
254
+ * Artifact keys servable via the bounded `/context-runs/:id/artifacts/:key`
255
+ * body endpoint. Mirrors the producer artifact filename map; the reader pins its
256
+ * own copy to the producer export via a parity test, so this enum and the
257
+ * reader's `CONTEXT_RUN_ARTIFACT_FILE_NAMES` cannot drift independently.
258
+ */
259
+ export const ContextRunArtifactKeySchema = z.enum([
260
+ "manifest_json",
261
+ "bundle_md",
262
+ "selected_context_jsonl",
263
+ "tree_json",
264
+ "search_jsonl",
265
+ "slices_jsonl",
266
+ "codemap_jsonl",
267
+ "summary_json",
268
+ ]);
269
+ export const ContextRunArtifactRouteParamsSchema = z.object({
270
+ id: ContextRunRouteIdSchema,
271
+ artifactKey: ContextRunArtifactKeySchema,
272
+ }).strict();
273
+ export const RunRouteParamsSchema = z.object({
274
+ runId: RunIdSchema,
275
+ }).strict();
276
+ export const ActivityRouteParamsSchema = z.object({
277
+ activityId: ActivityIdSchema,
278
+ }).strict();
279
+ export const CallRouteParamsSchema = z.object({
280
+ runId: RunIdSchema,
281
+ stageId: DashboardIdSchema,
282
+ callId: DashboardIdSchema,
283
+ contentKind: z.enum(["prompt", "output", "error", "artifact"]),
284
+ }).strict();
285
+ export const SessionLogWorkflowRouteParamsSchema = z.object({
286
+ runId: RunIdSchema,
287
+ stageId: DashboardIdSchema,
288
+ callId: DashboardIdSchema,
289
+ }).strict();
290
+ export const SessionLogLaneRouteParamsSchema = z.object({
291
+ laneId: z.string().min(1).max(160).regex(/^[A-Za-z0-9_:-]+$/),
292
+ }).strict();
293
+ const WorkflowVariableDescriptorSchema = z.object({
294
+ name: DashboardIdSchema,
295
+ type: z.enum(["string", "number", "boolean", "string[]"]),
296
+ required: z.boolean(),
297
+ }).strict();
298
+ export const WorkflowDescriptorSchema = z.object({
299
+ name: DashboardIdSchema,
300
+ version: z.string().min(1).max(128),
301
+ description: z.string().max(4_096),
302
+ stageCount: z.number().int().min(0).max(MAX_DASHBOARD_STAGE_CALL_RECORDS),
303
+ callCount: z.number().int().min(0).max(MAX_DASHBOARD_STAGE_CALL_RECORDS),
304
+ variables: z.array(WorkflowVariableDescriptorSchema).max(512),
305
+ }).strict();
306
+ const DashboardChildConfigSourceSchema = z.discriminatedUnion("source", [
307
+ z.object({
308
+ source: z.literal("explicit"),
309
+ configured: z.literal(true),
310
+ path: z.string().min(1).max(MAX_DASHBOARD_PATH_CHARS),
311
+ }).strict(),
312
+ z.object({
313
+ source: z.literal("ambient"),
314
+ configured: z.literal(false),
315
+ }).strict(),
316
+ ]);
317
+ export const DashboardEnvironmentSchema = z.object({
318
+ stateDir: z.string().min(1).max(MAX_DASHBOARD_PATH_CHARS),
319
+ activitiesRoot: z.string().min(1).max(MAX_DASHBOARD_PATH_CHARS).optional(),
320
+ progressReportsRoot: z.string().min(1).max(MAX_DASHBOARD_PATH_CHARS).optional(),
321
+ runsRoot: z.string().min(1).max(MAX_DASHBOARD_PATH_CHARS),
322
+ workspaceRoot: z.string().min(1).max(MAX_DASHBOARD_PATH_CHARS),
323
+ workflowsPath: z.string().min(1).max(MAX_DASHBOARD_PATH_CHARS),
324
+ templatesPath: z.string().min(1).max(MAX_DASHBOARD_PATH_CHARS),
325
+ childConfig: DashboardChildConfigSourceSchema,
326
+ }).strict();
327
+ const RunIdentitySchema = z.object({
328
+ runId: RunIdSchema,
329
+ runGeneration: OpaqueGenerationSchema,
330
+ stateRevision: OpaqueGenerationSchema,
331
+ });
332
+ const DashboardStageMarkerSchema = z.object({
333
+ stageId: DashboardIdSchema,
334
+ state: DashboardCallStateSchema,
335
+ }).strict();
336
+ export const MAX_DASHBOARD_STAGE_MARKERS = 64;
337
+ export const MAX_DASHBOARD_LIVE_RUNS = 500;
338
+ /** Cap on projected `cb_roots` (mirrors the search-terms channel cap). */
339
+ export const MAX_DASHBOARD_ROOTS = 20;
340
+ export const MAX_DASHBOARD_AGGREGATE_RETRY_COUNT = MAX_DASHBOARD_STAGE_CALL_RECORDS * 1_000_000;
341
+ const CompactStateCountsSchema = z.object({
342
+ pending: z.number().int().min(0).max(MAX_DASHBOARD_STAGE_CALL_RECORDS),
343
+ running: z.number().int().min(0).max(MAX_DASHBOARD_STAGE_CALL_RECORDS),
344
+ succeeded: z.number().int().min(0).max(MAX_DASHBOARD_STAGE_CALL_RECORDS),
345
+ failed: z.number().int().min(0).max(MAX_DASHBOARD_STAGE_CALL_RECORDS),
346
+ cancelled: z.number().int().min(0).max(MAX_DASHBOARD_STAGE_CALL_RECORDS),
347
+ }).strict();
348
+ const HealthyRunListItemSchema = RunIdentitySchema.extend({
349
+ availability: z.literal("available"),
350
+ workflowName: DashboardIdSchema,
351
+ workflowVersion: z.string().min(1).max(128),
352
+ status: DashboardCallStateSchema,
353
+ orphaned: z.boolean(),
354
+ workerLockObservation: WorkerLockObservationSchema.optional(),
355
+ resumable: z.boolean(),
356
+ startedAt: TimestampSchema.optional(),
357
+ completedAt: TimestampSchema.optional(),
358
+ stateUpdatedAt: TimestampSchema,
359
+ failureClass: DashboardFailureClassSchema.optional(),
360
+ async: z.boolean(),
361
+ debugKeepArtifacts: z.boolean(),
362
+ retryCount: z.number().int().min(0).max(MAX_DASHBOARD_AGGREGATE_RETRY_COUNT),
363
+ reportedRunningCalls: z.number().int().min(0).max(MAX_DASHBOARD_STAGE_CALL_RECORDS),
364
+ stageCounts: CompactStateCountsSchema,
365
+ callCounts: CompactStateCountsSchema,
366
+ stageMarkers: z.array(DashboardStageMarkerSchema).max(MAX_DASHBOARD_STAGE_MARKERS),
367
+ additionalStageCount: z.number().int().min(0).max(MAX_DASHBOARD_STAGE_CALL_RECORDS),
368
+ /**
369
+ * Project folder(s) the run was created for, sourced from the persisted
370
+ * `variables.cb_roots`. Always present (empty when no roots were recorded) so
371
+ * the detail page can show a stable "project folder" row.
372
+ */
373
+ projectFolders: z.array(z.string()).max(MAX_DASHBOARD_ROOTS),
374
+ }).strict();
375
+ const UnavailableReasonSchema = z.enum([
376
+ "state_unreadable",
377
+ "state_invalid",
378
+ "too_large_for_dashboard",
379
+ "too_complex_for_dashboard",
380
+ "path_rejected",
381
+ "identity_mismatch",
382
+ "run_generation_race",
383
+ ]);
384
+ const UnavailableRunSchema = RunIdentitySchema.extend({
385
+ availability: z.literal("unavailable"),
386
+ reason: UnavailableReasonSchema,
387
+ chronologyAt: TimestampSchema.optional(),
388
+ }).strict();
389
+ export const ActivityLeaseObservationSchema = z.enum([
390
+ "live",
391
+ "orphaned",
392
+ "unknown",
393
+ ]);
394
+ function requireConsistentActivityLease(item, ctx) {
395
+ if (item.orphaned !== (item.leaseObservation === "orphaned")) {
396
+ ctx.addIssue({
397
+ code: z.ZodIssueCode.custom,
398
+ message: "orphaned must agree with leaseObservation",
399
+ path: ["orphaned"],
400
+ });
401
+ }
402
+ if (item.status !== "running") {
403
+ if (item.orphaned || item.leaseObservation !== "unknown") {
404
+ ctx.addIssue({
405
+ code: z.ZodIssueCode.custom,
406
+ message: "terminal activities cannot carry a live or orphaned lease",
407
+ path: ["leaseObservation"],
408
+ });
409
+ }
410
+ }
411
+ }
412
+ function requireConsistentWorkerLockObservation(item, ctx) {
413
+ if (item.workerLockObservation !== undefined &&
414
+ item.orphaned !== (item.workerLockObservation === "orphaned")) {
415
+ ctx.addIssue({
416
+ code: z.ZodIssueCode.custom,
417
+ message: "orphaned must agree with workerLockObservation",
418
+ path: ["orphaned"],
419
+ });
420
+ }
421
+ }
422
+ const ConsistentHealthyRunListItemSchema = HealthyRunListItemSchema.superRefine(requireConsistentWorkerLockObservation);
423
+ export const RunListItemSchema = z.discriminatedUnion("availability", [
424
+ HealthyRunListItemSchema,
425
+ UnavailableRunSchema,
426
+ ]).superRefine((item, ctx) => {
427
+ if (item.availability === "available")
428
+ requireConsistentWorkerLockObservation(item, ctx);
429
+ });
430
+ export const RunListResponseSchema = z.object({
431
+ live: z.array(ConsistentHealthyRunListItemSchema).max(MAX_DASHBOARD_LIVE_RUNS),
432
+ history: z.array(RunListItemSchema).max(MAX_DASHBOARD_PAGE_SIZE),
433
+ nextBefore: OpaqueCursorSchema.optional(),
434
+ serverNow: TimestampSchema,
435
+ }).strict();
436
+ export const RunsResponseSchema = RunListResponseSchema;
437
+ const ActivityIdentitySchema = z.object({
438
+ activityId: ActivityIdSchema,
439
+ activityGeneration: OpaqueGenerationSchema,
440
+ stateRevision: OpaqueGenerationSchema,
441
+ }).strict();
442
+ const ActivityListItemObjectSchema = ActivityIdentitySchema.extend({
443
+ kind: ActivityKindSchema,
444
+ phase: ActivityPhaseSchema,
445
+ status: z.enum(["running", "succeeded", "failed", "cancelled"]),
446
+ adapter: DashboardIdSchema,
447
+ role: DashboardIdSchema,
448
+ startedAt: TimestampSchema,
449
+ stateUpdatedAt: TimestampSchema,
450
+ completedAt: TimestampSchema.optional(),
451
+ hasResult: z.boolean(),
452
+ projectFolders: z.array(z.string()).max(MAX_DASHBOARD_ROOTS),
453
+ orphaned: z.boolean(),
454
+ leaseObservation: ActivityLeaseObservationSchema,
455
+ }).strict();
456
+ export const ActivityListItemSchema = ActivityListItemObjectSchema
457
+ .superRefine(requireConsistentActivityLease);
458
+ export const ActivityListResponseSchema = z.object({
459
+ activities: z.array(ActivityListItemSchema).max(MAX_DASHBOARD_PAGE_SIZE),
460
+ nextBefore: OpaqueCursorSchema.optional(),
461
+ serverNow: TimestampSchema,
462
+ }).strict();
463
+ export const ActivityDetailSchema = ActivityListItemObjectSchema.extend({
464
+ outcome: z.object({
465
+ kind: ActivityOutcomeKindSchema,
466
+ }).strict().optional(),
467
+ resultTruncated: z.boolean().optional(),
468
+ }).strict().superRefine(requireConsistentActivityLease);
469
+ const ContextRunCountSchema = z.number().int().min(0).max(250_000_000);
470
+ export const ContextRunLifecycleProjectionSchema = z.object({
471
+ status: z.enum(CONTEXT_BUILDER_LIFECYCLE_STATUSES),
472
+ phase: z.enum(CONTEXT_BUILDER_LIFECYCLE_PHASES),
473
+ createdAt: TimestampSchema.nullable(),
474
+ updatedAt: TimestampSchema.nullable(),
475
+ startedAt: TimestampSchema.nullable(),
476
+ completedAt: TimestampSchema.nullable(),
477
+ durationMs: z.number().int().min(0).max(86_400_000).nullable(),
478
+ curator: z.object({
479
+ status: z.enum(CONTEXT_BUILDER_EXECUTION_STATUSES),
480
+ score: z.number().finite().min(0).max(10).nullable(),
481
+ }).strict(),
482
+ finalizer: z.object({
483
+ status: z.enum(CONTEXT_BUILDER_EXECUTION_STATUSES),
484
+ score: z.number().finite().min(0).max(10).nullable(),
485
+ }).strict(),
486
+ cache: z.object({
487
+ lookup: z.enum(["not_checked", "miss", "hit"]),
488
+ write: z.enum(["not_attempted", "skipped", "written"]),
489
+ }).strict(),
490
+ fallback: z.object({
491
+ status: z.enum(CONTEXT_BUILDER_FALLBACK_STATUSES),
492
+ }).strict(),
493
+ counts: z.object({
494
+ filesSeen: ContextRunCountSchema,
495
+ filesConsidered: ContextRunCountSchema,
496
+ filesSelected: ContextRunCountSchema,
497
+ filesOmitted: ContextRunCountSchema,
498
+ searchResults: ContextRunCountSchema,
499
+ bytesRead: ContextRunCountSchema,
500
+ bytesWritten: ContextRunCountSchema,
501
+ }).strict(),
502
+ coverage: z.object({
503
+ policy: z.literal("review_deep_v1").nullable(),
504
+ status: z.enum(["satisfied", "degraded", "not_evaluated"]),
505
+ required: ContextRunCountSchema,
506
+ selected: ContextRunCountSchema,
507
+ missing: ContextRunCountSchema,
508
+ }).strict(),
509
+ reasonCodes: z.array(z.enum(CONTEXT_BUILDER_LIFECYCLE_REASON_CODES))
510
+ .max(16)
511
+ .refine((codes) => new Set(codes).size === codes.length, "reason codes must be unique"),
512
+ artifactRunId: RunIdSchema.nullable(),
513
+ }).strict();
514
+ const CurrentDashboardContextPreflightSchema = ContextRunLifecycleProjectionSchema.extend({
515
+ availability: z.literal("current"),
516
+ profile: z.enum([
517
+ "handoff_small",
518
+ "implementation_medium",
519
+ "review_deep",
520
+ ]).nullable(),
521
+ effectiveMode: z.enum(["full", "deterministic", "off", "disabled"]).nullable(),
522
+ failurePolicy: z.enum(["fallback", "fail"]).nullable(),
523
+ // The ctxop_… operation id, present when a preflight session-log generation
524
+ // sidecar exists. Pairs with the sidecar under <runDir>/.context-preflight.
525
+ contextRunId: z.string().max(40).refine(isContextBuilderOperationId, "invalid context builder operation ID").optional(),
526
+ }).strict();
527
+ const LegacyDashboardContextPreflightSchema = z.object({
528
+ availability: z.literal("legacy_without_telemetry"),
529
+ status: z.enum(["succeeded", "partial"]),
530
+ profile: z.enum([
531
+ "handoff_small",
532
+ "implementation_medium",
533
+ "review_deep",
534
+ ]).nullable(),
535
+ effectiveMode: z.enum(["full", "deterministic", "off", "disabled"]).nullable(),
536
+ failurePolicy: z.enum(["fallback", "fail"]).nullable(),
537
+ }).strict();
538
+ const PolicyOnlyDashboardContextPreflightSchema = z.object({
539
+ profile: z.enum([
540
+ "handoff_small",
541
+ "implementation_medium",
542
+ "review_deep",
543
+ ]).nullable(),
544
+ effectiveMode: z.enum(["full", "deterministic", "off", "disabled"]),
545
+ failurePolicy: z.enum(["fallback", "fail"]).nullable(),
546
+ }).strict();
547
+ export const DashboardContextPreflightSchema = z.discriminatedUnion("availability", [
548
+ CurrentDashboardContextPreflightSchema,
549
+ LegacyDashboardContextPreflightSchema,
550
+ PolicyOnlyDashboardContextPreflightSchema.extend({
551
+ availability: z.literal("bypassed"),
552
+ }).strict(),
553
+ PolicyOnlyDashboardContextPreflightSchema.extend({
554
+ availability: z.literal("awaiting_telemetry"),
555
+ }).strict(),
556
+ PolicyOnlyDashboardContextPreflightSchema.extend({
557
+ availability: z.literal("telemetry_unavailable"),
558
+ }).strict(),
559
+ z.object({ availability: z.literal("absent") }).strict(),
560
+ ]);
561
+ export const ContextRunLivenessSchema = z.enum([
562
+ "live",
563
+ "orphaned",
564
+ "unknown",
565
+ ]);
566
+ function requireConsistentContextRunLiveness(row, ctx) {
567
+ if (row.orphaned !== (row.liveness === "orphaned")) {
568
+ ctx.addIssue({
569
+ code: z.ZodIssueCode.custom,
570
+ message: "orphaned must agree with liveness",
571
+ path: ["orphaned"],
572
+ });
573
+ }
574
+ const status = row.lifecycle?.status;
575
+ const active = status === "pending" || status === "running";
576
+ if (!active && (row.orphaned || row.liveness !== "unknown")) {
577
+ ctx.addIssue({
578
+ code: z.ZodIssueCode.custom,
579
+ message: "terminal or unsupported context runs cannot carry live or orphaned liveness",
580
+ path: ["liveness"],
581
+ });
582
+ }
583
+ }
584
+ export const ContextRunRowSchema = z.object({
585
+ id: ContextRunRouteIdSchema,
586
+ contextGeneration: OpaqueGenerationSchema,
587
+ source: z.enum(["journal", "historical_manifest"]),
588
+ compatibility: z.enum([
589
+ "current",
590
+ "legacy_synthesized",
591
+ "legacy_unsupported",
592
+ ]),
593
+ operationKind: z.enum(CONTEXT_BUILDER_OPERATION_KINDS),
594
+ lifecycle: ContextRunLifecycleProjectionSchema.nullable(),
595
+ /**
596
+ * Project folder(s) from the manifest `roots[].path`. Defaults to `[]` so the
597
+ * strict parse accepts both journal producers (no roots) and historical rows.
598
+ */
599
+ projectFolders: z.array(z.string()).max(MAX_DASHBOARD_ROOTS).default([]),
600
+ orphaned: z.boolean().default(false),
601
+ liveness: ContextRunLivenessSchema.default("unknown"),
602
+ }).strict().superRefine((row, context) => {
603
+ if ((row.compatibility === "legacy_unsupported") !== (row.lifecycle === null)) {
604
+ context.addIssue({
605
+ code: z.ZodIssueCode.custom,
606
+ message: "only legacy_unsupported context runs omit lifecycle detail",
607
+ path: ["lifecycle"],
608
+ });
609
+ }
610
+ requireConsistentContextRunLiveness(row, context);
611
+ });
612
+ export const ContextRunListResponseSchema = z.object({
613
+ contextRuns: z.array(ContextRunRowSchema).max(MAX_DASHBOARD_PAGE_SIZE),
614
+ serverNow: TimestampSchema,
615
+ truncated: z.boolean(),
616
+ }).strict();
617
+ const DashboardCallSummarySchema = z.object({
618
+ stageId: DashboardIdSchema,
619
+ callId: DashboardIdSchema,
620
+ state: DashboardCallStateSchema,
621
+ retryCount: z.number().int().min(0).max(1_000_000),
622
+ attemptsConsumed: z.number().int().min(0).max(1_000_000).optional(),
623
+ startedAt: TimestampSchema.optional(),
624
+ completedAt: TimestampSchema.optional(),
625
+ durationMs: z.number().finite().min(0).max(Number.MAX_SAFE_INTEGER).optional(),
626
+ failureClass: DashboardFailureClassSchema.optional(),
627
+ snapshotIdentity: z.object({
628
+ adapter: DashboardIdSchema,
629
+ role: DashboardIdSchema,
630
+ }).strict().optional(),
631
+ hasWorkflowInput: z.boolean(),
632
+ hasOutput: z.boolean(),
633
+ hasRawError: z.boolean(),
634
+ hasArtifactReference: z.boolean(),
635
+ }).strict();
636
+ const DashboardStageDetailSchema = z.object({
637
+ stageId: DashboardIdSchema,
638
+ state: DashboardCallStateSchema,
639
+ startedAt: TimestampSchema.optional(),
640
+ completedAt: TimestampSchema.optional(),
641
+ calls: z.array(DashboardCallSummarySchema).max(MAX_DASHBOARD_STAGE_CALL_RECORDS),
642
+ }).strict();
643
+ const SnapshotEnrichmentSchema = z.discriminatedUnion("availability", [
644
+ z.object({
645
+ availability: z.literal("available"),
646
+ stages: z.array(z.object({
647
+ stageId: DashboardIdSchema,
648
+ label: z.string().min(1).max(256).optional(),
649
+ dependsOn: z.array(DashboardIdSchema).max(MAX_DASHBOARD_STAGE_CALL_RECORDS),
650
+ }).strict()).max(MAX_DASHBOARD_STAGE_CALL_RECORDS),
651
+ }).strict(),
652
+ z.object({
653
+ availability: z.literal("unavailable"),
654
+ reason: z.enum(["missing", "not_loaded", "unreadable", "invalid", "too_large", "hash_mismatch"]),
655
+ }).strict(),
656
+ ]);
657
+ const ResultAvailabilitySchema = z.discriminatedUnion("availability", [
658
+ z.object({
659
+ availability: z.literal("available"),
660
+ kind: z.enum(["text", "json", "plan_review"]),
661
+ }).strict(),
662
+ z.object({
663
+ availability: z.literal("unavailable"),
664
+ reason: z.enum([
665
+ "run_pending",
666
+ "run_running",
667
+ "run_failed",
668
+ "run_cancelled",
669
+ "not_persisted",
670
+ "missing",
671
+ "invalid",
672
+ "too_large",
673
+ ]),
674
+ }).strict(),
675
+ ]);
676
+ const DecisiveFailureSchema = z.object({
677
+ stageId: DashboardIdSchema,
678
+ callId: DashboardIdSchema.optional(),
679
+ failureClass: DashboardFailureClassSchema,
680
+ }).strict();
681
+ const StateCountsSchema = z.object({
682
+ pending: z.number().int().min(0).max(MAX_DASHBOARD_STAGE_CALL_RECORDS),
683
+ running: z.number().int().min(0).max(MAX_DASHBOARD_STAGE_CALL_RECORDS),
684
+ succeeded: z.number().int().min(0).max(MAX_DASHBOARD_STAGE_CALL_RECORDS),
685
+ failed: z.number().int().min(0).max(MAX_DASHBOARD_STAGE_CALL_RECORDS),
686
+ cancelled: z.number().int().min(0).max(MAX_DASHBOARD_STAGE_CALL_RECORDS),
687
+ }).strict();
688
+ const GenericDetailCardSchema = z.object({
689
+ kind: z.literal("generic"),
690
+ stageCounts: StateCountsSchema,
691
+ callCounts: StateCountsSchema,
692
+ }).strict();
693
+ const PlanReviewTransportCardSchema = z.object({
694
+ kind: z.literal("council-plan-review"),
695
+ executionStatus: z.enum(["complete", "partial"]),
696
+ seatCount: z.number().int().min(1).max(10),
697
+ completedSeats: z.number().int().min(0).max(10),
698
+ failedSeats: z.number().int().min(0).max(10),
699
+ missingSeats: z.number().int().min(0).max(10),
700
+ executionContractDigestPrefix: z.string().length(16).regex(/^[0-9a-f]{16}$/),
701
+ chairmanStatus: z.enum(["completed", "failed", "skipped"]),
702
+ contextStatus: z.enum(["succeeded", "partial", "absent"]),
703
+ }).strict().superRefine((card, ctx) => {
704
+ if (card.completedSeats + card.failedSeats + card.missingSeats !== card.seatCount) {
705
+ ctx.addIssue({
706
+ code: z.ZodIssueCode.custom,
707
+ message: "plan-review seat counts must equal seatCount",
708
+ path: ["seatCount"],
709
+ });
710
+ }
711
+ });
712
+ const DashboardDetailCardSchema = z.union([
713
+ GenericDetailCardSchema,
714
+ PlanReviewTransportCardSchema,
715
+ ]);
716
+ const HealthyRunDetailSchema = HealthyRunListItemSchema.extend({
717
+ snapshotEnrichment: SnapshotEnrichmentSchema,
718
+ result: ResultAvailabilitySchema,
719
+ decisiveFailure: DecisiveFailureSchema.optional(),
720
+ card: DashboardDetailCardSchema,
721
+ stages: z.array(DashboardStageDetailSchema).max(MAX_DASHBOARD_STAGE_CALL_RECORDS),
722
+ contextPreflight: DashboardContextPreflightSchema.optional(),
723
+ }).strict();
724
+ export const RunDetailSchema = z.discriminatedUnion("availability", [
725
+ HealthyRunDetailSchema,
726
+ UnavailableRunSchema,
727
+ ]).superRefine((detail, ctx) => {
728
+ if (detail.availability !== "available")
729
+ return;
730
+ requireConsistentWorkerLockObservation(detail, ctx);
731
+ const count = detail.stages.length + detail.stages.reduce((sum, stage) => sum + stage.calls.length, 0);
732
+ if (count > MAX_DASHBOARD_STAGE_CALL_RECORDS) {
733
+ ctx.addIssue({
734
+ code: z.ZodIssueCode.custom,
735
+ message: COMPLEXITY_ISSUE,
736
+ path: ["stages"],
737
+ });
738
+ }
739
+ const detailStageIds = new Set(detail.stages.map((stage) => stage.stageId));
740
+ if (detail.snapshotEnrichment.availability === "available") {
741
+ const snapshotStageIds = new Set();
742
+ for (const [index, snapshotStage] of detail.snapshotEnrichment.stages.entries()) {
743
+ if (snapshotStageIds.has(snapshotStage.stageId)) {
744
+ ctx.addIssue({
745
+ code: z.ZodIssueCode.custom,
746
+ message: "snapshot enrichment stage IDs must be unique",
747
+ path: ["snapshotEnrichment", "stages", index, "stageId"],
748
+ });
749
+ }
750
+ snapshotStageIds.add(snapshotStage.stageId);
751
+ if (!detailStageIds.has(snapshotStage.stageId)) {
752
+ ctx.addIssue({
753
+ code: z.ZodIssueCode.custom,
754
+ message: "snapshot enrichment stage must match persisted state",
755
+ path: ["snapshotEnrichment", "stages", index, "stageId"],
756
+ });
757
+ }
758
+ }
759
+ if (snapshotStageIds.size !== detailStageIds.size) {
760
+ ctx.addIssue({
761
+ code: z.ZodIssueCode.custom,
762
+ message: "available snapshot enrichment must cover every persisted stage",
763
+ path: ["snapshotEnrichment", "stages"],
764
+ });
765
+ }
766
+ for (const [stageIndex, stage] of detail.stages.entries()) {
767
+ for (const [callIndex, call] of stage.calls.entries()) {
768
+ if (call.snapshotIdentity === undefined) {
769
+ ctx.addIssue({
770
+ code: z.ZodIssueCode.custom,
771
+ message: "available snapshot enrichment must identify every persisted call",
772
+ path: ["stages", stageIndex, "calls", callIndex, "snapshotIdentity"],
773
+ });
774
+ }
775
+ }
776
+ }
777
+ }
778
+ else {
779
+ for (const [stageIndex, stage] of detail.stages.entries()) {
780
+ for (const [callIndex, call] of stage.calls.entries()) {
781
+ if (call.snapshotIdentity !== undefined) {
782
+ ctx.addIssue({
783
+ code: z.ZodIssueCode.custom,
784
+ message: "unavailable snapshot enrichment cannot supply call identity",
785
+ path: ["stages", stageIndex, "calls", callIndex, "snapshotIdentity"],
786
+ });
787
+ }
788
+ }
789
+ }
790
+ }
791
+ if (detail.decisiveFailure !== undefined) {
792
+ const failureStage = detail.stages.find((stage) => stage.stageId === detail.decisiveFailure?.stageId);
793
+ if (failureStage === undefined || (detail.decisiveFailure.callId !== undefined &&
794
+ !failureStage.calls.some((call) => call.callId === detail.decisiveFailure?.callId))) {
795
+ ctx.addIssue({
796
+ code: z.ZodIssueCode.custom,
797
+ message: "decisive failure must identify a persisted stage/call",
798
+ path: ["decisiveFailure"],
799
+ });
800
+ }
801
+ }
802
+ // The transport-card kind literal "council-plan-review" is a wire-contract
803
+ // identifier, not the workflow name. Typed runs are named
804
+ // "plan-review-receipts" since the rename; legacy typed runs persist the
805
+ // pre-rename name "council-plan-review" (which now also names the generic
806
+ // plan-review council — its runs carry a generic card, never this one).
807
+ if (detail.card.kind === "council-plan-review" &&
808
+ detail.workflowName !== "plan-review-receipts" &&
809
+ detail.workflowName !== "council-plan-review") {
810
+ ctx.addIssue({
811
+ code: z.ZodIssueCode.custom,
812
+ message: "plan-review transport card requires the plan-review-receipts workflow",
813
+ path: ["card", "kind"],
814
+ });
815
+ }
816
+ });
817
+ export const RunDetailResponseSchema = RunDetailSchema;
818
+ export const ArtifactReferenceSchema = RunIdentitySchema.extend({
819
+ stageId: DashboardIdSchema,
820
+ callId: DashboardIdSchema,
821
+ kind: z.literal("json"),
822
+ validation: z.literal("deferred"),
823
+ }).strict();
824
+ export const WorkflowsResponseSchema = z.object({
825
+ workflows: z.array(WorkflowDescriptorSchema).max(1_000),
826
+ }).strict();
827
+ export const AdaptersResponseSchema = z.object({
828
+ adapters: z.array(SafeAdapterDescriptorSchema).max(MAX_DASHBOARD_ADAPTERS),
829
+ }).strict();
830
+ export const ArtifactsResponseSchema = z.object({
831
+ artifacts: z.array(ArtifactReferenceSchema).max(MAX_DASHBOARD_PAGE_SIZE),
832
+ nextBefore: OpaqueCursorSchema.optional(),
833
+ serverNow: TimestampSchema,
834
+ }).strict();
835
+ export const EnvironmentResponseSchema = DashboardEnvironmentSchema;
836
+ export const ApiErrorResponseSchema = z.object({
837
+ error: z.object({
838
+ code: z.enum([
839
+ "unauthorized",
840
+ "invalid_request",
841
+ "method_not_allowed",
842
+ "host_rejected",
843
+ "origin_rejected",
844
+ "not_found",
845
+ "dashboard_busy",
846
+ "run_directory_limit_exceeded",
847
+ "scan_byte_budget_exceeded",
848
+ "projection_cache_budget_exceeded",
849
+ "live_run_limit_exceeded",
850
+ "artifact_catalog_limit_exceeded",
851
+ "run_generation_changed",
852
+ "run_state_changed",
853
+ "activity_generation_changed",
854
+ "activity_state_changed",
855
+ "context_generation_changed",
856
+ "agent_instance_changed",
857
+ "content_too_large_for_dashboard",
858
+ "context_runs_unavailable",
859
+ "session_logs_unavailable",
860
+ "progress_report_malformed",
861
+ "progress_report_overrides_unavailable",
862
+ "internal_error",
863
+ ]),
864
+ }).strict(),
865
+ }).strict();
866
+ const DashboardCallStateEntrySchema = z.object({
867
+ callId: DashboardIdSchema,
868
+ stageId: DashboardIdSchema,
869
+ state: DashboardCallStateSchema,
870
+ retryCount: z.number().int().min(0).max(1_000_000),
871
+ attemptsConsumed: z.number().int().min(0).max(1_000_000).optional(),
872
+ startedAt: TimestampSchema.optional(),
873
+ completedAt: TimestampSchema.optional(),
874
+ durationMs: z.number().finite().min(0).max(Number.MAX_SAFE_INTEGER).optional(),
875
+ failureClass: DashboardFailureClassSchema.optional(),
876
+ errorMessage: z.string().max(MAX_DASHBOARD_STATE_TEXT_CHARS).optional(),
877
+ outputPath: RelativePathSchema.optional(),
878
+ outputInline: z.string().max(MAX_DASHBOARD_STATE_TEXT_CHARS).optional(),
879
+ materializedInputPath: RelativePathSchema.optional(),
880
+ artifactPath: RelativePathSchema.optional(),
881
+ });
882
+ const DashboardStageStateEntrySchema = z.object({
883
+ stageId: DashboardIdSchema,
884
+ state: DashboardCallStateSchema,
885
+ startedAt: TimestampSchema.optional(),
886
+ completedAt: TimestampSchema.optional(),
887
+ calls: z.array(DashboardCallStateEntrySchema).max(MAX_DASHBOARD_STAGE_CALL_RECORDS),
888
+ });
889
+ const DashboardPlanReviewPublicationSchema = z.discriminatedUnion("committed", [
890
+ z.object({ committed: z.literal(false) }),
891
+ z.object({
892
+ committed: z.literal(true),
893
+ sidecar_relpath: z.literal(PLAN_REVIEW_RESULT_RELPATH),
894
+ sidecar_sha256: z.string().length(64).regex(SHA256_PATTERN),
895
+ bytes: z.number().int().min(0).max(MAX_DASHBOARD_STATE_TEXT_CHARS),
896
+ }),
897
+ ]);
898
+ /**
899
+ * Consumed-field decoder for persisted engine state.
900
+ *
901
+ * Deliberately strips unknown producer fields: this is a dashboard read schema,
902
+ * not the execution engine's complete RunState authority.
903
+ */
904
+ export const DashboardRunStateSchema = z.object({
905
+ state_version: z.literal(1),
906
+ runId: RunIdSchema,
907
+ workflowName: DashboardIdSchema,
908
+ workflowVersion: z.string().min(1).max(128),
909
+ status: DashboardCallStateSchema,
910
+ resumable: z.boolean(),
911
+ workflowSnapshotPath: z.literal("workflow.snapshot.json").optional(),
912
+ workflowSnapshotHash: z.string().length(64).regex(SHA256_PATTERN).optional(),
913
+ stages: z.array(DashboardStageStateEntrySchema).max(MAX_DASHBOARD_STAGE_CALL_RECORDS),
914
+ startedAt: TimestampSchema.optional(),
915
+ completedAt: TimestampSchema.optional(),
916
+ failureClass: DashboardFailureClassSchema.optional(),
917
+ debugKeepArtifacts: z.boolean().optional(),
918
+ async: z.boolean().optional(),
919
+ variables: z.object({
920
+ cb_profile: z.enum([
921
+ "handoff_small",
922
+ "implementation_medium",
923
+ "review_deep",
924
+ ]).optional(),
925
+ /**
926
+ * Context-builder source roots the run operated on — the project folder(s)
927
+ * the run was created for. Persisted by the workflow engine as a string
928
+ * array; surfaced on the run detail page as "project folder".
929
+ */
930
+ cb_roots: z.array(z.string()).optional(),
931
+ }).optional(),
932
+ initialContextPolicy: z.object({
933
+ effectiveMode: z.enum(["full", "deterministic", "off", "disabled"]),
934
+ effectiveDelegate: z.object({
935
+ failure_policy: z.enum(["fallback", "fail"]).optional(),
936
+ }).optional(),
937
+ }).optional(),
938
+ context_builder_lifecycle: ContextBuilderLifecycleStateV1Schema.refine((lifecycle) => lifecycle.operation_kind === "workflow_preflight", "dashboard workflow preflight lifecycle must have operation_kind workflow_preflight").optional(),
939
+ workflow_context: z.object({
940
+ context_builder: z.object({
941
+ status: z.enum(["succeeded", "partial"]),
942
+ context_mode: z.enum(["full", "deterministic", "off", "disabled"]).optional(),
943
+ }),
944
+ }).optional(),
945
+ plan_review_state: z.object({
946
+ publication: DashboardPlanReviewPublicationSchema.optional(),
947
+ }).optional(),
948
+ }).superRefine((state, ctx) => {
949
+ const stageIds = new Set();
950
+ let recordCount = state.stages.length;
951
+ for (const [stageIndex, stage] of state.stages.entries()) {
952
+ if (stageIds.has(stage.stageId)) {
953
+ ctx.addIssue({
954
+ code: z.ZodIssueCode.custom,
955
+ message: `duplicate stageId ${stage.stageId}`,
956
+ path: ["stages", stageIndex, "stageId"],
957
+ });
958
+ }
959
+ stageIds.add(stage.stageId);
960
+ const callIds = new Set();
961
+ recordCount += stage.calls.length;
962
+ for (const [callIndex, call] of stage.calls.entries()) {
963
+ const callPath = ["stages", stageIndex, "calls", callIndex];
964
+ if (callIds.has(call.callId)) {
965
+ ctx.addIssue({
966
+ code: z.ZodIssueCode.custom,
967
+ message: `duplicate callId ${call.callId} in stage ${stage.stageId}`,
968
+ path: [...callPath, "callId"],
969
+ });
970
+ }
971
+ callIds.add(call.callId);
972
+ if (call.stageId !== stage.stageId) {
973
+ ctx.addIssue({
974
+ code: z.ZodIssueCode.custom,
975
+ message: "call.stageId must equal its enclosing stageId",
976
+ path: [...callPath, "stageId"],
977
+ });
978
+ }
979
+ const inputPath = `${stage.stageId}.${call.callId}.input.json`;
980
+ if (call.materializedInputPath !== undefined && call.materializedInputPath !== inputPath) {
981
+ ctx.addIssue({
982
+ code: z.ZodIssueCode.custom,
983
+ message: "materializedInputPath does not match its producer call",
984
+ path: [...callPath, "materializedInputPath"],
985
+ });
986
+ }
987
+ const hasInline = call.outputInline !== undefined;
988
+ const hasPath = call.outputPath !== undefined;
989
+ if (hasInline && hasPath) {
990
+ ctx.addIssue({
991
+ code: z.ZodIssueCode.custom,
992
+ message: "outputInline and outputPath are mutually exclusive",
993
+ path: callPath,
994
+ });
995
+ }
996
+ if (call.state === "succeeded" && !hasInline && !hasPath) {
997
+ ctx.addIssue({
998
+ code: z.ZodIssueCode.custom,
999
+ message: "succeeded call must have one persisted output representation",
1000
+ path: callPath,
1001
+ });
1002
+ }
1003
+ const outputPath = `${stage.stageId}.${call.callId}.output.txt`;
1004
+ if (hasPath && call.outputPath !== outputPath) {
1005
+ ctx.addIssue({
1006
+ code: z.ZodIssueCode.custom,
1007
+ message: "outputPath does not match its producer call",
1008
+ path: [...callPath, "outputPath"],
1009
+ });
1010
+ }
1011
+ const artifactPath = `artifacts/${stage.stageId}/${String(callIndex + 1).padStart(2, "0")}-${call.callId}.json`;
1012
+ if (call.artifactPath !== undefined && call.artifactPath !== artifactPath) {
1013
+ ctx.addIssue({
1014
+ code: z.ZodIssueCode.custom,
1015
+ message: "artifactPath does not match its producer call ordinal",
1016
+ path: [...callPath, "artifactPath"],
1017
+ });
1018
+ }
1019
+ }
1020
+ }
1021
+ if (recordCount > MAX_DASHBOARD_STAGE_CALL_RECORDS) {
1022
+ ctx.addIssue({
1023
+ code: z.ZodIssueCode.custom,
1024
+ message: COMPLEXITY_ISSUE,
1025
+ path: ["stages"],
1026
+ });
1027
+ }
1028
+ });
1029
+ export function parseDashboardRunState(raw, expectedRunId) {
1030
+ if (!RunIdSchema.safeParse(expectedRunId).success) {
1031
+ return { ok: false, reason: "state_invalid", issues: ["invalid expected runId"] };
1032
+ }
1033
+ const parsed = DashboardRunStateSchema.safeParse(raw);
1034
+ if (!parsed.success) {
1035
+ const issues = parsed.error.issues.map((issue) => issue.message);
1036
+ return {
1037
+ ok: false,
1038
+ reason: issues.includes(COMPLEXITY_ISSUE)
1039
+ ? "too_complex_for_dashboard"
1040
+ : "state_invalid",
1041
+ issues,
1042
+ };
1043
+ }
1044
+ if (parsed.data.runId !== expectedRunId) {
1045
+ return { ok: false, reason: "state_invalid", issues: ["persisted runId does not match directory runId"] };
1046
+ }
1047
+ return { ok: true, state: parsed.data };
1048
+ }
1049
+ // --- Progress report wire schemas ---------------------------------------
1050
+ /**
1051
+ * Re-export of the producer-side schema version literal so dashboard
1052
+ * consumers can import it from the single wire-contract module.
1053
+ */
1054
+ export { PROGRESS_REPORT_SCHEMA_VERSION } from "./progress-report-contract.js";
1055
+ /**
1056
+ * Timestamp validator shared across the progress-report wire schemas. Mirrors
1057
+ * the producer contract's strict RFC3339 validator (calendar + offset bounds +
1058
+ * finite epoch) so the wire layer never admits a timestamp the producer or
1059
+ * reader would reject. Kept local to progress reports; the dashboard-wide
1060
+ * `TimestampSchema` above is intentionally unchanged.
1061
+ */
1062
+ const ProgressReportTimestampSchema = StrictRfc3339TimestampSchema;
1063
+ /**
1064
+ * LIST wire row for a progress report session, camelCase.
1065
+ * Derived by the reader from the producer document's `session` section.
1066
+ */
1067
+ export const ProgressReportRowSchema = z.object({
1068
+ id: ProgressReportSessionIdSchema,
1069
+ title: BoundedTitleSchema,
1070
+ status: z.enum(["running", "paused", "blocked", "done", "failed"]),
1071
+ projectFolder: ProjectFolderPathSchema,
1072
+ startedAt: ProgressReportTimestampSchema,
1073
+ updatedAt: ProgressReportTimestampSchema,
1074
+ agentCount: NonnegativeSafeIntegerSchema,
1075
+ taskCounts: z.object({
1076
+ total: NonnegativeSafeIntegerSchema,
1077
+ done: NonnegativeSafeIntegerSchema,
1078
+ }).optional(),
1079
+ publishedStatus: z.enum(["running", "paused", "blocked", "done", "failed"]).optional(),
1080
+ }).strict();
1081
+ /**
1082
+ * DETAIL wire document for a progress report, camelCase. One camelCase
1083
+ * wire field for each producer field across all 8 sections. The `session`
1084
+ * section is required; the other 7 sections are optional.
1085
+ */
1086
+ export const ProgressReportWireDocumentSchema = z.object({
1087
+ schemaVersion: z.literal(PROGRESS_REPORT_SCHEMA_VERSION),
1088
+ session: z.object({
1089
+ id: ProgressReportSessionIdSchema,
1090
+ title: BoundedTitleSchema,
1091
+ goal: BoundedTitleSchema,
1092
+ status: z.enum(["running", "paused", "blocked", "done", "failed"]),
1093
+ startedAt: ProgressReportTimestampSchema,
1094
+ updatedAt: ProgressReportTimestampSchema,
1095
+ projectFolder: ProjectFolderPathSchema,
1096
+ }).strict(),
1097
+ agents: z.array(z.object({
1098
+ name: BoundedIdSchema,
1099
+ role: BoundedIdSchema,
1100
+ status: z.enum(["working", "idle", "blocked", "done"]),
1101
+ activity: BoundedMessageSchema,
1102
+ updatedAt: ProgressReportTimestampSchema,
1103
+ }).strict()).max(50).optional(),
1104
+ tasks: z.array(z.object({
1105
+ id: BoundedIdSchema,
1106
+ title: BoundedTitleSchema,
1107
+ status: z.enum(["pending", "active", "done", "blocked", "failed"]),
1108
+ agent: BoundedIdSchema.optional(),
1109
+ note: BoundedMessageSchema.optional(),
1110
+ }).strict()).max(200).optional(),
1111
+ log: z.array(z.object({
1112
+ t: ProgressReportTimestampSchema,
1113
+ agent: BoundedIdSchema,
1114
+ kind: z.enum(["info", "success", "warn", "error"]),
1115
+ msg: BoundedMessageSchema,
1116
+ }).strict()).max(200).optional(),
1117
+ files: z.array(z.object({
1118
+ path: BoundedIdSchema,
1119
+ change: z.enum(["added", "modified", "deleted"]),
1120
+ adds: NonnegativeSafeIntegerSchema,
1121
+ dels: NonnegativeSafeIntegerSchema,
1122
+ }).strict()).max(500).optional(),
1123
+ tests: z.object({
1124
+ passed: NonnegativeSafeIntegerSchema,
1125
+ failed: NonnegativeSafeIntegerSchema,
1126
+ skipped: NonnegativeSafeIntegerSchema,
1127
+ failing: z.array(BoundedMessageSchema).max(100),
1128
+ lastRun: ProgressReportTimestampSchema,
1129
+ }).strict().optional(),
1130
+ blockers: z.array(z.object({
1131
+ msg: BoundedMessageSchema,
1132
+ raisedBy: BoundedIdSchema,
1133
+ needsHuman: z.boolean(),
1134
+ }).strict()).max(50).optional(),
1135
+ decisions: z.array(z.object({
1136
+ t: ProgressReportTimestampSchema,
1137
+ by: BoundedIdSchema,
1138
+ msg: BoundedMessageSchema,
1139
+ }).strict()).max(100).optional(),
1140
+ }).strict();
1141
+ /**
1142
+ * Cap on projected progress-report rows surfaced by the list endpoint. The
1143
+ * reader never reads more than this many candidate directories per request.
1144
+ */
1145
+ export const MAX_DASHBOARD_PROGRESS_REPORTS = 200;
1146
+ export const ProgressReportListResponseSchema = z.object({
1147
+ progressReports: z.array(ProgressReportRowSchema).max(MAX_DASHBOARD_PROGRESS_REPORTS),
1148
+ serverNow: ProgressReportTimestampSchema,
1149
+ truncated: z.boolean(),
1150
+ }).strict();
1151
+ export const ProgressReportDetailResponseSchema = z.object({
1152
+ progressReport: ProgressReportWireDocumentSchema,
1153
+ serverNow: ProgressReportTimestampSchema,
1154
+ omittedSections: z.array(z.string()).max(16),
1155
+ publishedSessionStatus: z.enum(["running", "paused", "blocked", "done", "failed"]).optional(),
1156
+ }).strict();
1157
+ //# sourceMappingURL=contracts.js.map