cloving 1.1.0 → 1.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 (568) hide show
  1. package/README.md +584 -144
  2. package/assets/watch-fonts/fira-code-OFL.md +93 -0
  3. package/assets/watch-fonts/fira-code-latin-400-normal.woff2 +0 -0
  4. package/assets/watch-fonts/fira-code-latin-500-normal.woff2 +0 -0
  5. package/assets/watch-fonts/heebo-OFL.md +93 -0
  6. package/assets/watch-fonts/heebo-latin-500-normal.woff2 +0 -0
  7. package/assets/watch-fonts/heebo-latin-700-normal.woff2 +0 -0
  8. package/assets/watch-fonts/heebo-latin-800-normal.woff2 +0 -0
  9. package/assets/watch-fonts/manifest.json +112 -0
  10. package/assets/watch-fonts/space-grotesk-OFL.md +93 -0
  11. package/assets/watch-fonts/space-grotesk-latin-400-normal.woff2 +0 -0
  12. package/assets/watch-fonts/space-grotesk-latin-500-normal.woff2 +0 -0
  13. package/assets/watch-fonts/space-grotesk-latin-600-normal.woff2 +0 -0
  14. package/assets/watch-fonts/space-grotesk-latin-700-normal.woff2 +0 -0
  15. package/dist/src/agent-harness-shell.d.ts +12 -0
  16. package/dist/src/agent-harness-shell.js +90 -0
  17. package/dist/src/agent-harness-versions.d.ts +8 -0
  18. package/dist/src/agent-harness-versions.js +49 -0
  19. package/dist/src/agent-harnesses.d.ts +4 -0
  20. package/dist/src/agent-harnesses.js +13 -0
  21. package/dist/src/authority/commands.d.ts +2 -0
  22. package/dist/src/authority/commands.js +49 -8
  23. package/dist/src/authority/dispatch-decision.d.ts +1 -0
  24. package/dist/src/authority/dispatch-decision.js +7 -4
  25. package/dist/src/authority/events.js +2 -2
  26. package/dist/src/authority/gate-reduction.d.ts +1 -0
  27. package/dist/src/authority/gate-reduction.js +18 -3
  28. package/dist/src/authority/gates.d.ts +2 -1
  29. package/dist/src/authority/gates.js +5 -1
  30. package/dist/src/authority/handoff-chain.d.ts +24 -0
  31. package/dist/src/authority/handoff-chain.js +46 -0
  32. package/dist/src/authority/operations.js +1 -1
  33. package/dist/src/authority/reconciliation.d.ts +1 -0
  34. package/dist/src/authority/reconciliation.js +18 -11
  35. package/dist/src/authority/reduction.d.ts +1 -1
  36. package/dist/src/authority/reduction.js +6 -1
  37. package/dist/src/authority/status-input.d.ts +1 -1
  38. package/dist/src/authority/status.d.ts +1 -0
  39. package/dist/src/authority/status.js +27 -3
  40. package/dist/src/authority/transitions.d.ts +5 -5
  41. package/dist/src/authority/transitions.js +9 -0
  42. package/dist/src/broker/actor/authority-delivery.js +1 -0
  43. package/dist/src/broker/actor/authority-queries.d.ts +11 -1
  44. package/dist/src/broker/actor/authority-queries.js +67 -3
  45. package/dist/src/broker/actor/authority-receipts.js +11 -1
  46. package/dist/src/broker/actor/authority-session.js +2 -2
  47. package/dist/src/broker/actor/authority-settings.js +4 -0
  48. package/dist/src/broker/actor/delivery-intents.d.ts +3 -1
  49. package/dist/src/broker/actor/delivery-intents.js +4 -4
  50. package/dist/src/broker/actor/effect-delivery.js +13 -1
  51. package/dist/src/broker/actor/effect-queries.d.ts +1 -0
  52. package/dist/src/broker/actor/effect-queries.js +7 -0
  53. package/dist/src/broker/actor/pin-check.js +1 -1
  54. package/dist/src/broker/actor/stop-plan.js +1 -1
  55. package/dist/src/broker/actor/turn-state.js +1 -1
  56. package/dist/src/broker/authority-admission.js +26 -5
  57. package/dist/src/broker/authority-restore.js +1 -0
  58. package/dist/src/broker/decision-restore.js +4 -4
  59. package/dist/src/broker/socket-address.d.ts +3 -1
  60. package/dist/src/broker/socket-address.js +2 -2
  61. package/dist/src/cli/arguments.d.ts +11 -13
  62. package/dist/src/cli/arguments.js +37 -107
  63. package/dist/src/cli/command-effects.d.ts +7 -0
  64. package/dist/src/cli/command-effects.js +39 -0
  65. package/dist/src/cli/commands.js +11 -4
  66. package/dist/src/cli/config-arguments.d.ts +11 -0
  67. package/dist/src/cli/config-arguments.js +59 -0
  68. package/dist/src/cli/config-command.d.ts +2 -0
  69. package/dist/src/cli/config-command.js +105 -0
  70. package/dist/src/cli/config-file.d.ts +3 -0
  71. package/dist/src/cli/config-file.js +50 -0
  72. package/dist/src/cli/config-lock.d.ts +7 -0
  73. package/dist/src/cli/config-lock.js +61 -0
  74. package/dist/src/cli/config-notice.d.ts +5 -0
  75. package/dist/src/cli/config-notice.js +46 -0
  76. package/dist/src/cli/doctor-github.d.ts +9 -0
  77. package/dist/src/cli/doctor-github.js +138 -0
  78. package/dist/src/cli/doctor-harness.d.ts +13 -0
  79. package/dist/src/cli/doctor-harness.js +242 -0
  80. package/dist/src/cli/doctor-local.d.ts +18 -0
  81. package/dist/src/cli/doctor-local.js +77 -0
  82. package/dist/src/cli/doctor-runtime.d.ts +15 -0
  83. package/dist/src/cli/doctor-runtime.js +176 -0
  84. package/dist/src/cli/doctor-service.d.ts +1 -0
  85. package/dist/src/cli/doctor-service.js +11 -0
  86. package/dist/src/cli/doctor-workflows.d.ts +3 -0
  87. package/dist/src/cli/doctor-workflows.js +45 -0
  88. package/dist/src/cli/doctor.d.ts +15 -0
  89. package/dist/src/cli/doctor.js +190 -0
  90. package/dist/src/cli/github-ci-progress.d.ts +8 -0
  91. package/dist/src/cli/github-ci-progress.js +83 -0
  92. package/dist/src/cli/github-retry.d.ts +6 -0
  93. package/dist/src/cli/github-retry.js +47 -0
  94. package/dist/src/cli/harness-probes.d.ts +22 -0
  95. package/dist/src/cli/harness-probes.js +183 -0
  96. package/dist/src/cli/main.d.ts +7 -1
  97. package/dist/src/cli/main.js +39 -61
  98. package/dist/src/cli/phone-arguments.d.ts +14 -0
  99. package/dist/src/cli/phone-arguments.js +37 -0
  100. package/dist/src/cli/phone-client.d.ts +2 -0
  101. package/dist/src/cli/phone-client.js +32 -0
  102. package/dist/src/cli/phone-command.d.ts +13 -0
  103. package/dist/src/cli/phone-command.js +101 -0
  104. package/dist/src/cli/probe-command.d.ts +36 -0
  105. package/dist/src/cli/probe-command.js +59 -0
  106. package/dist/src/cli/project-settings.d.ts +4 -0
  107. package/dist/src/cli/project-settings.js +33 -0
  108. package/dist/src/cli/render.d.ts +3 -1
  109. package/dist/src/cli/render.js +102 -39
  110. package/dist/src/cli/report-github.d.ts +18 -0
  111. package/dist/src/cli/report-github.js +200 -0
  112. package/dist/src/cli/report.d.ts +17 -0
  113. package/dist/src/cli/report.js +192 -0
  114. package/dist/src/cli/repository-arguments.d.ts +5 -0
  115. package/dist/src/cli/repository-arguments.js +34 -0
  116. package/dist/src/cli/runtime-arguments.d.ts +4 -0
  117. package/dist/src/cli/runtime-arguments.js +15 -0
  118. package/dist/src/cli/runtime-directory.d.ts +6 -2
  119. package/dist/src/cli/runtime-directory.js +72 -14
  120. package/dist/src/cli/toolchain.d.ts +2 -0
  121. package/dist/src/cli/toolchain.js +22 -2
  122. package/dist/src/cli/usage-render.d.ts +5 -0
  123. package/dist/src/cli/usage-render.js +40 -1
  124. package/dist/src/cli/usage.d.ts +3 -3
  125. package/dist/src/cli/usage.js +74 -45
  126. package/dist/src/cli/watch-actions.d.ts +2 -0
  127. package/dist/src/cli/watch-actions.js +4 -4
  128. package/dist/src/cli/watch-board-view.d.ts +12 -1
  129. package/dist/src/cli/watch-board-view.js +64 -12
  130. package/dist/src/cli/watch-board.d.ts +7 -1
  131. package/dist/src/cli/watch-board.js +61 -16
  132. package/dist/src/cli/watch-card-forms.js +2 -2
  133. package/dist/src/cli/watch-client.d.ts +1 -1
  134. package/dist/src/cli/watch-client.js +12 -3
  135. package/dist/src/cli/watch-header-view.d.ts +27 -0
  136. package/dist/src/cli/watch-header-view.js +116 -0
  137. package/dist/src/cli/watch-model.d.ts +10 -4
  138. package/dist/src/cli/watch-model.js +49 -59
  139. package/dist/src/cli/watch-page.js +67 -14
  140. package/dist/src/cli/watch-phases.js +3 -3
  141. package/dist/src/cli/watch-phone-client.d.ts +1 -0
  142. package/dist/src/cli/watch-phone-client.js +84 -0
  143. package/dist/src/cli/watch-phone-view.d.ts +56 -0
  144. package/dist/src/cli/watch-phone-view.js +113 -0
  145. package/dist/src/cli/watch-phone.d.ts +5 -0
  146. package/dist/src/cli/watch-phone.js +53 -0
  147. package/dist/src/cli/watch-pr-command.d.ts +5 -2
  148. package/dist/src/cli/watch-pr-command.js +41 -4
  149. package/dist/src/cli/watch-pr-identity.d.ts +14 -2
  150. package/dist/src/cli/watch-pr-identity.js +25 -0
  151. package/dist/src/cli/watch-pr-observer.d.ts +1 -0
  152. package/dist/src/cli/watch-pr-observer.js +48 -6
  153. package/dist/src/cli/watch-pull-request.d.ts +12 -0
  154. package/dist/src/cli/watch-pull-request.js +134 -0
  155. package/dist/src/cli/watch-reads.d.ts +7 -1
  156. package/dist/src/cli/watch-reads.js +42 -20
  157. package/dist/src/cli/watch-render.d.ts +23 -2
  158. package/dist/src/cli/watch-render.js +2 -1
  159. package/dist/src/cli/watch-server.js +56 -7
  160. package/dist/src/cli/watch-turn.d.ts +4 -1
  161. package/dist/src/cli/watch-turn.js +38 -2
  162. package/dist/src/cli/watch-usage.js +5 -1
  163. package/dist/src/cli/watch-view.d.ts +10 -17
  164. package/dist/src/cli/watch-view.js +33 -77
  165. package/dist/src/cli.js +106 -23
  166. package/dist/src/command-settings.d.ts +16 -0
  167. package/dist/src/command-settings.js +42 -0
  168. package/dist/src/configuration-change.d.ts +11 -0
  169. package/dist/src/configuration-change.js +62 -0
  170. package/dist/src/configuration-display.d.ts +21 -0
  171. package/dist/src/configuration-display.js +69 -0
  172. package/dist/src/configuration-schema.d.ts +49 -0
  173. package/dist/src/configuration-schema.js +159 -0
  174. package/dist/src/daemon/claude-turn.d.ts +20 -5
  175. package/dist/src/daemon/claude-turn.js +116 -53
  176. package/dist/src/daemon/claude-worker.d.ts +3 -5
  177. package/dist/src/daemon/claude-worker.js +64 -80
  178. package/dist/src/daemon/command-journal.d.ts +5 -0
  179. package/dist/src/daemon/command-journal.js +50 -0
  180. package/dist/src/daemon/command-process.d.ts +28 -0
  181. package/dist/src/daemon/command-process.js +164 -0
  182. package/dist/src/daemon/command-worker.d.ts +19 -0
  183. package/dist/src/daemon/command-worker.js +182 -0
  184. package/dist/src/daemon/cursor-stream.d.ts +4 -0
  185. package/dist/src/daemon/cursor-stream.js +154 -0
  186. package/dist/src/daemon/daemon-adapters.d.ts +58 -0
  187. package/dist/src/daemon/daemon-adapters.js +102 -0
  188. package/dist/src/daemon/daemon-loops.d.ts +14 -0
  189. package/dist/src/daemon/daemon-loops.js +39 -0
  190. package/dist/src/daemon/daemon.d.ts +3 -30
  191. package/dist/src/daemon/daemon.js +132 -110
  192. package/dist/src/daemon/declared-input.d.ts +3 -0
  193. package/dist/src/daemon/declared-input.js +9 -0
  194. package/dist/src/daemon/delivery-router.js +7 -1
  195. package/dist/src/daemon/gemini-stream.d.ts +4 -0
  196. package/dist/src/daemon/gemini-stream.js +129 -0
  197. package/dist/src/daemon/github-calls.d.ts +4 -0
  198. package/dist/src/daemon/github-calls.js +16 -7
  199. package/dist/src/daemon/github-ci-rerun.d.ts +26 -0
  200. package/dist/src/daemon/github-ci-rerun.js +92 -0
  201. package/dist/src/daemon/github-ci.d.ts +6 -0
  202. package/dist/src/daemon/github-ci.js +251 -0
  203. package/dist/src/daemon/github-merge-call.d.ts +16 -0
  204. package/dist/src/daemon/github-merge-call.js +73 -0
  205. package/dist/src/daemon/github-merge.d.ts +3 -5
  206. package/dist/src/daemon/github-merge.js +59 -98
  207. package/dist/src/daemon/github-methods.d.ts +28 -0
  208. package/dist/src/daemon/github-methods.js +90 -16
  209. package/dist/src/daemon/github-operation.d.ts +3 -0
  210. package/dist/src/daemon/github-retry.d.ts +6 -0
  211. package/dist/src/daemon/github-retry.js +13 -0
  212. package/dist/src/daemon/github-ticket-status.js +27 -1
  213. package/dist/src/daemon/github-worker.js +2 -1
  214. package/dist/src/daemon/handoff-worker.d.ts +10 -0
  215. package/dist/src/daemon/handoff-worker.js +232 -0
  216. package/dist/src/daemon/issue-queue.d.ts +2 -0
  217. package/dist/src/daemon/issue-queue.js +92 -63
  218. package/dist/src/daemon/notify-journal.d.ts +18 -0
  219. package/dist/src/daemon/notify-journal.js +108 -0
  220. package/dist/src/daemon/notify-message.js +2 -1
  221. package/dist/src/daemon/notify.js +177 -37
  222. package/dist/src/daemon/opencode-stream.d.ts +5 -0
  223. package/dist/src/daemon/opencode-stream.js +87 -0
  224. package/dist/src/daemon/queue-status.d.ts +4 -0
  225. package/dist/src/daemon/queue-status.js +38 -0
  226. package/dist/src/daemon/retry-worktree.d.ts +18 -0
  227. package/dist/src/daemon/retry-worktree.js +139 -0
  228. package/dist/src/daemon/retrying-turn.d.ts +5 -0
  229. package/dist/src/daemon/retrying-turn.js +145 -21
  230. package/dist/src/daemon/schedule-journal.d.ts +19 -0
  231. package/dist/src/daemon/schedule-journal.js +57 -0
  232. package/dist/src/daemon/text-output.d.ts +18 -0
  233. package/dist/src/daemon/text-output.js +44 -0
  234. package/dist/src/daemon/ticket-dependency-waits.d.ts +18 -0
  235. package/dist/src/daemon/ticket-dependency-waits.js +60 -0
  236. package/dist/src/daemon/ticket-registration.d.ts +10 -8
  237. package/dist/src/daemon/ticket-registration.js +146 -47
  238. package/dist/src/daemon/ticket-source.d.ts +4 -1
  239. package/dist/src/daemon/ticket-source.js +8 -2
  240. package/dist/src/daemon/turn-command.d.ts +10 -0
  241. package/dist/src/daemon/turn-command.js +33 -0
  242. package/dist/src/daemon/turn-report.d.ts +18 -0
  243. package/dist/src/daemon/turn-report.js +79 -0
  244. package/dist/src/daemon/work-tree.d.ts +2 -1
  245. package/dist/src/daemon/work-tree.js +15 -12
  246. package/dist/src/daemon/workflow-generations.d.ts +32 -0
  247. package/dist/src/daemon/workflow-generations.js +57 -0
  248. package/dist/src/daemon/workflow-replay.d.ts +16 -0
  249. package/dist/src/daemon/workflow-replay.js +58 -0
  250. package/dist/src/daemon/workflow-schedules.d.ts +27 -0
  251. package/dist/src/daemon/workflow-schedules.js +185 -0
  252. package/dist/src/decision-visibility.d.ts +2 -0
  253. package/dist/src/decision-visibility.js +10 -0
  254. package/dist/src/decision-wait.d.ts +1 -0
  255. package/dist/src/decision-wait.js +3 -0
  256. package/dist/src/delivery-backoff.d.ts +1 -0
  257. package/dist/src/delivery-backoff.js +3 -0
  258. package/dist/src/doctor-report.d.ts +24 -0
  259. package/dist/src/doctor-report.js +70 -0
  260. package/dist/src/execution-pin.d.ts +9 -0
  261. package/dist/src/execution-pin.js +86 -2
  262. package/dist/src/grok-result.d.ts +12 -0
  263. package/dist/src/grok-result.js +61 -0
  264. package/dist/src/harness-defaults.d.ts +35 -0
  265. package/dist/src/harness-defaults.js +121 -0
  266. package/dist/src/host/decision-resume.d.ts +35 -0
  267. package/dist/src/host/decision-resume.js +86 -0
  268. package/dist/src/host/gate-bridge.d.ts +48 -0
  269. package/dist/src/host/gate-bridge.js +124 -0
  270. package/dist/src/host/run-wait.d.ts +26 -0
  271. package/dist/src/host/run-wait.js +37 -0
  272. package/dist/src/host/start-delivery.d.ts +3 -2
  273. package/dist/src/host/start-delivery.js +11 -4
  274. package/dist/src/host/step-bridge-host.d.ts +6 -19
  275. package/dist/src/host/step-bridge-host.js +57 -55
  276. package/dist/src/host/world-reconciliation.d.ts +1 -0
  277. package/dist/src/host/world-reconciliation.js +3 -0
  278. package/dist/src/host/world-runs.js +5 -0
  279. package/dist/src/issue-identity.d.ts +6 -0
  280. package/dist/src/issue-identity.js +23 -0
  281. package/dist/src/merge-request.d.ts +19 -0
  282. package/dist/src/merge-request.js +32 -0
  283. package/dist/src/phone/canonical-json.d.ts +1 -0
  284. package/dist/src/phone/canonical-json.js +16 -0
  285. package/dist/src/phone/phone-link.d.ts +7 -0
  286. package/dist/src/phone/phone-link.js +21 -0
  287. package/dist/src/phone/qr-data.d.ts +8 -0
  288. package/dist/src/phone/qr-data.js +133 -0
  289. package/dist/src/phone/qr-matrix.d.ts +6 -0
  290. package/dist/src/phone/qr-matrix.js +175 -0
  291. package/dist/src/phone/qr-penalty.d.ts +3 -0
  292. package/dist/src/phone/qr-penalty.js +67 -0
  293. package/dist/src/phone/qr-picture.d.ts +5 -0
  294. package/dist/src/phone/qr-picture.js +24 -0
  295. package/dist/src/private-config.schema.json +263 -0
  296. package/dist/src/project-config.schema.json +65 -0
  297. package/dist/src/project-settings.d.ts +19 -0
  298. package/dist/src/project-settings.js +131 -0
  299. package/dist/src/relay/answer-check.d.ts +24 -0
  300. package/dist/src/relay/answer-check.js +145 -0
  301. package/dist/src/relay/answer-inbox.d.ts +15 -0
  302. package/dist/src/relay/answer-inbox.js +173 -0
  303. package/dist/src/relay/daemon-keys.d.ts +16 -0
  304. package/dist/src/relay/daemon-keys.js +75 -0
  305. package/dist/src/relay/decision-check.d.ts +3 -0
  306. package/dist/src/relay/decision-check.js +77 -0
  307. package/dist/src/relay/decision-close.d.ts +6 -0
  308. package/dist/src/relay/decision-close.js +72 -0
  309. package/dist/src/relay/decision-envelopes.d.ts +29 -0
  310. package/dist/src/relay/decision-envelopes.js +93 -0
  311. package/dist/src/relay/decision-watch.d.ts +14 -0
  312. package/dist/src/relay/decision-watch.js +68 -0
  313. package/dist/src/relay/envelope-post.d.ts +8 -0
  314. package/dist/src/relay/envelope-post.js +71 -0
  315. package/dist/src/relay/envelope.d.ts +28 -0
  316. package/dist/src/relay/envelope.js +53 -0
  317. package/dist/src/relay/hpke.d.ts +25 -0
  318. package/dist/src/relay/hpke.js +108 -0
  319. package/dist/src/relay/pairing-checks.d.ts +42 -0
  320. package/dist/src/relay/pairing-checks.js +172 -0
  321. package/dist/src/relay/pairing-follow.d.ts +8 -0
  322. package/dist/src/relay/pairing-follow.js +95 -0
  323. package/dist/src/relay/pairing-session.d.ts +29 -0
  324. package/dist/src/relay/pairing-session.js +87 -0
  325. package/dist/src/relay/phone-delivery.d.ts +51 -0
  326. package/dist/src/relay/phone-delivery.js +139 -0
  327. package/dist/src/relay/phone-devices.d.ts +36 -0
  328. package/dist/src/relay/phone-devices.js +46 -0
  329. package/dist/src/relay/phone-inbox.d.ts +18 -0
  330. package/dist/src/relay/phone-inbox.js +17 -0
  331. package/dist/src/relay/phone-operations.d.ts +18 -0
  332. package/dist/src/relay/phone-operations.js +121 -0
  333. package/dist/src/relay/phone-outbox.d.ts +21 -0
  334. package/dist/src/relay/phone-outbox.js +25 -0
  335. package/dist/src/relay/phone-socket.d.ts +6 -0
  336. package/dist/src/relay/phone-socket.js +63 -0
  337. package/dist/src/relay/relay-control.d.ts +7 -0
  338. package/dist/src/relay/relay-control.js +24 -0
  339. package/dist/src/relay/relay-files.d.ts +2 -0
  340. package/dist/src/relay/relay-files.js +23 -0
  341. package/dist/src/relay/relay-heartbeat.d.ts +17 -0
  342. package/dist/src/relay/relay-heartbeat.js +81 -0
  343. package/dist/src/relay/relay-http.d.ts +14 -0
  344. package/dist/src/relay/relay-http.js +63 -0
  345. package/dist/src/relay/relay-registration.d.ts +15 -0
  346. package/dist/src/relay/relay-registration.js +63 -0
  347. package/dist/src/relay/relay-service.d.ts +25 -0
  348. package/dist/src/relay/relay-service.js +216 -0
  349. package/dist/src/relay/relay-store.d.ts +48 -0
  350. package/dist/src/relay/relay-store.js +131 -0
  351. package/dist/src/relay/sealed-post.d.ts +25 -0
  352. package/dist/src/relay/sealed-post.js +52 -0
  353. package/dist/src/relay.d.ts +1 -0
  354. package/dist/src/relay.js +8 -0
  355. package/dist/src/report-statistics.d.ts +50 -0
  356. package/dist/src/report-statistics.js +70 -0
  357. package/dist/src/report.d.ts +171 -0
  358. package/dist/src/report.js +119 -0
  359. package/dist/src/repository-identity.d.ts +4 -0
  360. package/dist/src/repository-identity.js +4 -0
  361. package/dist/src/review-subject.d.ts +41 -0
  362. package/dist/src/review-subject.js +91 -0
  363. package/dist/src/run-wait.d.ts +23 -0
  364. package/dist/src/run-wait.js +20 -0
  365. package/dist/src/service/active-tickets.d.ts +4 -0
  366. package/dist/src/service/active-tickets.js +49 -0
  367. package/dist/src/service/command-effects.d.ts +4 -0
  368. package/dist/src/service/command-effects.js +16 -0
  369. package/dist/src/service/decision-handler.d.ts +4 -0
  370. package/dist/src/service/decision-handler.js +39 -4
  371. package/dist/src/service/gateway.js +18 -3
  372. package/dist/src/service/queue-runs.d.ts +3 -0
  373. package/dist/src/service/queue-runs.js +39 -0
  374. package/dist/src/service/registry.d.ts +22 -3
  375. package/dist/src/service/registry.js +51 -8
  376. package/dist/src/service/replies.d.ts +10 -0
  377. package/dist/src/service/replies.js +12 -0
  378. package/dist/src/service/run-handlers.js +45 -54
  379. package/dist/src/service/run-metadata.d.ts +8 -0
  380. package/dist/src/service/run-metadata.js +53 -0
  381. package/dist/src/service/run-waits.d.ts +3 -0
  382. package/dist/src/service/run-waits.js +41 -0
  383. package/dist/src/service/service.d.ts +21 -2
  384. package/dist/src/service/service.js +23 -5
  385. package/dist/src/service/submission-handler.js +70 -19
  386. package/dist/src/service/worker-port.d.ts +1 -0
  387. package/dist/src/service/worker-totals.js +10 -1
  388. package/dist/src/step-bridge.d.ts +32 -0
  389. package/dist/src/steps/decision-gate.d.ts +2 -1
  390. package/dist/src/steps/decision-gate.js +7 -0
  391. package/dist/src/steps/handoff.d.ts +2 -0
  392. package/dist/src/steps/handoff.js +13 -0
  393. package/dist/src/steps/merge-by-person.d.ts +2 -0
  394. package/dist/src/steps/merge-by-person.js +18 -0
  395. package/dist/src/steps/merge-when-green.d.ts +2 -0
  396. package/dist/src/steps/merge-when-green.js +62 -0
  397. package/dist/src/steps/review-by-agent.d.ts +5 -0
  398. package/dist/src/steps/review-by-agent.js +124 -0
  399. package/dist/src/steps/review-by-person.d.ts +4 -0
  400. package/dist/src/steps/review-by-person.js +16 -0
  401. package/dist/src/steps/review-subject.d.ts +2 -0
  402. package/dist/src/steps/review-subject.js +11 -0
  403. package/dist/src/steps/run-command.d.ts +2 -0
  404. package/dist/src/steps/run-command.js +15 -0
  405. package/dist/src/steps/sleep.d.ts +3 -0
  406. package/dist/src/steps/sleep.js +19 -0
  407. package/dist/src/steps/wait-for-decision.d.ts +2 -0
  408. package/dist/src/steps/wait-for-decision.js +71 -0
  409. package/dist/src/steps/wait-for-run.d.ts +5 -0
  410. package/dist/src/steps/wait-for-run.js +9 -0
  411. package/dist/src/storage/decision-snapshots.d.ts +1 -0
  412. package/dist/src/storage/decision-snapshots.js +7 -1
  413. package/dist/src/submission.d.ts +4 -0
  414. package/dist/src/submission.js +6 -2
  415. package/dist/src/testing.d.ts +29 -0
  416. package/dist/src/testing.js +264 -0
  417. package/dist/src/ticket-dependencies.d.ts +1 -0
  418. package/dist/src/ticket-dependencies.js +15 -0
  419. package/dist/src/ticket-status-stream.d.ts +9 -0
  420. package/dist/src/ticket-status-stream.js +94 -0
  421. package/dist/src/ticket-status.js +7 -4
  422. package/dist/src/token-prices.d.ts +14 -4
  423. package/dist/src/token-prices.js +56 -11
  424. package/dist/src/turn-profile.d.ts +1 -0
  425. package/dist/src/turn-profile.js +8 -1
  426. package/dist/src/worker-usage.d.ts +25 -0
  427. package/dist/src/worker-usage.js +58 -1
  428. package/dist/src/workflow-admission.d.ts +6 -0
  429. package/dist/src/workflow-candidate.d.ts +7 -2
  430. package/dist/src/workflow-candidate.js +48 -5
  431. package/dist/src/workflow-contracts.d.ts +2 -0
  432. package/dist/src/workflow-contracts.js +8 -3
  433. package/dist/src/workflow-declaration.d.ts +31 -2
  434. package/dist/src/workflow-declaration.js +140 -16
  435. package/dist/src/workflow-discovery.d.ts +19 -0
  436. package/dist/src/workflow-discovery.js +36 -0
  437. package/dist/src/workflow-refusals.d.ts +6 -0
  438. package/dist/src/workflow-refusals.js +42 -0
  439. package/dist/src/workflow-schedule.d.ts +22 -0
  440. package/dist/src/workflow-schedule.js +53 -0
  441. package/dist/src/workflows.d.ts +12 -1
  442. package/dist/src/workflows.js +9 -0
  443. package/dist/tools/admit-workflow.d.ts +14 -0
  444. package/dist/tools/admit-workflow.js +107 -0
  445. package/dist/tools/doctor-adoption.d.ts +1 -0
  446. package/dist/tools/doctor-adoption.js +11 -0
  447. package/dist/tools/project-configuration.d.ts +4 -0
  448. package/dist/tools/project-configuration.js +47 -0
  449. package/dist/tools/self-host-processes.d.ts +1 -0
  450. package/dist/tools/self-host-processes.js +33 -22
  451. package/dist/tools/self-host-project.d.ts +21 -0
  452. package/dist/tools/self-host-project.js +224 -0
  453. package/dist/tools/self-host-runtime.d.ts +16 -0
  454. package/dist/tools/self-host-runtime.js +60 -0
  455. package/dist/tools/self-host-workflows.d.ts +1 -0
  456. package/dist/tools/self-host-workflows.js +36 -1
  457. package/dist/tools/self-host.js +106 -135
  458. package/dist/tools/workflow-bundle-dependencies.d.ts +5 -0
  459. package/dist/tools/workflow-bundle-dependencies.js +93 -0
  460. package/dist/tools/workflow-bundles.d.ts +20 -0
  461. package/dist/tools/workflow-bundles.js +173 -0
  462. package/dist/tools/workflow-candidate-counts.d.ts +12 -0
  463. package/dist/tools/workflow-candidate-counts.js +266 -0
  464. package/dist/tools/workflow-candidate-fields.d.ts +5 -0
  465. package/dist/tools/workflow-candidate-fields.js +24 -0
  466. package/dist/tools/workflow-candidate-helper-counts.d.ts +10 -0
  467. package/dist/tools/workflow-candidate-helper-counts.js +129 -0
  468. package/dist/tools/workflow-candidate-program.d.ts +13 -0
  469. package/dist/tools/workflow-candidate-program.js +106 -0
  470. package/dist/tools/workflow-candidate-source.d.ts +6 -0
  471. package/dist/tools/workflow-candidate-source.js +169 -0
  472. package/dist/tools/workflow-candidate-syntax.d.ts +21 -0
  473. package/dist/tools/workflow-candidate-syntax.js +263 -0
  474. package/dist/tools/workflow-command.d.ts +1 -0
  475. package/dist/tools/workflow-command.js +143 -0
  476. package/dist/tools/workflow-folder-capture.d.ts +18 -0
  477. package/dist/tools/workflow-folder-capture.js +261 -0
  478. package/dist/tools/workflow-folders.d.ts +49 -0
  479. package/dist/tools/workflow-folders.js +203 -0
  480. package/dist/tools/workflow-source-effects.d.ts +10 -0
  481. package/dist/tools/workflow-source-effects.js +213 -0
  482. package/dist/tools/workflow-test-hook.d.ts +7 -0
  483. package/dist/tools/workflow-test-hook.js +16 -0
  484. package/dist/tools/workflow-test-loader.d.ts +1 -0
  485. package/dist/tools/workflow-test-loader.js +10 -0
  486. package/dist/workflows/develop-prd.js +71 -3
  487. package/dist/workflows/develop-ticket.js +6 -1
  488. package/dist/workflows/ticket-prompts.js +17 -3
  489. package/package.json +66 -6
  490. package/templates/develop/README.md +78 -0
  491. package/templates/develop/develop/accept.ts +11 -0
  492. package/templates/develop/develop/flow-tests.ts +357 -0
  493. package/templates/develop/develop/local.ts +40 -0
  494. package/templates/develop/develop/option-tests.ts +174 -0
  495. package/templates/develop/develop/partial-choice.ts +29 -0
  496. package/templates/develop/develop/partial.ts +28 -0
  497. package/templates/develop/develop/pull.ts +152 -0
  498. package/templates/develop/develop/queue-partial.ts +39 -0
  499. package/templates/develop/develop/refusal-tests.ts +174 -0
  500. package/templates/develop/develop/report.ts +156 -0
  501. package/templates/develop/develop/round.ts +40 -0
  502. package/templates/develop/develop/scenarios.ts +87 -0
  503. package/templates/develop/develop/turn.ts +67 -0
  504. package/templates/develop/develop.declaration.json +24 -0
  505. package/templates/develop/develop.test.ts +287 -0
  506. package/templates/develop/develop.ts +30 -0
  507. package/templates/develop/template.json +153 -0
  508. package/dist/src/chats/analysis-batches.d.ts +0 -24
  509. package/dist/src/chats/analysis-batches.js +0 -83
  510. package/dist/src/chats/analysis-contract.d.ts +0 -80
  511. package/dist/src/chats/analysis-contract.js +0 -16
  512. package/dist/src/chats/analysis-data.d.ts +0 -3
  513. package/dist/src/chats/analysis-data.js +0 -85
  514. package/dist/src/chats/analysis-input.d.ts +0 -12
  515. package/dist/src/chats/analysis-input.js +0 -83
  516. package/dist/src/chats/analysis-links.d.ts +0 -2
  517. package/dist/src/chats/analysis-links.js +0 -25
  518. package/dist/src/chats/analysis-prompt.d.ts +0 -10
  519. package/dist/src/chats/analysis-prompt.js +0 -16
  520. package/dist/src/chats/analysis-proposal.d.ts +0 -2
  521. package/dist/src/chats/analysis-proposal.js +0 -32
  522. package/dist/src/chats/analysis-provenance.d.ts +0 -4
  523. package/dist/src/chats/analysis-provenance.js +0 -99
  524. package/dist/src/chats/analysis-shape.d.ts +0 -3
  525. package/dist/src/chats/analysis-shape.js +0 -228
  526. package/dist/src/chats/analysis.d.ts +0 -3
  527. package/dist/src/chats/analysis.js +0 -42
  528. package/dist/src/chats/corpus-input.d.ts +0 -5
  529. package/dist/src/chats/corpus-input.js +0 -288
  530. package/dist/src/chats/destination.d.ts +0 -4
  531. package/dist/src/chats/destination.js +0 -96
  532. package/dist/src/chats/import.d.ts +0 -15
  533. package/dist/src/chats/import.js +0 -243
  534. package/dist/src/chats/input-file.d.ts +0 -3
  535. package/dist/src/chats/input-file.js +0 -32
  536. package/dist/src/chats/normalize.d.ts +0 -29
  537. package/dist/src/chats/normalize.js +0 -155
  538. package/dist/src/chats/previous-import.d.ts +0 -5
  539. package/dist/src/chats/previous-import.js +0 -34
  540. package/dist/src/chats/reader.d.ts +0 -21
  541. package/dist/src/chats/reader.js +0 -118
  542. package/dist/src/chats/redact-import.d.ts +0 -14
  543. package/dist/src/chats/redact-import.js +0 -141
  544. package/dist/src/chats/redaction.d.ts +0 -41
  545. package/dist/src/chats/redaction.js +0 -161
  546. package/dist/src/chats/revision-input.d.ts +0 -3
  547. package/dist/src/chats/revision-input.js +0 -180
  548. package/dist/src/chats/revision.d.ts +0 -48
  549. package/dist/src/chats/revision.js +0 -94
  550. package/dist/src/chats/selection.d.ts +0 -25
  551. package/dist/src/chats/selection.js +0 -109
  552. package/dist/src/chats/source.d.ts +0 -23
  553. package/dist/src/chats/source.js +0 -135
  554. package/dist/src/chats/structure.d.ts +0 -57
  555. package/dist/src/chats/structure.js +0 -216
  556. package/dist/src/daemon/analysis-launch.d.ts +0 -5
  557. package/dist/src/daemon/analysis-launch.js +0 -81
  558. package/dist/src/daemon/analysis-token.d.ts +0 -6
  559. package/dist/src/daemon/analysis-token.js +0 -88
  560. package/dist/src/daemon/analysis-worker.d.ts +0 -22
  561. package/dist/src/daemon/analysis-worker.js +0 -219
  562. package/dist/src/daemon/chats-files.d.ts +0 -15
  563. package/dist/src/daemon/chats-files.js +0 -113
  564. package/dist/src/daemon/chats-worker.d.ts +0 -12
  565. package/dist/src/daemon/chats-worker.js +0 -200
  566. package/dist/workflows/analyze-chats.d.ts +0 -10
  567. package/dist/workflows/analyze-chats.declaration.json +0 -9
  568. package/dist/workflows/analyze-chats.js +0 -73
