@atolis-hq/wake 0.2.96 → 0.3.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 (442) hide show
  1. package/dist/src/activities/agent/agent-activity-definition.js +26 -0
  2. package/dist/src/activities/agent/agent-activity.js +171 -0
  3. package/dist/src/activities/agent/agent-result.js +149 -0
  4. package/dist/src/activities/contracts/activity.js +10 -0
  5. package/dist/src/activities/contracts/config.js +2 -0
  6. package/dist/src/activities/contracts/event-schema.js +302 -0
  7. package/dist/src/activities/contracts/events.js +42 -0
  8. package/dist/src/activities/contracts/identifiers.js +29 -0
  9. package/dist/src/activities/contracts/registry.js +71 -0
  10. package/dist/src/activities/contracts/streams.js +17 -0
  11. package/dist/src/activities/contracts/vocabulary.js +58 -0
  12. package/dist/src/activities/index.js +21 -0
  13. package/dist/src/activities/pr/activity-support.js +111 -0
  14. package/dist/src/activities/pr/application.js +158 -0
  15. package/dist/src/activities/pr/approve.js +85 -0
  16. package/dist/src/activities/pr/capability.js +11 -0
  17. package/dist/src/activities/pr/decision-claim.js +76 -0
  18. package/dist/src/activities/pr/event-drafts.js +66 -0
  19. package/dist/src/activities/pr/intent.js +37 -0
  20. package/dist/src/activities/pr/merge-authority-gate.js +14 -0
  21. package/dist/src/activities/pr/merge.js +110 -0
  22. package/dist/src/activities/pr/policy.js +135 -0
  23. package/dist/src/activities/pr/projection.js +130 -0
  24. package/dist/src/activities/pr/vocabulary.js +30 -0
  25. package/dist/src/activities/review/authorization.js +22 -0
  26. package/dist/src/activities/review/contracts.js +22 -0
  27. package/dist/src/activities/review/signals.js +3 -0
  28. package/dist/src/bootstrap/analytics-projection.js +26 -0
  29. package/dist/src/bootstrap/board-projection.js +337 -0
  30. package/dist/src/bootstrap/composition-root.js +382 -0
  31. package/dist/src/bootstrap/config/load-config.js +51 -0
  32. package/dist/src/bootstrap/config/root-schema.js +134 -0
  33. package/dist/src/bootstrap/external-ref.js +12 -0
  34. package/dist/src/bootstrap/fake-provider-files.js +44 -0
  35. package/dist/src/bootstrap/fake-scenarios.js +22 -0
  36. package/dist/src/bootstrap/index.js +48 -0
  37. package/dist/src/bootstrap/initialise.js +434 -0
  38. package/dist/src/bootstrap/paths.js +15 -0
  39. package/dist/src/bootstrap/projection-runtime.js +27 -0
  40. package/dist/src/bootstrap/runner-quota-reporter.js +21 -0
  41. package/dist/src/bootstrap/runner-registry.js +30 -0
  42. package/dist/src/bootstrap/schedule-checkpoint-store.js +49 -0
  43. package/dist/src/bootstrap/self-update-application.js +195 -0
  44. package/dist/src/bootstrap/self-update-failure-log.js +33 -0
  45. package/dist/src/bootstrap/source-update-port.js +47 -0
  46. package/dist/src/bootstrap/status-publish-activity.js +42 -0
  47. package/dist/src/bootstrap/surface-api-applications.js +325 -0
  48. package/dist/src/bootstrap/surface-api-execution-applications.js +95 -0
  49. package/dist/src/bootstrap/surface-api-metadata.js +12 -0
  50. package/dist/src/bootstrap/surface-api-projection-pages.js +22 -0
  51. package/dist/src/bootstrap/surface-api-run-context.js +5 -0
  52. package/dist/src/bootstrap/surface-api-transcripts.js +57 -0
  53. package/dist/src/bootstrap/surface-api-work-applications.js +199 -0
  54. package/dist/src/bootstrap/surface-applications.js +7 -0
  55. package/dist/src/bootstrap/surface-cli-applications.js +701 -0
  56. package/dist/src/bootstrap/update-ledger.js +61 -0
  57. package/dist/src/bootstrap/update-maintenance-lease.js +176 -0
  58. package/dist/src/{version.js → bootstrap/version.js} +35 -51
  59. package/dist/src/control-plane/application/advance-once.js +184 -0
  60. package/dist/src/control-plane/application/control-plane-projection.js +42 -0
  61. package/dist/src/control-plane/application/control-plane-service.js +42 -0
  62. package/dist/src/control-plane/application/intake-pipeline.js +29 -0
  63. package/dist/src/control-plane/application/runner-control-service.js +66 -0
  64. package/dist/src/control-plane/application/runner-pipeline.js +57 -0
  65. package/dist/src/control-plane/application/schedule-service.js +47 -0
  66. package/dist/src/control-plane/application/work-cancellation-policy.js +31 -0
  67. package/dist/src/control-plane/contracts/commands.js +10 -0
  68. package/dist/src/control-plane/contracts/config.js +22 -0
  69. package/dist/src/control-plane/contracts/events.js +81 -0
  70. package/dist/src/control-plane/contracts/streams.js +5 -0
  71. package/dist/src/control-plane/domain/dispatch-policy.js +15 -0
  72. package/dist/src/control-plane/domain/quota-policy.js +26 -0
  73. package/dist/src/control-plane/domain/runner-quota.js +35 -0
  74. package/dist/src/control-plane/domain/schedule-policy.js +46 -0
  75. package/dist/src/control-plane/index.js +20 -0
  76. package/dist/src/control-plane/infrastructure/intake-host.js +24 -0
  77. package/dist/src/control-plane/infrastructure/resident-host.js +45 -0
  78. package/dist/src/control-plane/infrastructure/tick-host.js +35 -0
  79. package/dist/src/execution/application/activation-claim.js +50 -0
  80. package/dist/src/execution/application/active-run-cancellation.js +14 -0
  81. package/dist/src/execution/application/execution-activity.js +97 -0
  82. package/dist/src/execution/application/execution-projection.js +17 -0
  83. package/dist/src/execution/application/execution-service.js +372 -0
  84. package/dist/src/execution/application/execution-validation.js +26 -0
  85. package/dist/src/execution/application/recovery-service.js +212 -0
  86. package/dist/src/execution/application/run-lifecycle.js +115 -0
  87. package/dist/src/execution/application/run-liveness-service.js +80 -0
  88. package/dist/src/execution/application/run-repository.js +27 -0
  89. package/dist/src/execution/contracts/commands.js +1 -0
  90. package/dist/src/execution/contracts/config.js +35 -0
  91. package/dist/src/execution/contracts/control-plane.js +1 -0
  92. package/dist/src/execution/contracts/event-factory.js +53 -0
  93. package/dist/src/execution/contracts/events.js +274 -0
  94. package/dist/src/execution/contracts/identifiers.js +5 -0
  95. package/dist/src/execution/contracts/liveness.js +1 -0
  96. package/dist/src/execution/contracts/results.js +1 -0
  97. package/dist/src/execution/contracts/runner.js +15 -0
  98. package/dist/src/execution/contracts/streams.js +10 -0
  99. package/dist/src/execution/contracts/views.js +1 -0
  100. package/dist/src/execution/contracts/vocabulary.js +43 -0
  101. package/dist/src/execution/contracts/workspace.js +1 -0
  102. package/dist/src/execution/domain/run-result.js +34 -0
  103. package/dist/src/execution/domain/run.js +142 -0
  104. package/dist/src/execution/index.js +31 -0
  105. package/dist/src/execution/infrastructure/agent-runner-adapter.js +114 -0
  106. package/dist/src/execution/infrastructure/process-execution.js +29 -0
  107. package/dist/src/execution/infrastructure/prompt-templates.js +42 -0
  108. package/dist/src/execution/infrastructure/runners/claude.js +120 -0
  109. package/dist/src/execution/infrastructure/runners/codex.js +143 -0
  110. package/dist/src/execution/infrastructure/runners/command.js +4 -0
  111. package/dist/src/execution/infrastructure/runners/cursor.js +69 -0
  112. package/dist/src/execution/infrastructure/runners/fake-scenarios.js +99 -0
  113. package/dist/src/execution/infrastructure/runners/fake.js +65 -0
  114. package/dist/src/execution/infrastructure/runners/registry.js +26 -0
  115. package/dist/src/execution/infrastructure/transcript-store.js +223 -0
  116. package/dist/src/execution/infrastructure/transcripts.js +11 -0
  117. package/dist/src/execution/infrastructure/workspace/fake-workspace.js +19 -0
  118. package/dist/src/execution/infrastructure/workspace/git-workspace.js +241 -0
  119. package/dist/src/integrations/application/agent-run-publication-reactor.js +111 -0
  120. package/dist/src/integrations/application/artifact-registration-reactor.js +159 -0
  121. package/dist/src/integrations/application/poll-service.js +25 -0
  122. package/dist/src/integrations/application/terminal-agent-run-report.js +40 -0
  123. package/dist/src/integrations/application/work-admission.js +31 -0
  124. package/dist/src/integrations/application/work-conclusion.js +19 -0
  125. package/dist/src/integrations/contracts/artifact-events.js +60 -0
  126. package/dist/src/integrations/contracts/artifact-vocabulary.js +9 -0
  127. package/dist/src/integrations/contracts/config.js +14 -0
  128. package/dist/src/integrations/contracts/identifiers.js +5 -0
  129. package/dist/src/integrations/contracts/intake-rules.js +14 -0
  130. package/dist/src/integrations/contracts/intake.js +1 -0
  131. package/dist/src/integrations/contracts/outcome-vocabulary.js +7 -0
  132. package/dist/src/integrations/contracts/provider.js +37 -0
  133. package/dist/src/integrations/contracts/streams.js +10 -0
  134. package/dist/src/integrations/delivery/application/delivery-outcome-reactor.js +75 -0
  135. package/dist/src/integrations/delivery/application/delivery-projector.js +165 -0
  136. package/dist/src/integrations/delivery/application/delivery-service.js +173 -0
  137. package/dist/src/integrations/delivery/contracts/commands.js +1 -0
  138. package/dist/src/integrations/delivery/contracts/config.js +1 -0
  139. package/dist/src/integrations/delivery/contracts/event-factory.js +18 -0
  140. package/dist/src/integrations/delivery/contracts/events.js +86 -0
  141. package/dist/src/integrations/delivery/contracts/intents.js +89 -0
  142. package/dist/src/integrations/delivery/contracts/views.js +1 -0
  143. package/dist/src/integrations/delivery/contracts/vocabulary.js +22 -0
  144. package/dist/src/integrations/fake/durable-delivery-provider.js +48 -0
  145. package/dist/src/integrations/fake/external-sink.js +9 -0
  146. package/dist/src/integrations/fake/external-source.js +44 -0
  147. package/dist/src/integrations/fake/inbound-translator.js +130 -0
  148. package/dist/src/integrations/fake/provider.js +95 -0
  149. package/dist/src/integrations/github/application/agent-context-reader.js +54 -0
  150. package/dist/src/integrations/github/application/agent-run-comment.js +94 -0
  151. package/dist/src/integrations/github/application/comment-history-reader.js +43 -0
  152. package/dist/src/integrations/github/application/inbound-context.js +10 -0
  153. package/dist/src/integrations/github/application/inbound-review-signals.js +159 -0
  154. package/dist/src/integrations/github/application/inbound-translator.js +231 -0
  155. package/dist/src/integrations/github/application/inbound-watch-gate-signals.js +84 -0
  156. package/dist/src/integrations/github/application/intake-policy.js +23 -0
  157. package/dist/src/integrations/github/application/outbound-translator.js +47 -0
  158. package/dist/src/integrations/github/application/poll-service.js +29 -0
  159. package/dist/src/integrations/github/application/pull-request-translation.js +10 -0
  160. package/dist/src/integrations/github/application/resource-links.js +8 -0
  161. package/dist/src/integrations/github/application/review-command-translator.js +16 -0
  162. package/dist/src/integrations/github/application/wake-labels.js +95 -0
  163. package/dist/src/integrations/github/contracts/config.js +47 -0
  164. package/dist/src/integrations/github/contracts/events.js +127 -0
  165. package/dist/src/integrations/github/contracts/external-key.js +19 -0
  166. package/dist/src/integrations/github/contracts/payloads.js +9 -0
  167. package/dist/src/integrations/github/contracts/vocabulary.js +55 -0
  168. package/dist/src/integrations/github/index.js +31 -0
  169. package/dist/src/integrations/github/infrastructure/client-reads.js +214 -0
  170. package/dist/src/integrations/github/infrastructure/client.js +132 -0
  171. package/dist/src/integrations/github/infrastructure/content-fingerprint.js +10 -0
  172. package/dist/src/integrations/github/infrastructure/delivery.js +31 -0
  173. package/dist/src/integrations/github/infrastructure/etag-cache.js +56 -0
  174. package/dist/src/integrations/github/infrastructure/gh-auth.js +19 -0
  175. package/dist/src/integrations/github/infrastructure/issue-source.js +109 -0
  176. package/dist/src/integrations/github/infrastructure/pr-source.js +186 -0
  177. package/dist/src/integrations/github/infrastructure/review-source.js +70 -0
  178. package/dist/src/integrations/github/infrastructure/source.js +108 -0
  179. package/dist/src/integrations/github/provider.js +96 -0
  180. package/dist/src/integrations/index.js +30 -0
  181. package/dist/src/kernel/contracts/checkpoint-store.js +1 -0
  182. package/dist/src/kernel/contracts/clock.js +1 -0
  183. package/dist/src/kernel/contracts/commands.js +1 -0
  184. package/dist/src/kernel/contracts/event-journal.js +2 -0
  185. package/dist/src/kernel/contracts/event-schema.js +54 -0
  186. package/dist/src/kernel/contracts/events.js +11 -0
  187. package/dist/src/kernel/contracts/id-generator.js +1 -0
  188. package/dist/src/kernel/contracts/identifiers.js +8 -0
  189. package/dist/src/kernel/contracts/projection-store.js +1 -0
  190. package/dist/src/kernel/contracts/relations.js +1 -0
  191. package/dist/src/kernel/contracts/schema.js +17 -0
  192. package/dist/src/kernel/contracts/vocabulary.js +6 -0
  193. package/dist/src/kernel/domain/event-envelope.js +29 -0
  194. package/dist/src/kernel/domain/match-mode.js +11 -0
  195. package/dist/src/kernel/domain/relation.js +10 -0
  196. package/dist/src/kernel/index.js +17 -0
  197. package/dist/src/{lib/clock.js → kernel/infrastructure/system-clock.js} +3 -3
  198. package/dist/src/kernel/infrastructure/ulid-id-generator.js +9 -0
  199. package/dist/src/main.js +137 -1030
  200. package/dist/src/orchestration/application/accept-activity-outcome.js +25 -0
  201. package/dist/src/orchestration/application/accept-signal.js +35 -0
  202. package/dist/src/orchestration/application/advance-workflow.js +160 -0
  203. package/dist/src/orchestration/application/coordination-claims.js +107 -0
  204. package/dist/src/orchestration/application/group-budget-recorder.js +43 -0
  205. package/dist/src/orchestration/application/orchestration-projection.js +20 -0
  206. package/dist/src/orchestration/application/orchestration-repository.js +36 -0
  207. package/dist/src/orchestration/application/orchestration-service.js +82 -0
  208. package/dist/src/orchestration/application/request-child.js +118 -0
  209. package/dist/src/orchestration/application/signal-reactor.js +17 -0
  210. package/dist/src/orchestration/application/start-workflow.js +51 -0
  211. package/dist/src/orchestration/application/watch-reactor.js +82 -0
  212. package/dist/src/orchestration/contracts/activity-outcome.js +18 -0
  213. package/dist/src/orchestration/contracts/commands.js +1 -0
  214. package/dist/src/orchestration/contracts/config.js +128 -0
  215. package/dist/src/orchestration/contracts/event-decoder.js +263 -0
  216. package/dist/src/orchestration/contracts/events.js +41 -0
  217. package/dist/src/orchestration/contracts/identifiers.js +35 -0
  218. package/dist/src/orchestration/contracts/streams.js +38 -0
  219. package/dist/src/orchestration/contracts/views.js +1 -0
  220. package/dist/src/orchestration/contracts/vocabulary.js +30 -0
  221. package/dist/src/orchestration/domain/activation-policy.js +55 -0
  222. package/dist/src/orchestration/domain/approval-defaults.js +17 -0
  223. package/dist/src/orchestration/domain/child-policy.js +63 -0
  224. package/dist/src/orchestration/domain/compiler.js +162 -0
  225. package/dist/src/orchestration/domain/coordination-events.js +25 -0
  226. package/dist/src/orchestration/domain/decision-events.js +47 -0
  227. package/dist/src/orchestration/domain/interpreter.js +49 -0
  228. package/dist/src/orchestration/domain/operator-retry-policy.js +34 -0
  229. package/dist/src/orchestration/domain/retry-policy.js +26 -0
  230. package/dist/src/orchestration/domain/signal-policy.js +120 -0
  231. package/dist/src/orchestration/domain/supplemental-policy.js +61 -0
  232. package/dist/src/orchestration/domain/transition.js +55 -0
  233. package/dist/src/orchestration/domain/workflow-graph.js +41 -0
  234. package/dist/src/orchestration/domain/workflow-instance-events.js +236 -0
  235. package/dist/src/orchestration/domain/workflow-instance.js +41 -0
  236. package/dist/src/orchestration/domain/workflow-selector.js +21 -0
  237. package/dist/src/orchestration/index.js +19 -0
  238. package/dist/src/persistence/application/projection-runner.js +79 -0
  239. package/dist/src/persistence/filesystem/file-checkpoint-store.js +35 -0
  240. package/dist/src/persistence/filesystem/file-event-journal.js +143 -0
  241. package/dist/src/persistence/filesystem/file-lock.js +91 -0
  242. package/dist/src/persistence/filesystem/file-projection-store.js +64 -0
  243. package/dist/src/persistence/index.js +8 -0
  244. package/dist/src/persistence/memory/in-memory-checkpoint-store.js +14 -0
  245. package/dist/src/persistence/memory/in-memory-event-journal.js +88 -0
  246. package/dist/src/persistence/memory/in-memory-projection-store.js +17 -0
  247. package/dist/src/resources/application/lookup-projections.js +48 -0
  248. package/dist/src/resources/application/resource-lookup.js +16 -0
  249. package/dist/src/resources/application/resource-projections.js +81 -0
  250. package/dist/src/resources/application/resource-repository.js +18 -0
  251. package/dist/src/resources/application/resource-service.js +83 -0
  252. package/dist/src/resources/contracts/commands.js +1 -0
  253. package/dist/src/resources/contracts/config.js +2 -0
  254. package/dist/src/resources/contracts/events.js +83 -0
  255. package/dist/src/resources/contracts/identifiers.js +15 -0
  256. package/dist/src/resources/contracts/streams.js +6 -0
  257. package/dist/src/resources/contracts/views.js +1 -0
  258. package/dist/src/resources/contracts/vocabulary.js +67 -0
  259. package/dist/src/resources/domain/correlation.js +8 -0
  260. package/dist/src/resources/domain/resource.js +58 -0
  261. package/dist/src/resources/index.js +14 -0
  262. package/dist/src/surfaces/api/contracts/activities.js +1 -0
  263. package/dist/src/surfaces/api/contracts/board.js +2 -0
  264. package/dist/src/surfaces/api/contracts/common.js +46 -0
  265. package/dist/src/surfaces/api/contracts/control-plane.js +5 -0
  266. package/dist/src/surfaces/api/contracts/events.js +1 -0
  267. package/dist/src/surfaces/api/contracts/execution.js +1 -0
  268. package/dist/src/surfaces/api/contracts/index.js +13 -0
  269. package/dist/src/surfaces/api/contracts/observability.js +1 -0
  270. package/dist/src/surfaces/api/contracts/orchestration.js +1 -0
  271. package/dist/src/surfaces/api/contracts/resources.js +1 -0
  272. package/dist/src/surfaces/api/contracts/status.js +1 -0
  273. package/dist/src/surfaces/api/contracts/system.js +1 -0
  274. package/dist/src/surfaces/api/contracts/transport-values.js +39 -0
  275. package/dist/src/surfaces/api/contracts/work.js +17 -0
  276. package/dist/src/surfaces/api/http-server.js +121 -0
  277. package/dist/src/surfaces/api/presenters/activities.js +1 -0
  278. package/dist/src/surfaces/api/presenters/board.js +3 -0
  279. package/dist/src/surfaces/api/presenters/control-plane.js +1 -0
  280. package/dist/src/surfaces/api/presenters/events.js +1 -0
  281. package/dist/src/surfaces/api/presenters/execution.js +59 -0
  282. package/dist/src/surfaces/api/presenters/observability.js +1 -0
  283. package/dist/src/surfaces/api/presenters/orchestration.js +19 -0
  284. package/dist/src/surfaces/api/presenters/resources.js +15 -0
  285. package/dist/src/surfaces/api/presenters/status.js +3 -0
  286. package/dist/src/surfaces/api/presenters/system.js +14 -0
  287. package/dist/src/surfaces/api/presenters/work.js +16 -0
  288. package/dist/src/surfaces/api/problem-details.js +9 -0
  289. package/dist/src/surfaces/api/router.js +13 -0
  290. package/dist/src/surfaces/api/routes/activities.js +1 -0
  291. package/dist/src/surfaces/api/routes/applications.js +1 -0
  292. package/dist/src/surfaces/api/routes/commands.js +82 -0
  293. package/dist/src/surfaces/api/routes/control-plane.js +6 -0
  294. package/dist/src/surfaces/api/routes/events.js +1 -0
  295. package/dist/src/surfaces/api/routes/execution.js +8 -0
  296. package/dist/src/surfaces/api/routes/index.js +18 -0
  297. package/dist/src/surfaces/api/routes/observability.js +1 -0
  298. package/dist/src/surfaces/api/routes/orchestration.js +1 -0
  299. package/dist/src/surfaces/api/routes/pagination.js +78 -0
  300. package/dist/src/surfaces/api/routes/read.js +135 -0
  301. package/dist/src/surfaces/api/routes/resources.js +1 -0
  302. package/dist/src/surfaces/api/routes/responses.js +67 -0
  303. package/dist/src/surfaces/api/routes/system.js +1 -0
  304. package/dist/src/surfaces/api/routes/work.js +9 -0
  305. package/dist/src/surfaces/cli/commands/api.js +1 -0
  306. package/dist/src/surfaces/cli/commands/audit.js +10 -0
  307. package/dist/src/surfaces/cli/commands/correlate.js +2 -0
  308. package/dist/src/surfaces/cli/commands/doctor.js +6 -0
  309. package/dist/src/surfaces/cli/commands/init.js +39 -0
  310. package/dist/src/surfaces/cli/commands/sandbox-entrypoint.js +33 -0
  311. package/dist/src/surfaces/cli/commands/sandbox-setup.js +29 -0
  312. package/dist/src/surfaces/cli/commands/sandbox.js +105 -0
  313. package/dist/src/surfaces/cli/commands/self-update.js +38 -0
  314. package/dist/src/surfaces/cli/commands/smoke.js +16 -0
  315. package/dist/src/surfaces/cli/commands/start.js +1 -0
  316. package/dist/src/surfaces/cli/commands/stop.js +13 -0
  317. package/dist/src/surfaces/cli/commands/tick.js +1 -0
  318. package/dist/src/surfaces/cli/commands/ui.js +2 -0
  319. package/dist/src/surfaces/cli/commands/validate-state.js +5 -0
  320. package/dist/src/surfaces/cli/infrastructure/docker-cli.js +221 -0
  321. package/dist/src/surfaces/cli/infrastructure/process-log.js +86 -0
  322. package/dist/src/surfaces/cli/main.js +140 -0
  323. package/dist/src/surfaces/cli/usage.js +33 -0
  324. package/dist/src/surfaces/contracts/config.js +34 -0
  325. package/dist/src/surfaces/index.js +47 -0
  326. package/dist/src/surfaces/web-assets/assets/index-Bfn4FwZG.css +1 -0
  327. package/dist/src/surfaces/web-assets/assets/index-ipB6JPGU.js +1090 -0
  328. package/dist/src/surfaces/web-assets/index.html +13 -0
  329. package/dist/src/surfaces/web-host/asset-source.js +1 -0
  330. package/dist/src/surfaces/web-host/packaged-assets.js +44 -0
  331. package/dist/src/work/application/work-projection.js +59 -0
  332. package/dist/src/work/application/work-repository.js +18 -0
  333. package/dist/src/work/application/work-service.js +117 -0
  334. package/dist/src/work/contracts/commands.js +1 -0
  335. package/dist/src/work/contracts/config.js +2 -0
  336. package/dist/src/work/contracts/events.js +103 -0
  337. package/dist/src/work/contracts/identifiers.js +5 -0
  338. package/dist/src/work/contracts/streams.js +6 -0
  339. package/dist/src/work/contracts/views.js +1 -0
  340. package/dist/src/work/contracts/vocabulary.js +6 -0
  341. package/dist/src/work/domain/work-item.js +89 -0
  342. package/dist/src/work/index.js +11 -0
  343. package/docker/Dockerfile +10 -6
  344. package/docker/Dockerfile.packaged +3 -3
  345. package/package.json +29 -4
  346. package/prompts/implement.md +2 -2
  347. package/templates/SETUP.md +7 -7
  348. package/dist/src/adapters/claude/claude-runner.js +0 -529
  349. package/dist/src/adapters/codex/codex-runner.js +0 -503
  350. package/dist/src/adapters/cursor/cursor-runner.js +0 -418
  351. package/dist/src/adapters/docker/docker-cli.js +0 -150
  352. package/dist/src/adapters/fake/fake-artifact-verifier.js +0 -14
  353. package/dist/src/adapters/fake/fake-github-pull-request-activity-source.js +0 -77
  354. package/dist/src/adapters/fake/fake-resource-index.js +0 -21
  355. package/dist/src/adapters/fake/fake-runner.js +0 -77
  356. package/dist/src/adapters/fake/fake-ticketing-system.js +0 -185
  357. package/dist/src/adapters/fake/fake-workspace-manager.js +0 -81
  358. package/dist/src/adapters/fs/resource-index.js +0 -126
  359. package/dist/src/adapters/fs/self-update-ledger.js +0 -17
  360. package/dist/src/adapters/fs/state-store.js +0 -775
  361. package/dist/src/adapters/git/git-workspace-manager.js +0 -289
  362. package/dist/src/adapters/github/github-artifact-verifier.js +0 -38
  363. package/dist/src/adapters/github/github-auth.js +0 -16
  364. package/dist/src/adapters/github/github-client.js +0 -249
  365. package/dist/src/adapters/github/github-etag-cache.js +0 -57
  366. package/dist/src/adapters/github/github-issues-work-source.js +0 -692
  367. package/dist/src/adapters/github/github-pull-request-activity-source.js +0 -584
  368. package/dist/src/adapters/github/github-pull-request-merge-actor.js +0 -45
  369. package/dist/src/adapters/http/ui-assets.js +0 -1188
  370. package/dist/src/adapters/http/ui-data.js +0 -1107
  371. package/dist/src/adapters/http/ui-server.js +0 -458
  372. package/dist/src/adapters/runner/cli-command.js +0 -73
  373. package/dist/src/adapters/runner/prompt-templates.js +0 -76
  374. package/dist/src/adapters/runner/runner-cli-adapter.js +0 -112
  375. package/dist/src/adapters/runner/runner-registry.js +0 -139
  376. package/dist/src/adapters/runner/runtime-events.js +0 -32
  377. package/dist/src/adapters/runner/stage-prompt.js +0 -268
  378. package/dist/src/adapters/runner/transcripts.js +0 -25
  379. package/dist/src/cli/audit-command.js +0 -36
  380. package/dist/src/cli/correlate-command.js +0 -62
  381. package/dist/src/cli/doctor-command.js +0 -48
  382. package/dist/src/cli/init-command.js +0 -18
  383. package/dist/src/cli/sandbox-command.js +0 -258
  384. package/dist/src/cli/sandbox-entrypoint-command.js +0 -88
  385. package/dist/src/cli/sandbox-exec-logging.js +0 -7
  386. package/dist/src/cli/sandbox-resume.js +0 -79
  387. package/dist/src/cli/sandbox-setup-command.js +0 -31
  388. package/dist/src/cli/scaffold-assets.js +0 -100
  389. package/dist/src/cli/self-update-command.js +0 -198
  390. package/dist/src/cli/startup-preflight.js +0 -134
  391. package/dist/src/cli/stop-command.js +0 -46
  392. package/dist/src/cli/ui-command.js +0 -27
  393. package/dist/src/config/defaults.js +0 -10
  394. package/dist/src/config/discover-config-files.js +0 -11
  395. package/dist/src/config/load-config.js +0 -69
  396. package/dist/src/config/split-config.js +0 -14
  397. package/dist/src/core/active-run-recovery.js +0 -44
  398. package/dist/src/core/approval-intents.js +0 -16
  399. package/dist/src/core/audit-events.js +0 -82
  400. package/dist/src/core/control-plane.js +0 -192
  401. package/dist/src/core/event-builders.js +0 -153
  402. package/dist/src/core/event-resolver.js +0 -249
  403. package/dist/src/core/lifecycle-service.js +0 -8
  404. package/dist/src/core/live-execution.js +0 -81
  405. package/dist/src/core/outbox.js +0 -198
  406. package/dist/src/core/policy-engine.js +0 -389
  407. package/dist/src/core/projection-updater.js +0 -693
  408. package/dist/src/core/quota-backoff.js +0 -69
  409. package/dist/src/core/run-lease.js +0 -38
  410. package/dist/src/core/scheduled-workflow-source.js +0 -199
  411. package/dist/src/core/sink-router.js +0 -107
  412. package/dist/src/core/stale-run-reconciler.js +0 -352
  413. package/dist/src/core/tick-runner.js +0 -2365
  414. package/dist/src/core/workspace-cleanup.js +0 -117
  415. package/dist/src/domain/branch-naming.js +0 -14
  416. package/dist/src/domain/custom-commands.js +0 -58
  417. package/dist/src/domain/event-types.js +0 -158
  418. package/dist/src/domain/manual-labels.js +0 -1
  419. package/dist/src/domain/resource-uri.js +0 -38
  420. package/dist/src/domain/runner-routing.js +0 -127
  421. package/dist/src/domain/runtime-events.js +0 -36
  422. package/dist/src/domain/schema.js +0 -1233
  423. package/dist/src/domain/sources.js +0 -16
  424. package/dist/src/domain/stages.js +0 -36
  425. package/dist/src/domain/work-item-labels.js +0 -48
  426. package/dist/src/domain/work-item-lifecycle.js +0 -10
  427. package/dist/src/domain/work-item-status.js +0 -33
  428. package/dist/src/domain/workflows.js +0 -159
  429. package/dist/src/lib/deep-merge.js +0 -14
  430. package/dist/src/lib/detached-process-logging.js +0 -46
  431. package/dist/src/lib/event-log.js +0 -21
  432. package/dist/src/lib/format.js +0 -41
  433. package/dist/src/lib/json-file.js +0 -23
  434. package/dist/src/lib/lock.js +0 -181
  435. package/dist/src/lib/log-rotation.js +0 -42
  436. package/dist/src/lib/paths.js +0 -52
  437. package/dist/src/lib/process-identity.js +0 -54
  438. package/dist/src/lib/state-health.js +0 -30
  439. package/dist/src/lib/work-id.js +0 -19
  440. package/dist/src/lib/yaml-file.js +0 -20
  441. /package/dist/src/{core → activities/pr}/contracts.js +0 -0
  442. /package/dist/src/{domain/types.js → control-plane/contracts/views.js} +0 -0
