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,1003 @@
1
+ import { link as fsLink, open as fsOpen, mkdir as fsMkdir, readdir as fsReaddir, readFile as fsReadFile, rename as fsRename, rm as fsRm, stat as fsStat, writeFile as fsWriteFile, } from "node:fs/promises";
2
+ import { randomBytes } from "node:crypto";
3
+ import { hostname } from "node:os";
4
+ import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
5
+ import { CancellationError, ExecutionError, InvalidParamsError } from "../errors.js";
6
+ import { validateProspectiveChildPath } from "../paths.js";
7
+ import { contextBuilderInternalCapsForManifest, CONTEXT_BUILDER_INTERNAL_CAP_DEFAULTS, resolveContextBuilderRunsDir, } from "./config.js";
8
+ import { boundContextBuilderOmissions, boundContextBuilderWarnings, } from "./diagnostics.js";
9
+ import { cloneContextBuilderDelegateReceiptMetadata, CONTEXT_BUILDER_DELEGATE_SCHEMA_VERSION, CONTEXT_BUILDER_LEGACY_ARTIFACT_KEYS, CONTEXT_BUILDER_NO_DELEGATE_ARTIFACT_KEYS, CONTEXT_BUILDER_NO_DELEGATE_SCHEMA_VERSION, CONTEXT_BUILDER_SCHEMA_VERSION, isContextBuilderDelegateReceiptMetadata, } from "./receipt.js";
10
+ import { validateCallerRunId } from "./run-id.js";
11
+ import { scanSecretPath } from "./secrets.js";
12
+ export const CONTEXT_BUILDER_ARTIFACT_FILE_NAMES = Object.freeze({
13
+ manifest_json: "manifest.json",
14
+ bundle_md: "bundle.md",
15
+ selected_context_jsonl: "selected-context.jsonl",
16
+ tree_json: "tree.json",
17
+ search_jsonl: "search.jsonl",
18
+ slices_jsonl: "slices.jsonl",
19
+ codemap_jsonl: "codemap.jsonl",
20
+ summary_json: "summary.json",
21
+ });
22
+ const DEFAULT_STORAGE_OPS = {
23
+ mkdir: fsMkdir,
24
+ writeFile: fsWriteFile,
25
+ readFile: fsReadFile,
26
+ rename: fsRename,
27
+ rm: fsRm,
28
+ open: fsOpen,
29
+ link: fsLink,
30
+ stat: fsStat,
31
+ readdir: fsReaddir,
32
+ };
33
+ const CONTEXT_BUILDER_METRIC_TYPES = Object.freeze({
34
+ files_seen: "number",
35
+ files_considered: "number",
36
+ files_selected: "number",
37
+ files_omitted: "number",
38
+ scan_cap_hit: "boolean",
39
+ search_cap_hit: "boolean",
40
+ discovery_byte_cap_hit: "boolean",
41
+ discovery_candidate_cap_hit: "boolean",
42
+ candidate_cap_hit: "boolean",
43
+ bytes_read: "number",
44
+ bytes_written: "number",
45
+ estimated_tokens: "number",
46
+ truncated: "boolean",
47
+ });
48
+ const CONTEXT_BUILDER_INTERNAL_CAP_KEYS = Object.keys(CONTEXT_BUILDER_INTERNAL_CAP_DEFAULTS);
49
+ const CONTEXT_BUILDER_MUTATION_LOCK_SUFFIX = ".mutation.lock";
50
+ const CONTEXT_BUILDER_MUTATION_LOCK_ATTEMPTS = 1_000;
51
+ const CONTEXT_BUILDER_MUTATION_LOCK_RETRY_MS = 10;
52
+ const CONTEXT_BUILDER_STALE_MUTATION_LOCK_MS = 10 * 60 * 1_000;
53
+ export const WORKFLOW_CONTEXT_CACHE_MAX_ENTRIES_ENV = "CLINKX_WORKFLOWS_CONTEXT_CACHE_MAX_ENTRIES";
54
+ export const WORKFLOW_CONTEXT_CACHE_TTL_SECONDS_ENV = "CLINKX_WORKFLOWS_CONTEXT_CACHE_TTL_SECONDS";
55
+ export const DEFAULT_WORKFLOW_CONTEXT_CACHE_MAX_ENTRIES = 50;
56
+ export const DEFAULT_WORKFLOW_CONTEXT_CACHE_TTL_SECONDS = 86_400;
57
+ const DEFAULT_WORKFLOW_CONTEXT_TEMP_TTL_SECONDS = 3_600;
58
+ export function resolveContextBuilderRunPaths(runsDir, runId) {
59
+ validateCallerRunId(runId);
60
+ const resolvedRunsDir = resolve(runsDir);
61
+ const runDir = validateProspectiveChildPath(resolvedRunsDir, runId);
62
+ if (dirname(runDir) !== resolvedRunsDir || basename(runDir) !== runId) {
63
+ throw new InvalidParamsError("context_builder run_id escaped runs directory");
64
+ }
65
+ const artifactDir = join(runDir, "artifacts");
66
+ const artifacts = Object.fromEntries(CONTEXT_BUILDER_NO_DELEGATE_ARTIFACT_KEYS.map((key) => [
67
+ key,
68
+ key === "manifest_json"
69
+ ? join(runDir, CONTEXT_BUILDER_ARTIFACT_FILE_NAMES[key])
70
+ : join(artifactDir, CONTEXT_BUILDER_ARTIFACT_FILE_NAMES[key]),
71
+ ]));
72
+ return {
73
+ runId,
74
+ runsDir: resolvedRunsDir,
75
+ runDir,
76
+ artifactDir,
77
+ buildingJson: join(runDir, ".building.json"),
78
+ manifestJson: artifacts.manifest_json,
79
+ artifacts,
80
+ };
81
+ }
82
+ export async function createContextBuilderRun(input, ops = DEFAULT_STORAGE_OPS) {
83
+ const runsDir = await resolveContextBuilderRunsDir(input.runsDir);
84
+ const ownerNonce = input.ownerNonce ?? randomBytes(16).toString("hex");
85
+ const paths = {
86
+ ...resolveContextBuilderRunPaths(runsDir, input.runId),
87
+ ownerNonce,
88
+ };
89
+ let claimedRunDir = false;
90
+ try {
91
+ await claimContextBuilderRunDir(paths, ops);
92
+ claimedRunDir = true;
93
+ await writeAtomicText(paths.buildingJson, `${JSON.stringify({
94
+ schema_version: CONTEXT_BUILDER_SCHEMA_VERSION,
95
+ run_id: input.runId,
96
+ pid: process.pid,
97
+ hostname: hostname(),
98
+ created_at: input.createdAt,
99
+ owner_nonce: ownerNonce,
100
+ })}\n`, ops);
101
+ await ops.mkdir(paths.artifactDir, { recursive: false, mode: 0o700 });
102
+ }
103
+ catch (error) {
104
+ if (claimedRunDir) {
105
+ const cleanupDecision = await canRemoveIncompleteRunDir(paths, ownerNonce, ops);
106
+ if (cleanupDecision.removable) {
107
+ await (ops.rm ?? fsRm)(paths.runDir, {
108
+ recursive: true,
109
+ force: true,
110
+ }).catch(() => { });
111
+ }
112
+ else {
113
+ throw new ExecutionError(`context_builder refused setup cleanup for ${input.runId}: ${cleanupDecision.reason}`);
114
+ }
115
+ }
116
+ throw error;
117
+ }
118
+ return paths;
119
+ }
120
+ export async function writeContextBuilderArtifact(storage, key, content, ops = DEFAULT_STORAGE_OPS) {
121
+ const canonicalStorage = canonicalizeContextBuilderStorage(storage);
122
+ await withContextBuilderMutationLock(canonicalStorage, ops, async () => {
123
+ await assertManifestAbsentForMutation(canonicalStorage, ops);
124
+ await writeAtomicText(canonicalStorage.artifacts[key], content, ops, {
125
+ mustNotExistPath: canonicalStorage.manifestJson,
126
+ });
127
+ }, { ownerNonce: canonicalStorage.ownerNonce });
128
+ }
129
+ export async function commitContextBuilderRun(storage, manifest, optionsOrOps = {}, maybeOps = DEFAULT_STORAGE_OPS) {
130
+ const { options, ops } = normalizeCommitArguments(optionsOrOps, maybeOps);
131
+ const canonicalStorage = canonicalizeContextBuilderStorage(storage);
132
+ const ownerNonce = options.ownerNonce ?? canonicalStorage.ownerNonce;
133
+ await withContextBuilderMutationLock(canonicalStorage, ops, async () => {
134
+ await assertManifestAbsentForMutation(canonicalStorage, ops);
135
+ await assertRequiredArtifactsReadable(canonicalStorage, ops);
136
+ throwIfCancelledBeforeManifest(options);
137
+ const internalCaps = contextBuilderInternalCapsForManifest(manifest.internal_caps);
138
+ const { delegate, ...manifestWithoutDelegate } = manifest;
139
+ const boundedDelegate = normalizeManifestDelegateMetadata(delegate);
140
+ const completeManifest = {
141
+ ...manifestWithoutDelegate,
142
+ schema_version: schemaVersionForManifestDelegate(boundedDelegate),
143
+ run_id: canonicalStorage.runId,
144
+ internal_caps: internalCaps,
145
+ artifacts: { ...canonicalStorage.artifacts },
146
+ warnings: boundContextBuilderWarnings(normalizeContextBuilderWarnings(manifest.warnings), internalCaps),
147
+ omissions: boundContextBuilderOmissions(normalizeContextBuilderOmissions(manifest.omissions), internalCaps),
148
+ ...(boundedDelegate == null ? {} : { delegate: boundedDelegate }),
149
+ };
150
+ await writeExclusiveText(canonicalStorage.manifestJson, `${JSON.stringify(completeManifest)}\n`, ops, options.signal === undefined ? {} : { signal: options.signal });
151
+ }, { ownerNonce });
152
+ }
153
+ export async function writeContextBuilderArtifactsAndCommit(storage, contents, manifest, options = {}) {
154
+ const ops = options.ops ?? DEFAULT_STORAGE_OPS;
155
+ const canonicalStorage = canonicalizeContextBuilderStorage(storage);
156
+ const ownerNonce = options.ownerNonce ?? canonicalStorage.ownerNonce;
157
+ await withContextBuilderMutationLock(canonicalStorage, ops, async () => {
158
+ await assertManifestAbsentForMutation(canonicalStorage, ops);
159
+ for (const [key, content] of Object.entries(contents)) {
160
+ if (options.signal?.aborted === true) {
161
+ throw new CancellationError();
162
+ }
163
+ await writeAtomicText(canonicalStorage.artifacts[key], content, ops, { mustNotExistPath: canonicalStorage.manifestJson });
164
+ }
165
+ throwIfCancelledBeforeManifest(options.signal === undefined ? {} : { signal: options.signal });
166
+ await assertRequiredArtifactsReadable(canonicalStorage, ops);
167
+ await options.beforeManifestCommit?.();
168
+ const internalCaps = contextBuilderInternalCapsForManifest(manifest.internal_caps);
169
+ const { delegate, ...manifestWithoutDelegate } = manifest;
170
+ const boundedDelegate = normalizeManifestDelegateMetadata(delegate);
171
+ const completeManifest = {
172
+ ...manifestWithoutDelegate,
173
+ schema_version: schemaVersionForManifestDelegate(boundedDelegate),
174
+ run_id: canonicalStorage.runId,
175
+ internal_caps: internalCaps,
176
+ artifacts: { ...canonicalStorage.artifacts },
177
+ warnings: boundContextBuilderWarnings(normalizeContextBuilderWarnings(manifest.warnings), internalCaps),
178
+ omissions: boundContextBuilderOmissions(normalizeContextBuilderOmissions(manifest.omissions), internalCaps),
179
+ ...(boundedDelegate == null ? {} : { delegate: boundedDelegate }),
180
+ };
181
+ await writeExclusiveText(canonicalStorage.manifestJson, `${JSON.stringify(completeManifest)}\n`, ops, options.signal === undefined ? {} : { signal: options.signal });
182
+ }, { ownerNonce });
183
+ }
184
+ export async function promoteContextBuilderRun(tempRunDir, targetRunId, ops = DEFAULT_STORAGE_OPS) {
185
+ const resolvedTempRunDir = resolve(tempRunDir);
186
+ const tempManifest = await readContextBuilderManifest(join(resolvedTempRunDir, "manifest.json"), ops);
187
+ const tempStorage = resolveContextBuilderRunPaths(dirname(resolvedTempRunDir), tempManifest.run_id);
188
+ if (tempStorage.runDir !== resolvedTempRunDir
189
+ || !await isContextBuilderRunCommitted(resolvedTempRunDir, ops)) {
190
+ throw new ExecutionError("context_builder cannot promote an uncommitted or mismatched temp run");
191
+ }
192
+ const targetStorage = resolveContextBuilderRunPaths(tempStorage.runsDir, targetRunId);
193
+ await claimContextBuilderRunDir(targetStorage, ops);
194
+ try {
195
+ await ops.mkdir(targetStorage.artifactDir, { recursive: false, mode: 0o700 });
196
+ await withContextBuilderMutationLock(targetStorage, ops, async () => {
197
+ await assertManifestAbsentForMutation(targetStorage, ops);
198
+ const artifactEntries = Object.entries(tempManifest.artifacts);
199
+ for (const [key, sourcePath] of artifactEntries) {
200
+ if (key === "manifest_json") {
201
+ continue;
202
+ }
203
+ const targetPath = targetStorage.artifacts[key];
204
+ const sourceContent = await ops.readFile(sourcePath, "utf8");
205
+ const targetContent = key === "summary_json"
206
+ ? rewriteContextBuilderSummaryRunId(sourceContent, targetRunId)
207
+ : sourceContent;
208
+ await writeAtomicText(targetPath, targetContent, ops, {
209
+ mustNotExistPath: targetStorage.manifestJson,
210
+ });
211
+ }
212
+ const targetArtifacts = Object.fromEntries(Object.keys(tempManifest.artifacts).map((key) => [
213
+ key,
214
+ targetStorage.artifacts[key],
215
+ ]));
216
+ const targetManifest = {
217
+ ...tempManifest,
218
+ run_id: targetRunId,
219
+ artifacts: targetArtifacts,
220
+ };
221
+ await writeExclusiveText(targetStorage.manifestJson, `${JSON.stringify(targetManifest)}\n`, ops);
222
+ });
223
+ if (!await isContextBuilderRunCommitted(targetStorage.runDir, ops)) {
224
+ throw new ExecutionError(`context_builder promoted run failed validation: ${targetRunId}`);
225
+ }
226
+ }
227
+ catch (error) {
228
+ // The target dir was claimed above, so always clean it up on failure.
229
+ await (ops.rm ?? fsRm)(targetStorage.runDir, {
230
+ recursive: true,
231
+ force: true,
232
+ }).catch(() => { });
233
+ await syncDirectoryBestEffort(targetStorage.runsDir, ops);
234
+ throw error;
235
+ }
236
+ await (ops.rm ?? fsRm)(resolvedTempRunDir, { recursive: true, force: true })
237
+ .catch(() => { });
238
+ await syncDirectoryBestEffort(tempStorage.runsDir, ops);
239
+ return targetStorage;
240
+ }
241
+ export async function evictWorkflowContextRuns(runsDir, options = {}) {
242
+ const ops = options.ops ?? DEFAULT_STORAGE_OPS;
243
+ const readdir = ops.readdir ?? fsReaddir;
244
+ const stat = ops.stat ?? fsStat;
245
+ const resolvedRunsDir = await resolveContextBuilderRunsDir(runsDir);
246
+ const bounds = resolveWorkflowContextEvictionBounds(options);
247
+ const nowMs = options.nowMs ?? Date.now();
248
+ const protectedRunIds = new Set(options.protectedRunIds ?? []);
249
+ const entries = await readdir(resolvedRunsDir, { withFileTypes: true });
250
+ const committedCacheEntries = [];
251
+ const removeSet = new Map();
252
+ let scanned = 0;
253
+ let skipped = 0;
254
+ let failed = 0;
255
+ for (const entry of entries) {
256
+ if (!entry.isDirectory() || !isWorkflowContextRunId(entry.name)) {
257
+ continue;
258
+ }
259
+ scanned += 1;
260
+ try {
261
+ const storage = resolveContextBuilderRunPaths(resolvedRunsDir, entry.name);
262
+ const runStat = await stat(storage.runDir).catch((error) => {
263
+ if (isNodeError(error) && error.code === "ENOENT") {
264
+ return undefined;
265
+ }
266
+ throw error;
267
+ });
268
+ if (runStat === undefined) {
269
+ skipped += 1;
270
+ continue;
271
+ }
272
+ if (!await isContextBuilderRunCommitted(storage.runDir, ops)) {
273
+ skipped += 1;
274
+ continue;
275
+ }
276
+ const isProtected = protectedRunIds.has(storage.runId);
277
+ if (entry.name.startsWith("wfctx-")) {
278
+ // Protected cache entries are excluded from LRU survivor accounting so
279
+ // they can never be selected for the max-entries trim below either.
280
+ if (!isProtected) {
281
+ committedCacheEntries.push({ storage, mtimeMs: runStat.mtimeMs });
282
+ }
283
+ if (nowMs - runStat.mtimeMs > bounds.cacheTtlMs) {
284
+ if (isProtected) {
285
+ skipped += 1;
286
+ }
287
+ else {
288
+ removeSet.set(storage.runId, storage);
289
+ }
290
+ }
291
+ continue;
292
+ }
293
+ if (nowMs - runStat.mtimeMs > bounds.tempTtlMs) {
294
+ if (isProtected) {
295
+ skipped += 1;
296
+ }
297
+ else {
298
+ removeSet.set(storage.runId, storage);
299
+ }
300
+ }
301
+ }
302
+ catch {
303
+ failed += 1;
304
+ }
305
+ }
306
+ const cacheSurvivors = committedCacheEntries
307
+ .filter(({ storage }) => !removeSet.has(storage.runId))
308
+ .sort((a, b) => a.mtimeMs - b.mtimeMs)
309
+ .map(({ storage }) => storage);
310
+ cacheSurvivors
311
+ .slice(0, Math.max(0, cacheSurvivors.length - bounds.maxEntries))
312
+ .forEach((storage) => removeSet.set(storage.runId, storage));
313
+ let evicted = 0;
314
+ for (const storage of removeSet.values()) {
315
+ try {
316
+ const didRemove = await removeCommittedWorkflowContextRun(storage, ops);
317
+ if (didRemove) {
318
+ evicted += 1;
319
+ }
320
+ else {
321
+ skipped += 1;
322
+ }
323
+ }
324
+ catch (error) {
325
+ if (isNodeError(error) && error.code === "ENOENT") {
326
+ skipped += 1;
327
+ }
328
+ else {
329
+ failed += 1;
330
+ }
331
+ }
332
+ }
333
+ if (evicted > 0) {
334
+ await syncDirectoryBestEffort(resolvedRunsDir, ops);
335
+ }
336
+ return { scanned, evicted, skipped, failed };
337
+ }
338
+ export async function cleanupContextBuilderIncompleteRun(storage, ownerNonce, ops = DEFAULT_STORAGE_OPS) {
339
+ const canonicalStorage = canonicalizeContextBuilderStorage(storage);
340
+ return withContextBuilderMutationLock(canonicalStorage, ops, async () => cleanupContextBuilderIncompleteRunLocked(canonicalStorage, ownerNonce, ops), {
341
+ ownerNonce,
342
+ recoverStaleForCleanup: true,
343
+ });
344
+ }
345
+ /**
346
+ * Hold the existing per-run mutation lock while a committed run is consumed.
347
+ * Writers and pruning use the same lock, so the callback may safely materialize
348
+ * artifact paths without the run directory disappearing underneath it.
349
+ */
350
+ export async function withContextBuilderRunMutationLease(storage, callback, ops = DEFAULT_STORAGE_OPS) {
351
+ const canonicalStorage = canonicalizeContextBuilderStorage(storage);
352
+ return await withContextBuilderMutationLock(canonicalStorage, ops, callback);
353
+ }
354
+ async function cleanupContextBuilderIncompleteRunLocked(storage, ownerNonce, ops) {
355
+ if (!await mayRemoveIncompleteRunDir(storage, ownerNonce, ops)) {
356
+ return false;
357
+ }
358
+ await (ops.rm ?? fsRm)(storage.runDir, {
359
+ recursive: true,
360
+ force: true,
361
+ });
362
+ await syncDirectoryBestEffort(storage.runsDir, ops);
363
+ return true;
364
+ }
365
+ export async function isContextBuilderRunCommitted(runDir, ops = DEFAULT_STORAGE_OPS) {
366
+ try {
367
+ const resolvedRunDir = resolve(runDir);
368
+ const parsed = JSON.parse(await ops.readFile(join(resolvedRunDir, "manifest.json"), "utf8"));
369
+ if (!isValidContextBuilderManifest(parsed, basename(resolvedRunDir))) {
370
+ return false;
371
+ }
372
+ const expectedStorage = resolveContextBuilderRunPaths(dirname(resolvedRunDir), parsed.run_id);
373
+ if (expectedStorage.runDir !== resolvedRunDir) {
374
+ return false;
375
+ }
376
+ const artifactKeys = supportedArtifactKeys(parsed.artifacts);
377
+ if (artifactKeys == null
378
+ || !artifactPathsExactlyMatch(parsed.artifacts, expectedStorage.artifacts, artifactKeys)) {
379
+ return false;
380
+ }
381
+ await assertRequiredArtifactsReadable(expectedStorage, ops, artifactKeys);
382
+ return true;
383
+ }
384
+ catch {
385
+ return false;
386
+ }
387
+ }
388
+ function canonicalizeContextBuilderStorage(storage) {
389
+ const expected = resolveContextBuilderRunPaths(storage.runsDir, storage.runId);
390
+ if (storage.runDir !== expected.runDir
391
+ || storage.artifactDir !== expected.artifactDir
392
+ || storage.buildingJson !== expected.buildingJson
393
+ || storage.manifestJson !== expected.manifestJson
394
+ || !artifactPathsExactlyMatch(storage.artifacts, expected.artifacts, CONTEXT_BUILDER_NO_DELEGATE_ARTIFACT_KEYS)) {
395
+ throw new ExecutionError("context_builder storage paths do not match run_id and runs_dir");
396
+ }
397
+ return storage.ownerNonce === undefined
398
+ ? expected
399
+ : { ...expected, ownerNonce: storage.ownerNonce };
400
+ }
401
+ async function readContextBuilderManifest(manifestPath, ops) {
402
+ let parsed;
403
+ try {
404
+ parsed = JSON.parse(await ops.readFile(manifestPath, "utf8"));
405
+ }
406
+ catch (error) {
407
+ throw new ExecutionError(`context_builder cannot read manifest for promotion: ${nodeErrorCode(error)}`);
408
+ }
409
+ const parsedRunId = parsed !== null && typeof parsed === "object"
410
+ ? parsed.run_id
411
+ : undefined;
412
+ if (typeof parsedRunId !== "string"
413
+ || !isValidContextBuilderManifest(parsed, parsedRunId)) {
414
+ throw new ExecutionError("context_builder cannot promote run with an invalid manifest");
415
+ }
416
+ return parsed;
417
+ }
418
+ function rewriteContextBuilderSummaryRunId(summaryText, targetRunId) {
419
+ let parsed;
420
+ try {
421
+ parsed = JSON.parse(summaryText);
422
+ }
423
+ catch {
424
+ throw new ExecutionError("context_builder cannot promote run with an invalid summary artifact");
425
+ }
426
+ if (parsed === null || typeof parsed !== "object") {
427
+ throw new ExecutionError("context_builder cannot promote run with an invalid summary artifact");
428
+ }
429
+ return `${JSON.stringify({
430
+ ...parsed,
431
+ run_id: targetRunId,
432
+ })}\n`;
433
+ }
434
+ async function mayRemoveIncompleteRunDir(storage, ownerNonce, ops) {
435
+ return (await canRemoveIncompleteRunDir(storage, ownerNonce, ops)).removable;
436
+ }
437
+ async function canRemoveIncompleteRunDir(storage, ownerNonce, ops) {
438
+ const resolvedRunsDir = resolve(storage.runsDir);
439
+ const resolvedRunDir = resolve(storage.runDir);
440
+ if (!isPathInsideDirectory(resolvedRunDir, resolvedRunsDir)) {
441
+ return { removable: false, reason: "run directory is outside runs directory" };
442
+ }
443
+ const manifestDecision = await manifestCleanupDecision(storage, ops);
444
+ if (!manifestDecision.removable) {
445
+ return manifestDecision;
446
+ }
447
+ let building;
448
+ try {
449
+ building = JSON.parse(await ops.readFile(storage.buildingJson, "utf8"));
450
+ }
451
+ catch {
452
+ return { removable: false, reason: "missing marker" };
453
+ }
454
+ if (building === null
455
+ || typeof building !== "object"
456
+ || building.owner_nonce !== ownerNonce) {
457
+ return { removable: false, reason: "owner mismatch" };
458
+ }
459
+ return { removable: true };
460
+ }
461
+ async function manifestCleanupDecision(storage, ops) {
462
+ try {
463
+ await ops.readFile(storage.manifestJson, "utf8");
464
+ return { removable: false, reason: "manifest exists" };
465
+ }
466
+ catch (error) {
467
+ if (isNodeError(error) && error.code === "ENOENT") {
468
+ return { removable: true };
469
+ }
470
+ return {
471
+ removable: false,
472
+ reason: `manifest unreadable: ${nodeErrorCode(error)}`,
473
+ };
474
+ }
475
+ }
476
+ async function claimContextBuilderRunDir(paths, ops) {
477
+ try {
478
+ await ops.mkdir(paths.runDir, { recursive: false, mode: 0o700 });
479
+ }
480
+ catch (error) {
481
+ if (isNodeError(error) && error.code === "EEXIST") {
482
+ if (await isContextBuilderRunCommitted(paths.runDir, ops)) {
483
+ throw new InvalidParamsError(`context_builder run_id already exists: ${paths.runId}`);
484
+ }
485
+ throw new ExecutionError(`context_builder run_id conflicts with an incomplete or active run: ${paths.runId}`);
486
+ }
487
+ throw error;
488
+ }
489
+ }
490
+ function throwIfCancelledBeforeManifest(options) {
491
+ if (options.signal?.aborted !== true) {
492
+ return;
493
+ }
494
+ throw new CancellationError();
495
+ }
496
+ function normalizeCommitArguments(optionsOrOps, maybeOps) {
497
+ if (isStorageOps(optionsOrOps)) {
498
+ return { options: {}, ops: optionsOrOps };
499
+ }
500
+ return { options: optionsOrOps, ops: maybeOps };
501
+ }
502
+ function isStorageOps(value) {
503
+ return ("mkdir" in value
504
+ || "writeFile" in value
505
+ || "readFile" in value
506
+ || "rename" in value
507
+ || "rm" in value
508
+ || "open" in value
509
+ || "link" in value);
510
+ }
511
+ async function withContextBuilderMutationLock(storage, ops, callback, options = {}) {
512
+ const lockPath = mutationLockPathForStorage(storage);
513
+ const lockHandle = await acquireContextBuilderMutationLock(storage, lockPath, ops, options);
514
+ try {
515
+ return await callback();
516
+ }
517
+ finally {
518
+ await lockHandle.close().catch(() => { });
519
+ await (ops.rm ?? fsRm)(lockPath, { force: true }).catch(() => { });
520
+ }
521
+ }
522
+ async function acquireContextBuilderMutationLock(storage, lockPath, ops, options) {
523
+ const open = ops.open ?? fsOpen;
524
+ for (let attempt = 0; attempt < CONTEXT_BUILDER_MUTATION_LOCK_ATTEMPTS; attempt += 1) {
525
+ try {
526
+ const handle = await open(lockPath, "wx", 0o600);
527
+ try {
528
+ await writeMutationLockMetadata(handle, options.ownerNonce);
529
+ return handle;
530
+ }
531
+ catch (error) {
532
+ await handle.close().catch(() => { });
533
+ await (ops.rm ?? fsRm)(lockPath, { force: true }).catch(() => { });
534
+ throw error;
535
+ }
536
+ }
537
+ catch (error) {
538
+ if (isNodeError(error) && error.code === "EEXIST") {
539
+ if (options.recoverStaleForCleanup === true
540
+ && await breakStaleCleanupMutationLock(storage, lockPath, options.ownerNonce, ops)) {
541
+ continue;
542
+ }
543
+ await delay(CONTEXT_BUILDER_MUTATION_LOCK_RETRY_MS);
544
+ continue;
545
+ }
546
+ throw error;
547
+ }
548
+ }
549
+ throw new ExecutionError("context_builder timed out waiting for the run mutation lock");
550
+ }
551
+ function mutationLockPathForStorage(storage) {
552
+ validateCallerRunId(storage.runId);
553
+ const resolvedRunsDir = resolve(storage.runsDir);
554
+ const resolvedRunDir = resolve(storage.runDir);
555
+ if (!isPathInsideDirectory(resolvedRunDir, resolvedRunsDir)) {
556
+ throw new ExecutionError("context_builder refused mutation lock outside runs directory");
557
+ }
558
+ return join(resolvedRunsDir, `.${storage.runId}${CONTEXT_BUILDER_MUTATION_LOCK_SUFFIX}`);
559
+ }
560
+ async function writeMutationLockMetadata(handle, ownerNonce) {
561
+ const metadata = {
562
+ pid: process.pid,
563
+ hostname: hostname(),
564
+ created_at: new Date().toISOString(),
565
+ ...(ownerNonce == null ? {} : { owner_nonce: ownerNonce }),
566
+ };
567
+ await handle.writeFile(`${JSON.stringify(metadata)}\n`, { encoding: "utf8" });
568
+ }
569
+ async function breakStaleCleanupMutationLock(storage, lockPath, ownerNonce, ops) {
570
+ if (ownerNonce == null) {
571
+ return false;
572
+ }
573
+ const cleanupDecision = await canRemoveIncompleteRunDir(storage, ownerNonce, ops);
574
+ if (!cleanupDecision.removable) {
575
+ return false;
576
+ }
577
+ if (!await isMutationLockOldEnough(lockPath, ops)) {
578
+ return false;
579
+ }
580
+ const metadata = await readMutationLockMetadata(lockPath, ops);
581
+ if (metadata !== "invalid" && !isStaleMutationLockMetadata(metadata)) {
582
+ return false;
583
+ }
584
+ await (ops.rm ?? fsRm)(lockPath, { force: true }).catch(() => { });
585
+ return true;
586
+ }
587
+ async function isMutationLockOldEnough(lockPath, ops) {
588
+ const stat = ops.stat ?? fsStat;
589
+ try {
590
+ const lockStat = await stat(lockPath);
591
+ return Date.now() - lockStat.mtimeMs >= CONTEXT_BUILDER_STALE_MUTATION_LOCK_MS;
592
+ }
593
+ catch {
594
+ return false;
595
+ }
596
+ }
597
+ async function readMutationLockMetadata(lockPath, ops) {
598
+ let parsed;
599
+ try {
600
+ parsed = JSON.parse(await ops.readFile(lockPath, "utf8"));
601
+ }
602
+ catch {
603
+ return "invalid";
604
+ }
605
+ if (parsed === null || typeof parsed !== "object") {
606
+ return "invalid";
607
+ }
608
+ const metadata = parsed;
609
+ if (typeof metadata.pid !== "number"
610
+ || !Number.isInteger(metadata.pid)
611
+ || typeof metadata.hostname !== "string"
612
+ || typeof metadata.created_at !== "string") {
613
+ return "invalid";
614
+ }
615
+ if (metadata.owner_nonce !== undefined
616
+ && typeof metadata.owner_nonce !== "string") {
617
+ return "invalid";
618
+ }
619
+ return {
620
+ pid: metadata.pid,
621
+ hostname: metadata.hostname,
622
+ created_at: metadata.created_at,
623
+ ...(metadata.owner_nonce === undefined
624
+ ? {}
625
+ : { owner_nonce: metadata.owner_nonce }),
626
+ };
627
+ }
628
+ function isStaleMutationLockMetadata(metadata) {
629
+ const createdAtMs = Date.parse(metadata.created_at);
630
+ if (!Number.isFinite(createdAtMs)
631
+ || Date.now() - createdAtMs < CONTEXT_BUILDER_STALE_MUTATION_LOCK_MS) {
632
+ return false;
633
+ }
634
+ if (metadata.hostname !== hostname()) {
635
+ return false;
636
+ }
637
+ return !isProcessAlive(metadata.pid);
638
+ }
639
+ function isProcessAlive(pid) {
640
+ if (pid <= 0) {
641
+ return false;
642
+ }
643
+ try {
644
+ process.kill(pid, 0);
645
+ return true;
646
+ }
647
+ catch (error) {
648
+ return !(isNodeError(error) && error.code === "ESRCH");
649
+ }
650
+ }
651
+ async function assertRequiredArtifactsReadable(storage, ops, artifactKeys = CONTEXT_BUILDER_NO_DELEGATE_ARTIFACT_KEYS) {
652
+ const missing = [];
653
+ for (const key of artifactKeys) {
654
+ if (key === "manifest_json") {
655
+ continue;
656
+ }
657
+ try {
658
+ await ops.readFile(storage.artifacts[key], "utf8");
659
+ }
660
+ catch {
661
+ missing.push(key);
662
+ }
663
+ }
664
+ if (missing.length > 0) {
665
+ throw new Error(`context_builder cannot commit before required artifacts exist: ${missing.join(", ")}`);
666
+ }
667
+ }
668
+ async function assertManifestAbsentForMutation(storage, ops) {
669
+ try {
670
+ await ops.readFile(storage.manifestJson, "utf8");
671
+ }
672
+ catch (error) {
673
+ if (isNodeError(error) && error.code === "ENOENT") {
674
+ return;
675
+ }
676
+ throw new ExecutionError(`context_builder cannot mutate committed run: manifest unreadable (${nodeErrorCode(error)})`);
677
+ }
678
+ throw new ExecutionError("context_builder cannot mutate committed run: manifest already exists");
679
+ }
680
+ function artifactPathsExactlyMatch(actual, expected, artifactKeys) {
681
+ if (!hasExactArtifactKeys(actual, artifactKeys)) {
682
+ return false;
683
+ }
684
+ for (const key of artifactKeys) {
685
+ if (actual[key] !== expected[key]) {
686
+ return false;
687
+ }
688
+ }
689
+ return true;
690
+ }
691
+ function isValidContextBuilderManifest(value, expectedRunId) {
692
+ if (value === null || typeof value !== "object") {
693
+ return false;
694
+ }
695
+ const manifest = value;
696
+ const hasDelegate = Object.prototype.hasOwnProperty.call(manifest, "delegate");
697
+ const hasValidDelegate = isContextBuilderDelegateReceiptMetadata(manifest.delegate);
698
+ const hasValidVersionedDelegate = (manifest.schema_version === CONTEXT_BUILDER_NO_DELEGATE_SCHEMA_VERSION
699
+ && !hasDelegate)
700
+ || (manifest.schema_version === CONTEXT_BUILDER_DELEGATE_SCHEMA_VERSION
701
+ && hasDelegate
702
+ && hasValidDelegate);
703
+ return (hasValidVersionedDelegate
704
+ && manifest.run_id === expectedRunId
705
+ && (manifest.status === "succeeded" || manifest.status === "partial")
706
+ && hasRequiredInternalCaps(manifest.internal_caps)
707
+ && hasRequiredArtifactPaths(manifest.artifacts)
708
+ && hasRequiredMetrics(manifest.metrics)
709
+ && Array.isArray(manifest.warnings)
710
+ && Array.isArray(manifest.omissions));
711
+ }
712
+ function normalizeManifestDelegateMetadata(delegate) {
713
+ if (delegate === undefined) {
714
+ return undefined;
715
+ }
716
+ if (delegate === null || typeof delegate !== "object") {
717
+ throw new ExecutionError("context_builder manifest delegate metadata is invalid");
718
+ }
719
+ const bounded = cloneContextBuilderDelegateReceiptMetadata(delegate);
720
+ if (!isContextBuilderDelegateReceiptMetadata(bounded)) {
721
+ throw new ExecutionError("context_builder manifest delegate metadata is invalid");
722
+ }
723
+ return bounded;
724
+ }
725
+ function schemaVersionForManifestDelegate(delegate) {
726
+ return delegate == null
727
+ ? CONTEXT_BUILDER_NO_DELEGATE_SCHEMA_VERSION
728
+ : CONTEXT_BUILDER_DELEGATE_SCHEMA_VERSION;
729
+ }
730
+ function hasRequiredInternalCaps(value) {
731
+ if (value === null || typeof value !== "object") {
732
+ return false;
733
+ }
734
+ const caps = value;
735
+ return CONTEXT_BUILDER_INTERNAL_CAP_KEYS.every((key) => (typeof caps[key] === "number"));
736
+ }
737
+ function hasRequiredArtifactPaths(value) {
738
+ if (value === null || typeof value !== "object") {
739
+ return false;
740
+ }
741
+ const artifacts = value;
742
+ const artifactKeys = supportedArtifactKeys(artifacts);
743
+ return artifactKeys != null && artifactKeys.every((key) => (typeof artifacts[key] === "string"));
744
+ }
745
+ function supportedArtifactKeys(value) {
746
+ if (hasExactArtifactKeys(value, CONTEXT_BUILDER_NO_DELEGATE_ARTIFACT_KEYS)) {
747
+ return CONTEXT_BUILDER_NO_DELEGATE_ARTIFACT_KEYS;
748
+ }
749
+ if (hasExactArtifactKeys(value, CONTEXT_BUILDER_LEGACY_ARTIFACT_KEYS)) {
750
+ return CONTEXT_BUILDER_LEGACY_ARTIFACT_KEYS;
751
+ }
752
+ return undefined;
753
+ }
754
+ function hasExactArtifactKeys(value, expectedArtifactKeys) {
755
+ const expectedKeys = new Set(expectedArtifactKeys);
756
+ const actualKeys = Object.keys(value);
757
+ return (actualKeys.length === expectedArtifactKeys.length
758
+ && actualKeys.every((key) => expectedKeys.has(key)));
759
+ }
760
+ function hasRequiredMetrics(value) {
761
+ if (value === null || typeof value !== "object") {
762
+ return false;
763
+ }
764
+ const metrics = value;
765
+ return Object.entries(CONTEXT_BUILDER_METRIC_TYPES).every(([key, expectedType]) => typeof metrics[key] === expectedType);
766
+ }
767
+ async function writeAtomicText(finalPath, content, ops, options = {}) {
768
+ let tempPath = "";
769
+ let handle;
770
+ try {
771
+ const opened = await openExclusiveTempFile(finalPath, ops);
772
+ tempPath = opened.tempPath;
773
+ handle = opened.handle;
774
+ await handle.writeFile(content, { encoding: "utf8" });
775
+ await handle.sync();
776
+ await handle.close();
777
+ handle = undefined;
778
+ if (options.mustNotExistPath != null) {
779
+ await assertPathAbsentForMutation(options.mustNotExistPath, ops);
780
+ }
781
+ await ops.rename(tempPath, finalPath);
782
+ tempPath = "";
783
+ await syncDirectoryBestEffort(dirname(finalPath), ops);
784
+ }
785
+ finally {
786
+ if (handle !== undefined) {
787
+ await handle.close().catch(() => { });
788
+ }
789
+ if (tempPath !== "") {
790
+ await (ops.rm ?? fsRm)(tempPath, { force: true }).catch(() => { });
791
+ }
792
+ }
793
+ }
794
+ async function writeExclusiveText(finalPath, content, ops, options = {}) {
795
+ let tempPath = "";
796
+ let handle;
797
+ try {
798
+ const opened = await openExclusiveTempFile(finalPath, ops);
799
+ tempPath = opened.tempPath;
800
+ handle = opened.handle;
801
+ await handle.writeFile(content, { encoding: "utf8" });
802
+ await handle.sync();
803
+ await handle.close();
804
+ handle = undefined;
805
+ throwIfCancelledBeforeManifest(options);
806
+ await linkNoClobber(tempPath, finalPath, ops);
807
+ await (ops.rm ?? fsRm)(tempPath, { force: true }).catch(() => { });
808
+ tempPath = "";
809
+ await syncDirectoryBestEffort(dirname(finalPath), ops);
810
+ }
811
+ finally {
812
+ if (handle !== undefined) {
813
+ await handle.close().catch(() => { });
814
+ }
815
+ if (tempPath !== "") {
816
+ await (ops.rm ?? fsRm)(tempPath, { force: true }).catch(() => { });
817
+ }
818
+ }
819
+ }
820
+ async function linkNoClobber(existingPath, newPath, ops) {
821
+ const link = ops.link ?? fsLink;
822
+ try {
823
+ await link(existingPath, newPath);
824
+ }
825
+ catch (error) {
826
+ if (isNodeError(error) && error.code === "EEXIST") {
827
+ throw new ExecutionError("context_builder cannot mutate committed run: manifest already exists");
828
+ }
829
+ throw error;
830
+ }
831
+ }
832
+ async function assertPathAbsentForMutation(path, ops) {
833
+ try {
834
+ await ops.readFile(path, "utf8");
835
+ }
836
+ catch (error) {
837
+ if (isNodeError(error) && error.code === "ENOENT") {
838
+ return;
839
+ }
840
+ throw new ExecutionError(`context_builder cannot mutate committed run: manifest unreadable (${nodeErrorCode(error)})`);
841
+ }
842
+ throw new ExecutionError("context_builder cannot mutate committed run: manifest already exists");
843
+ }
844
+ async function openExclusiveTempFile(finalPath, ops) {
845
+ const open = ops.open ?? fsOpen;
846
+ for (let attempt = 0; attempt < 10; attempt += 1) {
847
+ const tempPath = `${finalPath}.${process.pid}.${randomBytes(8).toString("hex")}.tmp`;
848
+ try {
849
+ return {
850
+ tempPath,
851
+ handle: await open(tempPath, "wx", 0o600),
852
+ };
853
+ }
854
+ catch (error) {
855
+ if (isNodeError(error) && error.code === "EEXIST") {
856
+ continue;
857
+ }
858
+ throw error;
859
+ }
860
+ }
861
+ throw new Error("context_builder failed to create an exclusive temp file");
862
+ }
863
+ async function syncDirectoryBestEffort(path, ops) {
864
+ let handle;
865
+ const open = ops.open ?? fsOpen;
866
+ try {
867
+ handle = await open(path, "r");
868
+ await handle.sync();
869
+ }
870
+ catch {
871
+ return;
872
+ }
873
+ finally {
874
+ if (handle !== undefined) {
875
+ await handle.close().catch(() => { });
876
+ }
877
+ }
878
+ }
879
+ async function removeCommittedWorkflowContextRun(storage, ops) {
880
+ if (!isWorkflowContextRunId(storage.runId)) {
881
+ return false;
882
+ }
883
+ return await withContextBuilderMutationLock(storage, ops, async () => {
884
+ if (!await isContextBuilderRunCommitted(storage.runDir, ops)) {
885
+ return false;
886
+ }
887
+ await (ops.rm ?? fsRm)(storage.runDir, { recursive: true, force: true });
888
+ return true;
889
+ });
890
+ }
891
+ function isWorkflowContextRunId(runId) {
892
+ return runId.startsWith("wfctx-") || runId.startsWith("wfpre-");
893
+ }
894
+ function resolveWorkflowContextEvictionBounds(options) {
895
+ const env = options.env ?? process.env;
896
+ const maxEntries = normalizeNonNegativeInteger(options.maxEntries, parseNonNegativeInteger(env[WORKFLOW_CONTEXT_CACHE_MAX_ENTRIES_ENV], DEFAULT_WORKFLOW_CONTEXT_CACHE_MAX_ENTRIES));
897
+ const cacheTtlSeconds = normalizeNonNegativeInteger(options.cacheTtlSeconds, parseNonNegativeInteger(env[WORKFLOW_CONTEXT_CACHE_TTL_SECONDS_ENV], DEFAULT_WORKFLOW_CONTEXT_CACHE_TTL_SECONDS));
898
+ const tempTtlSeconds = normalizeNonNegativeInteger(options.tempTtlSeconds, Math.min(cacheTtlSeconds, DEFAULT_WORKFLOW_CONTEXT_TEMP_TTL_SECONDS));
899
+ return {
900
+ maxEntries,
901
+ cacheTtlMs: cacheTtlSeconds * 1_000,
902
+ // Provenance-only temp runs are useful for debugging recent misses, but they
903
+ // are not reusable cache entries, so they get a shorter bounded lifetime.
904
+ tempTtlMs: tempTtlSeconds * 1_000,
905
+ };
906
+ }
907
+ function parseNonNegativeInteger(value, fallback) {
908
+ if (value == null || value.trim() === "") {
909
+ return fallback;
910
+ }
911
+ const parsed = Number(value);
912
+ return normalizeNonNegativeInteger(parsed, fallback);
913
+ }
914
+ function normalizeNonNegativeInteger(value, fallback) {
915
+ if (value === undefined) {
916
+ return fallback;
917
+ }
918
+ return Number.isSafeInteger(value) && value >= 0 ? value : fallback;
919
+ }
920
+ function isNodeError(error) {
921
+ return error instanceof Error && "code" in error;
922
+ }
923
+ function nodeErrorCode(error) {
924
+ return isNodeError(error) && typeof error.code === "string"
925
+ ? error.code
926
+ : "unknown";
927
+ }
928
+ function normalizeContextBuilderWarnings(warnings) {
929
+ return warnings.map((warning) => {
930
+ if (isRecord(warning)) {
931
+ return {
932
+ code: diagnosticText(warning.code, "warning"),
933
+ message: diagnosticText(warning.message, "warning"),
934
+ };
935
+ }
936
+ return {
937
+ code: "warning",
938
+ message: diagnosticText(warning, "warning"),
939
+ };
940
+ });
941
+ }
942
+ function normalizeContextBuilderOmissions(omissions) {
943
+ return omissions.map((omission) => {
944
+ if (isRecord(omission)) {
945
+ const rootIndex = normalizeContextBuilderRootIndex(omission.root_index);
946
+ return {
947
+ ...(rootIndex == null ? {} : { root_index: rootIndex }),
948
+ reason: diagnosticText(omission.reason, "omission"),
949
+ message: diagnosticText(omission.message, "omission"),
950
+ ...(Array.isArray(omission.paths)
951
+ ? { paths: omission.paths.map(normalizeContextBuilderOmissionPath) }
952
+ : {}),
953
+ };
954
+ }
955
+ return {
956
+ reason: "omission",
957
+ message: diagnosticText(omission, "omission"),
958
+ };
959
+ });
960
+ }
961
+ function normalizeContextBuilderRootIndex(rootIndex) {
962
+ return typeof rootIndex === "number"
963
+ && Number.isInteger(rootIndex)
964
+ && rootIndex >= 0
965
+ ? rootIndex
966
+ : undefined;
967
+ }
968
+ function normalizeContextBuilderOmissionPath(path) {
969
+ if (typeof path !== "string") {
970
+ return "[redacted-sensitive-path]";
971
+ }
972
+ const text = diagnosticText(path, "");
973
+ return scanSecretPath(text).length > 0 ? "[redacted-sensitive-path]" : text;
974
+ }
975
+ function diagnosticText(value, fallback) {
976
+ if (typeof value === "string") {
977
+ return value;
978
+ }
979
+ if (value == null) {
980
+ return fallback;
981
+ }
982
+ if (typeof value === "number" || typeof value === "boolean") {
983
+ return String(value);
984
+ }
985
+ try {
986
+ const serialized = JSON.stringify(value);
987
+ return serialized ?? fallback;
988
+ }
989
+ catch {
990
+ return fallback;
991
+ }
992
+ }
993
+ function isRecord(value) {
994
+ return value !== null && typeof value === "object";
995
+ }
996
+ async function delay(ms) {
997
+ await new Promise((resolve) => setTimeout(resolve, ms));
998
+ }
999
+ function isPathInsideDirectory(candidate, directory) {
1000
+ const relation = relative(directory, candidate);
1001
+ return relation !== "" && !relation.startsWith("..") && !isAbsolute(relation);
1002
+ }
1003
+ //# sourceMappingURL=storage.js.map