@@ -1,11 +1,19 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { setTimeout as delay } from "node:timers/promises";
3
3
  import { getStepMetadata, getWorkflowMetadata } from "workflow";
4
- import { gateKey } from "../authority/gates.js";
4
+ import { openBridgeGate, waitForBridgeDecision, } from "./gate-bridge.js";
5
+ import { runWait } from "./run-wait.js";
6
+ import { reconciledDecision } from "./decision-resume.js";
7
+ import { taggedRuns } from "./world-runs.js";
5
8
  import { stepBridgeKey, } from "../step-bridge.js";
6
9
  export function sdkStepCall() {
7
- const { stepId, attempt } = getStepMetadata();
8
- return { worldRunId: getWorkflowMetadata().workflowRunId, stepId, attempt };
10
+ const { stepId, attempt, stepStartedAt } = getStepMetadata();
11
+ return {
12
+ worldRunId: getWorkflowMetadata().workflowRunId,
13
+ stepId,
14
+ attempt,
15
+ startedAt: stepStartedAt.getTime(),
16
+ };
9
17
  }
10
18
  export const bridgeTiming = {
11
19
  lookupTries: 250,
@@ -129,71 +137,65 @@ async function effect(hold, request) {
129
137
  return answer;
130
138
  return await settled(hold, answer.operationId);
131
139
  }
132
- function verdict(hold, receipt) {
133
- if (receipt === undefined || receipt.kind === "failed")
134
- return hold.timing.retryMilliseconds;
135
- if (committed.includes(receipt.kind))
136
- return "committed";
137
- if (receipt.reason === "service-busy")
138
- return hold.timing.retryMilliseconds;
139
- if (receipt.reason === "stale-revision")
140
- return hold.timing.pollMilliseconds;
141
- return { kind: "refused", reason: receipt.reason ?? receipt.kind };
142
- }
143
- async function gateCommand(hold, send) {
144
- for (;;) {
145
- await paused(hold, 0);
146
- const result = verdict(hold, await send().catch(() => undefined));
147
- if (result === "committed")
148
- return undefined;
149
- if (typeof result !== "number")
150
- return result;
151
- await paused(hold, result);
152
- }
153
- }
154
- async function opening(hold, subject) {
155
- const { runId, transport, request } = subject;
156
- const { gateId, kind, prompt } = request;
157
- const state = await hold.ports.state();
158
- const run = state.runs[runId];
159
- if (run === undefined)
160
- return { kind: "rejected", reason: "unknown-run" };
161
- if (Object.hasOwn(state.gates, gateKey(runId, gateId)))
162
- return { kind: "duplicate" };
163
- return await hold.ports.openGate({
164
- runId,
165
- commandId: `${transport}:open:${gateId}`,
166
- expectedRevision: run.revision,
167
- gateId,
168
- kind,
169
- prompt,
170
- subject: `sha256:${createHash("sha256").update(prompt).digest("hex")}`,
171
- });
172
- }
173
- async function gate(hold, request) {
140
+ async function gateSubject(hold, request) {
174
141
  const call = hold.ports.call();
175
142
  const world = await located(hold, call.worldRunId);
176
143
  if (world === undefined)
177
- return { kind: "unavailable", reason: "unknown-world-run" };
144
+ return undefined;
178
145
  await inWork(hold, world.runId);
179
- const subject = {
146
+ return {
147
+ request,
180
148
  runId: world.runId,
181
149
  transport: transportOf(call),
182
- request,
183
150
  };
184
- const refusal = (await gateCommand(hold, () => opening(hold, subject))) ??
185
- (await gateCommand(hold, () => hold.ports.registerWait({
186
- runId: subject.runId,
187
- commandId: `${subject.transport}:wait:${request.gateId}`,
188
- gateId: request.gateId,
189
- })));
190
- return refusal ?? { kind: "opened", decisionId: request.gateId };
151
+ }
152
+ async function gate(hold, request) {
153
+ const subject = await gateSubject(hold, request);
154
+ if (subject === undefined)
155
+ return { kind: "unavailable", reason: "unknown-world-run" };
156
+ return await openBridgeGate(hold.ports, subject);
191
157
  }
192
158
  export function stepBridge(ports) {
193
159
  const hold = { ports, timing: ports.timing ?? bridgeTiming };
194
160
  return {
195
161
  effect: (request) => effect(hold, request),
196
162
  gate: (request) => gate(hold, request),
163
+ waitForDecision: async (request) => {
164
+ const subject = await gateSubject(hold, request);
165
+ if (subject === undefined)
166
+ throw new Error("unknown-world-run");
167
+ return await waitForBridgeDecision({
168
+ ...ports,
169
+ decisionReceived: ports.decisionReceived ??
170
+ (async (runId, gateId) => (await reconciledDecision({ runs: taggedRuns, document: ports.document }, { runId, gateId })).kind === "accepted"),
171
+ }, subject);
172
+ },
173
+ waitForRun: async (request) => {
174
+ const call = ports.call();
175
+ const world = await located(hold, call.worldRunId);
176
+ if (world === undefined ||
177
+ ports.runWait === undefined ||
178
+ call.startedAt === undefined)
179
+ throw new Error("cloving-host-unavailable");
180
+ await inWork(hold, world.runId);
181
+ return await runWait(ports.runWait, {
182
+ caller: { ...world, stepId: call.stepId, startedAt: call.startedAt },
183
+ request,
184
+ });
185
+ },
186
+ handoff: (request) => effect(hold, {
187
+ scope: {
188
+ phase: "handoff",
189
+ operation: "handoff",
190
+ round: 1,
191
+ key: createHash("sha256").update(ports.call().stepId).digest("hex"),
192
+ },
193
+ capability: "handoff",
194
+ method: "run",
195
+ target: request.workflowId,
196
+ payload: JSON.stringify(request.input),
197
+ units: 1,
198
+ }),
197
199
  };
198
200
  }
199
201
  export function registerStepBridge(bridge) {
@@ -3,6 +3,7 @@ import type { AuthorityState } from "../authority/transitions.ts";
3
3
  export type ReconciledState = Pick<AuthorityState, "runs" | "intents" | "details" | "gates" | "commands">;
4
4
  export interface WorkflowOutcome {
5
5
  readonly kind: string;
6
+ readonly promotionId?: string;
6
7
  readonly reason?: string;
7
8
  readonly issueUpdate?: "failed";
8
9
  readonly ticketStatus?: "complete" | "partial";
@@ -14,6 +14,9 @@ async function withOutcome(ports, observed) {
14
14
  : {
15
15
  ...world,
16
16
  outcome: read.outcome.kind,
17
+ ...(read.outcome.promotionId === undefined
18
+ ? {}
19
+ : { promotionId: read.outcome.promotionId }),
17
20
  ...(read.outcome.issueUpdate === "failed"
18
21
  ? { issueUpdate: read.outcome.issueUpdate }
19
22
  : {}),
@@ -1,4 +1,5 @@
1
1
  import { isTicketStatus } from "../ticket-status.js";
2
+ import { isPromotionId } from "../workflow-contracts.js";
2
3
  import { getRun } from "workflow/api";
3
4
  import { getWorld } from "workflow/runtime";
4
5
  export const runTag = "cloving.run";
@@ -47,8 +48,12 @@ export async function workflowOutcome(receipt) {
47
48
  const reason = Reflect.get(Object(value), "reason");
48
49
  const issueUpdate = Reflect.get(Object(value), "issueUpdate");
49
50
  const ticketStatus = Reflect.get(Object(value), "ticketStatus");
51
+ const promotionId = Reflect.get(Object(value), "promotionId");
50
52
  return {
51
53
  kind,
54
+ ...(kind === "handoff_requested" && isPromotionId(promotionId)
55
+ ? { promotionId }
56
+ : {}),
52
57
  ...(typeof reason === "string" ? { reason } : {}),
53
58
  ...(issueUpdate === "failed" ? { issueUpdate } : {}),
54
59
  ...(isTicketStatus(ticketStatus) ? { ticketStatus } : {}),
@@ -0,0 +1,6 @@
1
+ export interface IssueIdentity {
2
+ readonly owner: string;
3
+ readonly repository: string;
4
+ readonly number: number;
5
+ }
6
+ export declare function issueIdentity(ticket: unknown): IssueIdentity | null;
@@ -0,0 +1,23 @@
1
+ export function issueIdentity(ticket) {
2
+ if (typeof ticket !== "string")
3
+ return null;
4
+ const markers = ticket
5
+ .split(/\r?\n/)
6
+ .filter((line) => line.startsWith("GitHub issue:"));
7
+ if (markers.length !== 1)
8
+ return null;
9
+ const match = /^GitHub issue: ([a-zA-Z0-9][a-zA-Z0-9-]*)\/([a-zA-Z0-9_.-]+)#([1-9][0-9]*)(?: \((?:open|closed)\))?\s*$/.exec(markers[0] ?? "");
10
+ const [, owner, repository, digits] = match ?? [];
11
+ const number = Number(digits);
12
+ if (owner === undefined ||
13
+ repository === undefined ||
14
+ [".", ".."].includes(repository) ||
15
+ !Number.isSafeInteger(number) ||
16
+ number <= 0)
17
+ return null;
18
+ return {
19
+ owner: owner.toLowerCase(),
20
+ repository: repository.toLowerCase(),
21
+ number,
22
+ };
23
+ }
@@ -0,0 +1,19 @@
1
+ export interface PullRequest {
2
+ readonly number: number;
3
+ readonly url: string;
4
+ readonly commit: string;
5
+ readonly target: string;
6
+ }
7
+ export type MergeCheckName = "beforeMerge";
8
+ export interface MergeRequest {
9
+ readonly pull: PullRequest;
10
+ readonly check: MergeCheckName | null;
11
+ readonly round?: number;
12
+ }
13
+ export type MergeReason = "check-failed" | "merge-conflict" | "ci-failed" | "ci-pending" | "check-not-configured" | "not-approved";
14
+ export interface MergeResult {
15
+ readonly merged: boolean;
16
+ readonly reason: MergeReason | null;
17
+ readonly output: string;
18
+ }
19
+ export declare function mergeRequest(value: unknown): Required<MergeRequest>;
@@ -0,0 +1,32 @@
1
+ import { record } from "./protocol.js";
2
+ import { commitId } from "./review-subject.js";
3
+ export function mergeRequest(value) {
4
+ const request = record(value);
5
+ const pull = pullRequest(request?.["pull"]);
6
+ const check = request?.["check"];
7
+ if (request === undefined ||
8
+ pull === undefined ||
9
+ !Object.hasOwn(request, "check") ||
10
+ (check !== null && check !== "beforeMerge"))
11
+ throw new Error("invalid-merge-request");
12
+ return { pull, check, round: mergeRound(request["round"] ?? 1) };
13
+ }
14
+ function mergeRound(value) {
15
+ if (!positiveInteger(value))
16
+ throw new Error("invalid-merge-request");
17
+ return value;
18
+ }
19
+ function pullRequest(value) {
20
+ const pull = record(value);
21
+ const { number, url, commit, target } = pull ?? {};
22
+ if (!positiveInteger(number) ||
23
+ typeof url !== "string" ||
24
+ !commitId(commit) ||
25
+ typeof target !== "string" ||
26
+ target.trim() === "")
27
+ return undefined;
28
+ return { number, url, commit, target };
29
+ }
30
+ function positiveInteger(value) {
31
+ return typeof value === "number" && Number.isSafeInteger(value) && value > 0;
32
+ }
@@ -0,0 +1 @@
1
+ export declare function canonicalJson(value: unknown): string;
@@ -0,0 +1,16 @@
1
+ export function canonicalJson(value) {
2
+ if (value === null || typeof value === "boolean" || typeof value === "string")
3
+ return JSON.stringify(value);
4
+ if (typeof value === "number" && !Number.isSafeInteger(value))
5
+ throw new Error("canonical-json-number: Only safe integers are allowed.");
6
+ if (typeof value === "number")
7
+ return String(value);
8
+ if (Array.isArray(value))
9
+ return `[${value.map(canonicalJson).join(",")}]`;
10
+ if (typeof value !== "object")
11
+ throw new Error("canonical-json-value: The value is not JSON.");
12
+ const fields = Object.keys(value)
13
+ .sort()
14
+ .map((key) => `${JSON.stringify(key)}:${canonicalJson(Reflect.get(value, key))}`);
15
+ return `{${fields.join(",")}}`;
16
+ }
@@ -0,0 +1,7 @@
1
+ export interface PhoneLink {
2
+ readonly daemonId: string;
3
+ readonly origin: string;
4
+ readonly token: string;
5
+ readonly registeredAt: string;
6
+ }
7
+ export declare function parsePhoneLink(text: string | undefined): PhoneLink | undefined;
@@ -0,0 +1,21 @@
1
+ export function parsePhoneLink(text) {
2
+ if (text === undefined)
3
+ return undefined;
4
+ const value = JSON.parse(text);
5
+ if (typeof value !== "object" || value === null)
6
+ return undefined;
7
+ const filled = (name) => {
8
+ const field = Reflect.get(value, name);
9
+ return typeof field === "string" && field !== "" ? field : undefined;
10
+ };
11
+ const daemonId = filled("daemonId");
12
+ const origin = filled("origin");
13
+ const token = filled("token");
14
+ const registeredAt = filled("registeredAt");
15
+ if (daemonId === undefined ||
16
+ origin === undefined ||
17
+ token === undefined ||
18
+ registeredAt === undefined)
19
+ return undefined;
20
+ return { daemonId, origin, token, registeredAt };
21
+ }
@@ -0,0 +1,8 @@
1
+ export declare function qrVersion(byteCount: number): number;
2
+ export declare function qrDataCodewords(bytes: Uint8Array, version: number): number[];
3
+ export declare function qrCorrection(data: readonly number[], degree: number): number[];
4
+ export interface QrCodewords {
5
+ readonly version: number;
6
+ readonly codewords: readonly number[];
7
+ }
8
+ export declare function qrCodewords(text: string): QrCodewords;
@@ -0,0 +1,133 @@
1
+ const layouts = [
2
+ { correctionCodewords: 10, groups: [{ count: 1, dataCodewords: 16 }] },
3
+ { correctionCodewords: 16, groups: [{ count: 1, dataCodewords: 28 }] },
4
+ { correctionCodewords: 26, groups: [{ count: 1, dataCodewords: 44 }] },
5
+ { correctionCodewords: 18, groups: [{ count: 2, dataCodewords: 32 }] },
6
+ { correctionCodewords: 24, groups: [{ count: 2, dataCodewords: 43 }] },
7
+ { correctionCodewords: 16, groups: [{ count: 4, dataCodewords: 27 }] },
8
+ { correctionCodewords: 18, groups: [{ count: 4, dataCodewords: 31 }] },
9
+ {
10
+ correctionCodewords: 22,
11
+ groups: [
12
+ { count: 2, dataCodewords: 38 },
13
+ { count: 2, dataCodewords: 39 },
14
+ ],
15
+ },
16
+ {
17
+ correctionCodewords: 22,
18
+ groups: [
19
+ { count: 3, dataCodewords: 36 },
20
+ { count: 2, dataCodewords: 37 },
21
+ ],
22
+ },
23
+ {
24
+ correctionCodewords: 26,
25
+ groups: [
26
+ { count: 4, dataCodewords: 43 },
27
+ { count: 1, dataCodewords: 44 },
28
+ ],
29
+ },
30
+ ];
31
+ function multiply(left, right) {
32
+ let product = 0;
33
+ for (let bit = 7; bit >= 0; bit -= 1) {
34
+ product = (product << 1) ^ ((product >>> 7) * 0x11d);
35
+ product ^= ((right >>> bit) & 1) * left;
36
+ }
37
+ return product;
38
+ }
39
+ function layoutOf(version) {
40
+ const layout = layouts[version - 1];
41
+ if (layout === undefined)
42
+ throw new Error("qr-version-unsupported");
43
+ return layout;
44
+ }
45
+ function dataCapacity(version) {
46
+ return layoutOf(version).groups.reduce((total, group) => total + group.count * group.dataCodewords, 0);
47
+ }
48
+ function countBits(version) {
49
+ return version < 10 ? 8 : 16;
50
+ }
51
+ export function qrVersion(byteCount) {
52
+ const version = layouts.findIndex((_, index) => 4 + countBits(index + 1) + 8 * byteCount <= 8 * dataCapacity(index + 1));
53
+ if (version < 0)
54
+ throw new Error("qr-text-too-long");
55
+ return version + 1;
56
+ }
57
+ function bitStream(bytes, version) {
58
+ const bits = [];
59
+ const append = (value, length) => {
60
+ for (let shift = length - 1; shift >= 0; shift -= 1)
61
+ bits.push((value >>> shift) & 1);
62
+ };
63
+ append(0b0100, 4);
64
+ append(bytes.length, countBits(version));
65
+ for (const byte of bytes)
66
+ append(byte, 8);
67
+ append(0, Math.min(4, 8 * dataCapacity(version) - bits.length));
68
+ append(0, (8 - (bits.length % 8)) % 8);
69
+ return bits;
70
+ }
71
+ export function qrDataCodewords(bytes, version) {
72
+ const bits = bitStream(bytes, version);
73
+ const codewords = [];
74
+ for (let start = 0; start < bits.length; start += 8)
75
+ codewords.push(bits.slice(start, start + 8).reduce((byte, bit) => (byte << 1) | bit, 0));
76
+ for (let index = 0; codewords.length < dataCapacity(version); index += 1)
77
+ codewords.push(index % 2 === 0 ? 0xec : 0x11);
78
+ return codewords;
79
+ }
80
+ function divisor(degree) {
81
+ let coefficients = [...Array.from({ length: degree - 1 }, () => 0), 1];
82
+ let root = 1;
83
+ for (let step = 0; step < degree; step += 1) {
84
+ const previous = coefficients;
85
+ coefficients = previous.map((value, index) => multiply(value, root) ^ (previous[index + 1] ?? 0));
86
+ root = multiply(root, 0x02);
87
+ }
88
+ return coefficients;
89
+ }
90
+ export function qrCorrection(data, degree) {
91
+ const coefficients = divisor(degree);
92
+ let remainder = Array.from({ length: degree }, () => 0);
93
+ for (const codeword of data) {
94
+ const [first, ...rest] = remainder;
95
+ const factor = codeword ^ Number(first);
96
+ remainder = [...rest, 0].map((value, index) => value ^ multiply(Number(coefficients[index]), factor));
97
+ }
98
+ return remainder;
99
+ }
100
+ function blocks(data, version) {
101
+ const result = [];
102
+ let start = 0;
103
+ for (const group of layoutOf(version).groups)
104
+ for (let block = 0; block < group.count; block += 1) {
105
+ result.push(data.slice(start, start + group.dataCodewords));
106
+ start += group.dataCodewords;
107
+ }
108
+ return result;
109
+ }
110
+ function interleaved(columns) {
111
+ const longest = Math.max(...columns.map((column) => column.length));
112
+ const result = [];
113
+ for (let index = 0; index < longest; index += 1)
114
+ for (const column of columns) {
115
+ const value = column[index];
116
+ if (value !== undefined)
117
+ result.push(value);
118
+ }
119
+ return result;
120
+ }
121
+ export function qrCodewords(text) {
122
+ const bytes = new TextEncoder().encode(text);
123
+ const version = qrVersion(bytes.length);
124
+ const dataBlocks = blocks(qrDataCodewords(bytes, version), version);
125
+ const degree = layoutOf(version).correctionCodewords;
126
+ return {
127
+ version,
128
+ codewords: [
129
+ ...interleaved(dataBlocks),
130
+ ...interleaved(dataBlocks.map((block) => qrCorrection(block, degree))),
131
+ ],
132
+ };
133
+ }
@@ -0,0 +1,6 @@
1
+ export interface QrSymbol {
2
+ readonly version: number;
3
+ readonly mask: number;
4
+ readonly modules: readonly (readonly boolean[])[];
5
+ }
6
+ export declare function qrMatrix(text: string): QrSymbol;
@@ -0,0 +1,175 @@
1
+ import { qrCodewords } from "./qr-data.js";
2
+ import { qrPenalty } from "./qr-penalty.js";
3
+ const alignmentCenters = [
4
+ [],
5
+ [6, 18],
6
+ [6, 22],
7
+ [6, 26],
8
+ [6, 30],
9
+ [6, 34],
10
+ [6, 22, 38],
11
+ [6, 24, 42],
12
+ [6, 26, 46],
13
+ [6, 28, 50],
14
+ ];
15
+ const masks = [
16
+ (row, column) => (row + column) % 2 === 0,
17
+ (row) => row % 2 === 0,
18
+ (_, column) => column % 3 === 0,
19
+ (row, column) => (row + column) % 3 === 0,
20
+ (row, column) => (Math.floor(row / 2) + Math.floor(column / 3)) % 2 === 0,
21
+ (row, column) => ((row * column) % 2) + ((row * column) % 3) === 0,
22
+ (row, column) => (((row * column) % 2) + ((row * column) % 3)) % 2 === 0,
23
+ (row, column) => (((row + column) % 2) + ((row * column) % 3)) % 2 === 0,
24
+ ];
25
+ function grid(size) {
26
+ return Array.from({ length: size }, () => Array.from({ length: size }, () => false));
27
+ }
28
+ function mark(canvas, place) {
29
+ const [row, column, dark] = place;
30
+ const modules = canvas.modules[row];
31
+ const reserved = canvas.reserved[row];
32
+ if (modules === undefined || reserved === undefined)
33
+ return;
34
+ if (column < 0 || column >= canvas.size)
35
+ return;
36
+ modules[column] = dark;
37
+ reserved[column] = true;
38
+ }
39
+ function finder(canvas, corner) {
40
+ const [top, left] = corner;
41
+ for (let row = -1; row <= 7; row += 1)
42
+ for (let column = -1; column <= 7; column += 1) {
43
+ const distance = Math.max(Math.abs(row - 3), Math.abs(column - 3));
44
+ mark(canvas, [top + row, left + column, distance !== 2 && distance < 4]);
45
+ }
46
+ }
47
+ function alignment(canvas, center) {
48
+ const [top, left] = center;
49
+ for (let row = -2; row <= 2; row += 1)
50
+ for (let column = -2; column <= 2; column += 1)
51
+ mark(canvas, [
52
+ top + row,
53
+ left + column,
54
+ Math.max(Math.abs(row), Math.abs(column)) !== 1,
55
+ ]);
56
+ }
57
+ function functionPatterns(canvas, version) {
58
+ const last = canvas.size - 7;
59
+ for (let index = 8; index < canvas.size - 8; index += 1) {
60
+ mark(canvas, [6, index, index % 2 === 0]);
61
+ mark(canvas, [index, 6, index % 2 === 0]);
62
+ }
63
+ finder(canvas, [0, 0]);
64
+ finder(canvas, [0, last]);
65
+ finder(canvas, [last, 0]);
66
+ const centers = alignmentCenters[version - 1] ?? [];
67
+ const final = centers.length - 1;
68
+ centers.forEach((row, rowIndex) => {
69
+ centers.forEach((column, columnIndex) => {
70
+ const corner = (rowIndex === 0 && (columnIndex === 0 || columnIndex === final)) ||
71
+ (rowIndex === final && columnIndex === 0);
72
+ if (!corner)
73
+ alignment(canvas, [row, column]);
74
+ });
75
+ });
76
+ }
77
+ function formatPlaces(size) {
78
+ const first = [
79
+ ...[0, 1, 2, 3, 4, 5, 7, 8].map((row) => [row, 8]),
80
+ ...[7, 5, 4, 3, 2, 1, 0].map((column) => [8, column]),
81
+ ];
82
+ const second = [
83
+ ...[0, 1, 2, 3, 4, 5, 6, 7].map((index) => [
84
+ 8,
85
+ size - 1 - index,
86
+ ]),
87
+ ...[6, 5, 4, 3, 2, 1, 0].map((index) => [
88
+ size - 1 - index,
89
+ 8,
90
+ ]),
91
+ ];
92
+ return [...first, ...second];
93
+ }
94
+ function formatBits(mask) {
95
+ let remainder = mask;
96
+ for (let step = 0; step < 10; step += 1)
97
+ remainder = (remainder << 1) ^ ((remainder >>> 9) * 0x537);
98
+ return ((mask << 10) | remainder) ^ 0x5412;
99
+ }
100
+ function versionBits(version) {
101
+ let remainder = version;
102
+ for (let step = 0; step < 12; step += 1)
103
+ remainder = (remainder << 1) ^ ((remainder >>> 11) * 0x1f25);
104
+ return (version << 12) | remainder;
105
+ }
106
+ function formatInformation(canvas, mask) {
107
+ const format = formatBits(mask);
108
+ formatPlaces(canvas.size).forEach(([row, column], index) => {
109
+ mark(canvas, [row, column, ((format >>> (index % 15)) & 1) === 1]);
110
+ });
111
+ mark(canvas, [canvas.size - 8, 8, true]);
112
+ }
113
+ function versionInformation(canvas, version) {
114
+ if (version < 7)
115
+ return;
116
+ const bits = versionBits(version);
117
+ for (let index = 0; index < 18; index += 1) {
118
+ const near = Math.floor(index / 3);
119
+ const far = canvas.size - 11 + (index % 3);
120
+ const dark = ((bits >>> index) & 1) === 1;
121
+ mark(canvas, [near, far, dark]);
122
+ mark(canvas, [far, near, dark]);
123
+ }
124
+ }
125
+ function columnPairs(size) {
126
+ const columns = [];
127
+ for (let right = size - 1; right >= 1; right -= 2) {
128
+ if (right === 6)
129
+ right = 5;
130
+ columns.push(right);
131
+ }
132
+ return columns;
133
+ }
134
+ function dataPlaces(canvas) {
135
+ return columnPairs(canvas.size).flatMap((right) => {
136
+ const upward = ((right + 1) & 2) === 0;
137
+ return Array.from({ length: canvas.size }, (_, step) => upward ? canvas.size - 1 - step : step)
138
+ .flatMap((row) => [right, right - 1].map((column) => [row, column]))
139
+ .filter(([row, column]) => canvas.reserved[row]?.[column] !== true);
140
+ });
141
+ }
142
+ function placeData(canvas, codewords) {
143
+ dataPlaces(canvas).forEach(([row, column], index) => {
144
+ const codeword = codewords[Math.floor(index / 8)] ?? 0;
145
+ const modules = canvas.modules[row];
146
+ if (modules !== undefined)
147
+ modules[column] = ((codeword >>> (7 - (index % 8))) & 1) === 1;
148
+ });
149
+ }
150
+ function masked(canvas, mask) {
151
+ const condition = masks[mask] ?? (() => false);
152
+ return canvas.modules.map((row, rowIndex) => Array.from({ length: row.length }, (_, column) => {
153
+ const dark = row[column] === true;
154
+ return canvas.reserved[rowIndex]?.[column] === true
155
+ ? dark
156
+ : dark !== condition(rowIndex, column);
157
+ }));
158
+ }
159
+ function maskedCanvas(canvas, mask) {
160
+ const candidate = { ...canvas, modules: masked(canvas, mask) };
161
+ formatInformation(candidate, mask);
162
+ return candidate;
163
+ }
164
+ export function qrMatrix(text) {
165
+ const { version, codewords } = qrCodewords(text);
166
+ const size = 17 + 4 * version;
167
+ const canvas = { size, modules: grid(size), reserved: grid(size) };
168
+ functionPatterns(canvas, version);
169
+ formatInformation(canvas, 0);
170
+ versionInformation(canvas, version);
171
+ placeData(canvas, codewords);
172
+ const penalties = masks.map((_, mask) => qrPenalty(maskedCanvas(canvas, mask).modules));
173
+ const mask = penalties.indexOf(Math.min(...penalties));
174
+ return { version, mask, modules: maskedCanvas(canvas, mask).modules };
175
+ }
@@ -0,0 +1,3 @@
1
+ type Line = readonly boolean[];
2
+ export declare function qrPenalty(modules: readonly Line[]): number;
3
+ export {};