@@ -1,16 +0,0 @@
1
- /**
2
- * Names the configured ticket source. This is one decision with several
3
- * consumers that MUST agree: main.ts names the source it wires into the fan-in
4
- * and the sink router, while the UI builds `<provider>:issue:<repo>#<n>` URIs
5
- * to resolve tickets against the index those same events registered. If the
6
- * two ever disagreed, the UI would resolve against a provider nothing had
7
- * registered, miss, and report live work items as missing.
8
- *
9
- * It lives here, and not inline at each call site, because adding a third
10
- * source means changing this one function rather than finding every ternary —
11
- * source-pluggability is the point of the adapter seams, so the choice must
12
- * not be duplicated across them.
13
- */
14
- export function configuredTicketSource(config) {
15
- return config.sources.github.enabled ? 'github' : 'fake-ticketing';
16
- }
@@ -1,36 +0,0 @@
1
- export const stageValues = ['queue', 'done'];
2
- export const doneRunnerSentinel = 'DONE';
3
- export const rejectedRunnerSentinel = 'REJECTED';
4
- export const blockedRunnerSentinel = 'BLOCKED';
5
- export const failedRunnerSentinel = 'FAILED';
6
- export const runnerSentinelValues = [
7
- doneRunnerSentinel,
8
- rejectedRunnerSentinel,
9
- blockedRunnerSentinel,
10
- failedRunnerSentinel,
11
- ];
12
- export const terminalStageValues = ['done'];
13
- export function isTerminalStage(stage) {
14
- return terminalStageValues.includes(stage);
15
- }
16
- export const wakeStageLabelPrefix = 'wake:stage.';
17
- export function stageLabelForStage(stage) {
18
- return `${wakeStageLabelPrefix}${stage}`;
19
- }
20
- export function stageFromStageLabel(label, configuredStages = stageValues) {
21
- if (!label.startsWith(wakeStageLabelPrefix)) {
22
- return undefined;
23
- }
24
- const stage = label.slice(wakeStageLabelPrefix.length);
25
- return new Set(configuredStages).has(stage) ? stage : undefined;
26
- }
27
- export function stageFromLabels(labels, configuredStages = stageValues) {
28
- const stages = new Set();
29
- for (const label of labels) {
30
- const stage = stageFromStageLabel(label, configuredStages);
31
- if (stage !== undefined) {
32
- stages.add(stage);
33
- }
34
- }
35
- return stages.size === 1 ? [...stages][0] : undefined;
36
- }
@@ -1,48 +0,0 @@
1
- import { stageLabelForStage } from './stages.js';
2
- import { FROZEN_WORK_ITEM_LABEL } from './work-item-lifecycle.js';
3
- import { workflowLabelForWorkflowName, workflowNameForProjection } from './workflows.js';
4
- // The single place that translates the canonical, typed context fields
5
- // (status/frozen/deleted/scheduled) into wake:* label strings. Lives in
6
- // domain/ (not adapters/github/) so core/ can call it directly without
7
- // importing a concrete adapter — the wake: naming convention is Wake's own,
8
- // not GitHub-specific, matching stageLabelForStage/workflowLabelForWorkflowName
9
- // which already live here for the same reason.
10
- export const SCHEDULED_WORKFLOW_LABEL = 'wake:scheduled-workflow';
11
- const statusLabelByStatus = {
12
- queued: 'wake:status.pending',
13
- working: 'wake:status.working',
14
- 'awaiting-approval': 'wake:status.awaiting-approval',
15
- 'changes-requested': 'wake:status.changes-requested',
16
- blocked: 'wake:status.blocked',
17
- done: 'wake:status.completed',
18
- failed: 'wake:status.failed',
19
- };
20
- // A projection that predates context.status being folded (or hasn't had a
21
- // run complete yet since this design shipped) has no status field — fall
22
- // back to the same sentinel+stage heuristic the old statusLabelForOutcome
23
- // used, so an untouched legacy item is translated to the *same* label it
24
- // already carries (e.g. still-AWAITING_APPROVAL) instead of drifting to a
25
- // wrong one just because context.status hasn't been folded onto it yet.
26
- function legacyStatusFallback(projection) {
27
- const sentinel = projection.context.lastRunSentinel;
28
- if (sentinel === 'AWAITING_APPROVAL') {
29
- return 'awaiting-approval';
30
- }
31
- if (sentinel === 'BLOCKED') {
32
- return 'blocked';
33
- }
34
- if (sentinel === 'FAILED') {
35
- return 'failed';
36
- }
37
- return projection.wake.stage === 'done' ? 'done' : 'queued';
38
- }
39
- export function labelsForWorkItem(projection, config) {
40
- const statusLabel = statusLabelByStatus[projection.context.status ?? legacyStatusFallback(projection)];
41
- return {
42
- statusLabel,
43
- stageLabel: stageLabelForStage(projection.wake.stage),
44
- workflowLabel: workflowLabelForWorkflowName(workflowNameForProjection(projection, config)),
45
- ...(projection.context.frozen !== undefined ? { frozenLabel: FROZEN_WORK_ITEM_LABEL } : {}),
46
- ...(projection.context.scheduled === true ? { scheduledLabel: SCHEDULED_WORKFLOW_LABEL } : {}),
47
- };
48
- }
@@ -1,10 +0,0 @@
1
- export const FROZEN_WORK_ITEM_LABEL = 'wake:frozen';
2
- export function isWorkItemDeleted(item) {
3
- return item.context.deleted !== undefined;
4
- }
5
- export function isWorkItemFrozen(item) {
6
- return item.context.frozen !== undefined;
7
- }
8
- export function isWorkItemRunnable(item) {
9
- return !isWorkItemDeleted(item) && !isWorkItemFrozen(item);
10
- }
@@ -1,33 +0,0 @@
1
- import { z } from 'zod';
2
- // Canonical, typed status for a work item — folded once in
3
- // projection-updater.ts, translated (never recomputed) everywhere else
4
- // (e.g. GitHub labels via labelsForWorkItem). See
5
- // docs/superpowers/specs/2026-07-28-canonical-work-item-status-design.md.
6
- export const workItemStatusValues = [
7
- 'queued',
8
- 'working',
9
- 'awaiting-approval',
10
- 'changes-requested',
11
- 'blocked',
12
- 'done',
13
- 'failed',
14
- ];
15
- export const workItemStatusSchema = z.enum(workItemStatusValues);
16
- // Mirrors the sentinel/stage mapping that used to live only in
17
- // tick-runner.ts's statusLabelForOutcome/statusLabelForStage. Folded onto
18
- // context.status alongside (not replacing) context.lastRunSentinel.
19
- export function workItemStatusForRunOutcome(input) {
20
- if (input.sentinel === 'DONE' && input.approvalGated === true) {
21
- return 'awaiting-approval';
22
- }
23
- if (input.sentinel === 'REJECTED') {
24
- return 'changes-requested';
25
- }
26
- if (input.sentinel === 'BLOCKED') {
27
- return 'blocked';
28
- }
29
- if (input.sentinel === 'FAILED') {
30
- return 'failed';
31
- }
32
- return input.stage === 'done' ? 'done' : 'queued';
33
- }
@@ -1,159 +0,0 @@
1
- import { stageLabelForStage } from './stages.js';
2
- export const universalQueueStage = 'queue';
3
- export const universalDoneStage = 'done';
4
- export const workflowChangedBlockReason = 'workflow-changed';
5
- export const wakeWorkflowLabelPrefix = 'wake:workflow.';
6
- export const builtInDefaultWorkflowDefinition = {
7
- stages: {
8
- refine: {
9
- action: 'refine',
10
- workspace: 'read-only',
11
- tier: 'light',
12
- onDone: 'implement',
13
- },
14
- implement: {
15
- action: 'implement',
16
- workspace: 'branch',
17
- tier: 'standard',
18
- onDone: 'done',
19
- },
20
- },
21
- };
22
- export function configuredWorkflowNames(config) {
23
- return Object.keys(config.workflows);
24
- }
25
- export function defaultWorkflowName(config) {
26
- const [name] = configuredWorkflowNames(config);
27
- if (name === undefined) {
28
- throw new Error('Wake config must define at least one workflow.');
29
- }
30
- return name;
31
- }
32
- export function workflowForProjection(projection, config) {
33
- const workflowName = workflowNameForProjection(projection, config);
34
- return config.workflows[workflowName] ?? null;
35
- }
36
- export function workflowNameForProjection(projection, config) {
37
- const context = projection.context;
38
- return typeof context.workflow === 'string' ? context.workflow : defaultWorkflowName(config);
39
- }
40
- function stringArray(value) {
41
- return Array.isArray(value)
42
- ? value.filter((entry) => typeof entry === 'string')
43
- : [];
44
- }
45
- function repoFromResourceUri(resourceUri) {
46
- if (resourceUri === undefined) {
47
- return undefined;
48
- }
49
- const [, , rest] = resourceUri.split(':', 3);
50
- return rest?.split('#')[0];
51
- }
52
- export function workflowSelectorInputFromEvent(event) {
53
- const resourceUri = event.sourceRefs.resourceUri ?? event.sourceRefs.parentResourceUri;
54
- const kind = resourceUri?.split(':')[1];
55
- const ticket = (event.payload.ticket ?? event.payload.issue);
56
- const pr = event.payload.pr;
57
- const repo = (typeof ticket?.repo === 'string' ? ticket.repo : undefined) ??
58
- event.sourceRefs.repo ??
59
- repoFromResourceUri(resourceUri);
60
- return {
61
- ...(kind === undefined ? {} : { kind }),
62
- sourceEventType: event.sourceEventType,
63
- ...(repo === undefined ? {} : { repo }),
64
- labels: stringArray(ticket?.labels),
65
- assignees: stringArray(ticket?.assignees),
66
- ...(typeof pr?.author === 'string' ? { author: pr.author } : {}),
67
- };
68
- }
69
- function labelsAndAssigneesMatch(input) {
70
- const labels = new Set(input.labels);
71
- const assignees = new Set(input.assignees);
72
- if (input.requiredLabels.some((label) => !labels.has(label))) {
73
- return false;
74
- }
75
- if (input.ignoredLabels.some((label) => labels.has(label))) {
76
- return false;
77
- }
78
- if (input.requiredAssignees.length > 0 &&
79
- !input.requiredAssignees.some((login) => assignees.has(login))) {
80
- return false;
81
- }
82
- return true;
83
- }
84
- function selectorMatches(selector, input) {
85
- const match = selector.match;
86
- if (match.kind !== undefined && match.kind !== input.kind) {
87
- return false;
88
- }
89
- if (match.sourceEventType !== undefined && match.sourceEventType !== input.sourceEventType) {
90
- return false;
91
- }
92
- if (match.repo !== undefined && match.repo !== input.repo) {
93
- return false;
94
- }
95
- if (!labelsAndAssigneesMatch({ ...match, labels: input.labels, assignees: input.assignees })) {
96
- return false;
97
- }
98
- if (match.requiredAuthors.length > 0 &&
99
- (input.author === undefined || !match.requiredAuthors.includes(input.author))) {
100
- return false;
101
- }
102
- return true;
103
- }
104
- export function selectWorkflowForEvent(event, config) {
105
- const hintedWorkflow = event.payload.workflow;
106
- if (typeof hintedWorkflow === 'string' && config.workflows[hintedWorkflow] !== undefined) {
107
- return hintedWorkflow;
108
- }
109
- const input = workflowSelectorInputFromEvent(event);
110
- const selector = config.workflowSelectors.find((candidate) => selectorMatches(candidate, input));
111
- return selector?.workflow ?? null;
112
- }
113
- export function configuredStageNames(workflow) {
114
- return Object.keys(workflow.stages);
115
- }
116
- export function workflowStageVocabulary(workflow) {
117
- return [universalQueueStage, ...configuredStageNames(workflow), universalDoneStage];
118
- }
119
- export function stageLabelsForWorkflow(workflow) {
120
- return workflowStageVocabulary(workflow).map((stage) => stageLabelForStage(stage));
121
- }
122
- export function workflowLabelForWorkflowName(workflowName) {
123
- return `${wakeWorkflowLabelPrefix}${workflowName}`;
124
- }
125
- export function isKnownWorkflowStage(stage, workflow) {
126
- return workflowStageVocabulary(workflow).includes(stage);
127
- }
128
- export function entryStage(workflow) {
129
- return workflow.entryStage ?? configuredStageNames(workflow)[0];
130
- }
131
- export function stageAfterQueue(workflow) {
132
- return entryStage(workflow);
133
- }
134
- export function chooseAction(projection, workflow) {
135
- const stage = projection.wake.stage === universalQueueStage
136
- ? stageAfterQueue(workflow)
137
- : projection.wake.stage;
138
- const definition = workflow.stages[stage];
139
- if (definition === undefined || stage === universalDoneStage) {
140
- return null;
141
- }
142
- return {
143
- action: definition.action ?? stage,
144
- workspace: definition.workspace,
145
- routing: {
146
- ...(definition.tier === undefined ? {} : { tier: definition.tier }),
147
- ...(definition.runner === undefined ? {} : { runner: definition.runner }),
148
- },
149
- ...(definition.promptContext === undefined ? {} : { promptContext: definition.promptContext }),
150
- stage,
151
- };
152
- }
153
- export function nextStage(stage, sentinel, workflow) {
154
- if (sentinel === 'BLOCKED' || sentinel === 'FAILED' || sentinel === 'REJECTED') {
155
- return null;
156
- }
157
- const runnableStage = stage === universalQueueStage ? stageAfterQueue(workflow) : stage;
158
- return workflow.stages[runnableStage]?.onDone ?? null;
159
- }
@@ -1,14 +0,0 @@
1
- function isPlainObject(value) {
2
- return typeof value === 'object' && value !== null && !Array.isArray(value);
3
- }
4
- export function deepMergeRaw(target, source) {
5
- const result = { ...target };
6
- for (const [key, sourceValue] of Object.entries(source)) {
7
- const targetValue = result[key];
8
- result[key] =
9
- isPlainObject(sourceValue) && isPlainObject(targetValue)
10
- ? deepMergeRaw(targetValue, sourceValue)
11
- : sourceValue;
12
- }
13
- return result;
14
- }
@@ -1,46 +0,0 @@
1
- import { createWriteStream } from 'node:fs';
2
- import { DEFAULT_LOG_MAX_BYTES, DEFAULT_LOG_ROTATE_CHECK_INTERVAL_MS, rotateLogFileIfNeeded, } from './log-rotation.js';
3
- export function createDetachedProcessLogSink(logFile, options) {
4
- const maxBytes = options?.maxBytes ?? DEFAULT_LOG_MAX_BYTES;
5
- const rotateCheckIntervalMs = options?.rotateCheckIntervalMs ?? DEFAULT_LOG_ROTATE_CHECK_INTERVAL_MS;
6
- const stdout = options?.stdout ?? process.stdout;
7
- let closed = false;
8
- let fileStream = openLogFile(logFile, maxBytes);
9
- const rotateInterval = setInterval(() => {
10
- if (closed) {
11
- return;
12
- }
13
- const stream = fileStream;
14
- stream.end(() => {
15
- if (closed) {
16
- return;
17
- }
18
- rotateLogFileIfNeeded(logFile, maxBytes);
19
- fileStream = openLogFile(logFile, maxBytes);
20
- });
21
- }, rotateCheckIntervalMs);
22
- rotateInterval.unref();
23
- return {
24
- write: (chunk) => {
25
- if (closed) {
26
- return;
27
- }
28
- fileStream.write(chunk);
29
- stdout.write(chunk);
30
- },
31
- close: () => {
32
- if (closed) {
33
- return Promise.resolve();
34
- }
35
- closed = true;
36
- clearInterval(rotateInterval);
37
- return new Promise((resolve) => {
38
- fileStream.end(resolve);
39
- });
40
- },
41
- };
42
- }
43
- function openLogFile(logFile, maxBytes) {
44
- rotateLogFileIfNeeded(logFile, maxBytes);
45
- return createWriteStream(logFile, { flags: 'a' });
46
- }
@@ -1,21 +0,0 @@
1
- export function createEventEnvelope(input) {
2
- return {
3
- schemaVersion: 1,
4
- ...input,
5
- };
6
- }
7
- /**
8
- * Builds a source event with no workItemKey. Sources do not self-key; the
9
- * resolver in tick-runner stamps the canonical key between poll and append
10
- * (spec D1).
11
- *
12
- * The return type is spelled structurally rather than importing
13
- * core/contracts' `UnkeyedEventEnvelope` — it is the identical type, and lib/
14
- * must not depend on core/.
15
- */
16
- export function createUnkeyedEventEnvelope(input) {
17
- return {
18
- schemaVersion: 1,
19
- ...input,
20
- };
21
- }
@@ -1,41 +0,0 @@
1
- // Presentation-only formatting for run summaries (cost, duration, tokens).
2
- // Pure functions with no dependency on tick state — kept in lib/ so they are
3
- // directly unit-testable rather than only reachable through a full run.
4
- export function extractTokenCount(tokenUsage) {
5
- if (tokenUsage === undefined) {
6
- return undefined;
7
- }
8
- // Cache tokens dominate real usage and were previously dropped from this
9
- // total entirely, understating the reported figure by roughly an order of
10
- // magnitude (#135).
11
- return (tokenUsage.inputTokens +
12
- tokenUsage.outputTokens +
13
- (tokenUsage.cacheCreationInputTokens ?? 0) +
14
- (tokenUsage.cacheReadInputTokens ?? 0));
15
- }
16
- export function formatCostUsd(costUsd) {
17
- return `$${costUsd.toFixed(costUsd < 1 ? 4 : 2)}`;
18
- }
19
- export function formatDuration(startedAtStr, finishedAtStr) {
20
- const startedAt = new Date(startedAtStr);
21
- const finishedAt = new Date(finishedAtStr);
22
- const durationMs = finishedAt.getTime() - startedAt.getTime();
23
- if (durationMs < 0 || !isFinite(durationMs))
24
- return undefined;
25
- const totalSeconds = Math.floor(durationMs / 1000);
26
- const minutes = Math.floor(totalSeconds / 60);
27
- const seconds = totalSeconds % 60;
28
- if (minutes > 0) {
29
- return `${minutes}m${seconds}s`;
30
- }
31
- return `${seconds}s`;
32
- }
33
- export function formatTokenCount(count) {
34
- if (count >= 1000000) {
35
- return `${(count / 1000000).toFixed(1)}M`;
36
- }
37
- if (count >= 1000) {
38
- return `${(count / 1000).toFixed(0)}k`;
39
- }
40
- return String(count);
41
- }
@@ -1,23 +0,0 @@
1
- import { appendFile, mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
2
- import { randomUUID } from 'node:crypto';
3
- import { dirname } from 'node:path';
4
- export async function writeJsonFile(path, value) {
5
- await mkdir(dirname(path), { recursive: true });
6
- const tempPath = `${path}.${randomUUID()}.tmp`;
7
- try {
8
- await writeFile(tempPath, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
9
- await rename(tempPath, path);
10
- }
11
- catch (error) {
12
- await rm(tempPath, { force: true }).catch(() => { });
13
- throw error;
14
- }
15
- }
16
- export async function readJsonFile(path) {
17
- const raw = await readFile(path, 'utf8');
18
- return JSON.parse(raw);
19
- }
20
- export async function appendJsonLine(path, value) {
21
- await mkdir(dirname(path), { recursive: true });
22
- await appendFile(path, `${JSON.stringify(value)}\n`, 'utf8');
23
- }
@@ -1,181 +0,0 @@
1
- import { readFileSync } from 'node:fs';
2
- import { link, mkdir, readFile, rm, writeFile } from 'node:fs/promises';
3
- import { dirname, join } from 'node:path';
4
- import { randomUUID } from 'node:crypto';
5
- function parseLockMetadata(raw) {
6
- try {
7
- const parsed = JSON.parse(raw);
8
- if (parsed === null || typeof parsed !== 'object') {
9
- return null;
10
- }
11
- const record = parsed;
12
- if (typeof record.pid !== 'number' ||
13
- !Number.isInteger(record.pid) ||
14
- typeof record.acquiredAt !== 'string') {
15
- return null;
16
- }
17
- const acquiredAtMs = Date.parse(record.acquiredAt);
18
- if (!Number.isFinite(acquiredAtMs)) {
19
- return null;
20
- }
21
- return {
22
- pid: record.pid,
23
- acquiredAt: record.acquiredAt,
24
- ...(typeof record.lockId === 'string' ? { lockId: record.lockId } : {}),
25
- ...(typeof record.commandLine === 'string' ? { commandLine: record.commandLine } : {}),
26
- };
27
- }
28
- catch {
29
- return null;
30
- }
31
- }
32
- function isPidAlive(pid) {
33
- if (pid <= 0) {
34
- return false;
35
- }
36
- try {
37
- process.kill(pid, 0);
38
- return true;
39
- }
40
- catch (error) {
41
- const code = error.code;
42
- if (code === 'ESRCH') {
43
- return false;
44
- }
45
- return true;
46
- }
47
- }
48
- function readProcessCommandLine(pid) {
49
- if (pid === process.pid) {
50
- return process.argv.join(' ');
51
- }
52
- try {
53
- return readFileSyncProcessCommandLine(pid);
54
- }
55
- catch {
56
- return undefined;
57
- }
58
- }
59
- function readFileSyncProcessCommandLine(pid) {
60
- const raw = readFileSync(`/proc/${pid}/cmdline`, 'utf8');
61
- const commandLine = raw.replace(/\0/g, ' ').trim();
62
- return commandLine.length === 0 ? undefined : commandLine;
63
- }
64
- function defaultProcessInspector() {
65
- return {
66
- isPidAlive,
67
- readCommandLine: readProcessCommandLine,
68
- };
69
- }
70
- async function readLockMetadata(path) {
71
- try {
72
- return parseLockMetadata(await readFile(path, 'utf8'));
73
- }
74
- catch {
75
- return null;
76
- }
77
- }
78
- export async function readFileLockStatus(path, options) {
79
- const metadata = await readLockMetadata(path);
80
- if (metadata === null) {
81
- try {
82
- await readFile(path, 'utf8');
83
- return { present: true, active: false, staleReason: 'invalid-metadata' };
84
- }
85
- catch {
86
- return { present: false, active: false, staleReason: 'missing' };
87
- }
88
- }
89
- const now = options?.now ?? new Date();
90
- const ageMs = now.getTime() - Date.parse(metadata.acquiredAt);
91
- if (options?.staleAfterMs !== undefined && ageMs >= options.staleAfterMs) {
92
- return { present: true, active: false, metadata, ageMs, staleReason: 'expired' };
93
- }
94
- const inspector = options?.processInspector ?? defaultProcessInspector();
95
- if (!inspector.isPidAlive(metadata.pid)) {
96
- return { present: true, active: false, metadata, ageMs, staleReason: 'pid-not-alive' };
97
- }
98
- const commandLine = inspector.readCommandLine(metadata.pid);
99
- if (commandLine !== undefined &&
100
- ((metadata.commandLine !== undefined && commandLine !== metadata.commandLine) ||
101
- (metadata.commandLine === undefined &&
102
- options?.expectedCommandIncludes !== undefined &&
103
- !options.expectedCommandIncludes.every((fragment) => commandLine.includes(fragment))))) {
104
- return {
105
- present: true,
106
- active: false,
107
- metadata,
108
- ageMs,
109
- commandLine,
110
- staleReason: 'pid-command-mismatch',
111
- };
112
- }
113
- return {
114
- present: true,
115
- active: true,
116
- metadata,
117
- ageMs,
118
- ...(commandLine === undefined ? {} : { commandLine }),
119
- };
120
- }
121
- export async function acquireFileLock(path, options) {
122
- await mkdir(dirname(path), { recursive: true });
123
- const metadata = {
124
- pid: process.pid,
125
- acquiredAt: (options?.now ?? new Date()).toISOString(),
126
- lockId: randomUUID(),
127
- commandLine: process.argv.join(' '),
128
- };
129
- async function tryAcquire() {
130
- const tempPath = join(dirname(path), `.tick-lock-${metadata.lockId}.tmp`);
131
- await writeFile(tempPath, `${JSON.stringify(metadata)}\n`, {
132
- encoding: 'utf8',
133
- flag: 'wx',
134
- });
135
- try {
136
- await link(tempPath, path);
137
- }
138
- finally {
139
- await rm(tempPath, { force: true });
140
- }
141
- return {
142
- acquired: true,
143
- metadata,
144
- async release() {
145
- const current = await readLockMetadata(path);
146
- if (current?.pid === metadata.pid &&
147
- current.acquiredAt === metadata.acquiredAt &&
148
- current.lockId === metadata.lockId) {
149
- await rm(path, { force: true });
150
- }
151
- },
152
- };
153
- }
154
- try {
155
- return await tryAcquire();
156
- }
157
- catch (error) {
158
- if (error.code === 'EEXIST') {
159
- const status = await readFileLockStatus(path, {
160
- ...(options?.staleAfterMs === undefined ? {} : { staleAfterMs: options.staleAfterMs }),
161
- now: options?.now ?? new Date(),
162
- });
163
- if (!status.active) {
164
- await rm(path, { force: true });
165
- try {
166
- return await tryAcquire();
167
- }
168
- catch (retryError) {
169
- if (retryError.code !== 'EEXIST') {
170
- throw retryError;
171
- }
172
- }
173
- }
174
- return {
175
- acquired: false,
176
- async release() { },
177
- };
178
- }
179
- throw error;
180
- }
181
- }
@@ -1,42 +0,0 @@
1
- import { renameSync, rmSync, statSync } from 'node:fs';
2
- export const DEFAULT_LOG_MAX_BYTES = 20 * 1024 * 1024;
3
- export const DEFAULT_LOG_ROTATE_CHECK_INTERVAL_MS = 5 * 60 * 1000;
4
- export function resolveLogMaxBytes(env = process.env) {
5
- const raw = env.WAKE_LOG_MAX_BYTES;
6
- if (raw === undefined || raw.trim() === '') {
7
- return DEFAULT_LOG_MAX_BYTES;
8
- }
9
- const parsed = Number(raw);
10
- if (!Number.isFinite(parsed) || parsed <= 0) {
11
- return DEFAULT_LOG_MAX_BYTES;
12
- }
13
- return Math.floor(parsed);
14
- }
15
- export function resolveLogRotateCheckIntervalMs(env = process.env) {
16
- const raw = env.WAKE_LOG_ROTATE_CHECK_INTERVAL_MS;
17
- if (raw === undefined || raw.trim() === '') {
18
- return DEFAULT_LOG_ROTATE_CHECK_INTERVAL_MS;
19
- }
20
- const parsed = Number(raw);
21
- if (!Number.isFinite(parsed) || parsed <= 0) {
22
- return DEFAULT_LOG_ROTATE_CHECK_INTERVAL_MS;
23
- }
24
- return Math.floor(parsed);
25
- }
26
- export function rotateLogFileIfNeeded(logFile, maxBytes = DEFAULT_LOG_MAX_BYTES) {
27
- try {
28
- if (statSync(logFile).size < maxBytes) {
29
- return false;
30
- }
31
- }
32
- catch (error) {
33
- if (error.code === 'ENOENT') {
34
- return false;
35
- }
36
- throw error;
37
- }
38
- const backupFile = `${logFile}.1`;
39
- rmSync(backupFile, { force: true });
40
- renameSync(logFile, backupFile);
41
- return true;
42
- }