@astrosheep/keiyaku 4.6.7 → 4.6.9

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 (336) hide show
  1. package/README.md +46 -16
  2. package/build/plugins/claude/.claude-plugin/plugin.json +1 -1
  3. package/build/plugins/claude/skills/keiyaku/SKILL.md +5 -6
  4. package/build/plugins/claude/skills/keiyaku-akuma/SKILL.md +1 -1
  5. package/build/plugins/claude/skills/keiyaku-akuma/references/automation.md +8 -8
  6. package/build/plugins/claude/skills/keiyaku-babysit/SKILL.md +1 -1
  7. package/build/plugins/claude/skills/keiyaku-bind/SKILL.md +9 -9
  8. package/build/plugins/claude/skills/keiyaku-debt/SKILL.md +91 -0
  9. package/build/plugins/claude/skills/keiyaku-workflow/SKILL.md +2 -2
  10. package/build/plugins/codex/.codex-plugin/plugin.json +1 -1
  11. package/build/plugins/codex/skills/keiyaku/SKILL.md +5 -6
  12. package/build/plugins/codex/skills/keiyaku-akuma/SKILL.md +1 -1
  13. package/build/plugins/codex/skills/keiyaku-akuma/references/automation.md +8 -8
  14. package/build/plugins/codex/skills/keiyaku-babysit/SKILL.md +1 -1
  15. package/build/plugins/codex/skills/keiyaku-bind/SKILL.md +9 -9
  16. package/build/plugins/codex/skills/keiyaku-debt/SKILL.md +91 -0
  17. package/build/plugins/codex/skills/keiyaku-workflow/SKILL.md +2 -2
  18. package/build/plugins/opencode/index.js +1 -1
  19. package/build/plugins/opencode/skills/keiyaku/SKILL.md +5 -6
  20. package/build/plugins/opencode/skills/keiyaku-akuma/SKILL.md +1 -1
  21. package/build/plugins/opencode/skills/keiyaku-akuma/references/automation.md +8 -8
  22. package/build/plugins/opencode/skills/keiyaku-babysit/SKILL.md +1 -1
  23. package/build/plugins/opencode/skills/keiyaku-bind/SKILL.md +9 -9
  24. package/build/plugins/opencode/skills/keiyaku-debt/SKILL.md +91 -0
  25. package/build/plugins/opencode/skills/keiyaku-workflow/SKILL.md +2 -2
  26. package/build/plugins/pi/keiyaku.ts +0 -5
  27. package/build/skills/keiyaku/SKILL.md +5 -6
  28. package/build/skills/keiyaku-akuma/SKILL.md +1 -1
  29. package/build/skills/keiyaku-akuma/references/automation.md +8 -8
  30. package/build/skills/keiyaku-babysit/SKILL.md +1 -1
  31. package/build/skills/keiyaku-bind/SKILL.md +9 -9
  32. package/build/skills/keiyaku-debt/SKILL.md +91 -0
  33. package/build/skills/keiyaku-workflow/SKILL.md +2 -2
  34. package/build/src/akuma/akuma-call.d.ts +2 -0
  35. package/build/src/akuma/akuma-call.js +8 -2
  36. package/build/src/akuma/akuma-instance.d.ts +14 -1
  37. package/build/src/akuma/akuma-instance.js +37 -7
  38. package/build/src/akuma/akuma-observe.d.ts +33 -8
  39. package/build/src/akuma/akuma-observe.js +89 -63
  40. package/build/src/akuma/akuma-owner.d.ts +14 -2
  41. package/build/src/akuma/akuma-owner.js +49 -35
  42. package/build/src/akuma/akuma-selection-execution.js +9 -1
  43. package/build/src/akuma/akuma-stream.d.ts +22 -0
  44. package/build/src/akuma/akuma-stream.js +116 -0
  45. package/build/src/akuma/akuma-wait.d.ts +1 -40
  46. package/build/src/akuma/akuma-wait.js +23 -84
  47. package/build/src/akuma/akuma.d.ts +52 -16
  48. package/build/src/akuma/akuma.js +10 -10
  49. package/build/src/akuma/allowed.d.ts +7 -12
  50. package/build/src/akuma/allowed.js +13 -4
  51. package/build/src/akuma/archetype.d.ts +7 -15
  52. package/build/src/akuma/archetype.js +36 -35
  53. package/build/src/akuma/body-supervisor.d.ts +5 -5
  54. package/build/src/akuma/body-supervisor.js +22 -20
  55. package/build/src/akuma/body.d.ts +5 -3
  56. package/build/src/akuma/body.js +57 -8
  57. package/build/src/akuma/call-request.d.ts +30 -32
  58. package/build/src/akuma/call-request.js +10 -3
  59. package/build/src/akuma/caller.d.ts +39 -0
  60. package/build/src/akuma/caller.js +36 -0
  61. package/build/src/akuma/dispatch-association.d.ts +0 -1
  62. package/build/src/akuma/dispatch-association.js +0 -3
  63. package/build/src/akuma/heart/activity-schema.d.ts +12 -0
  64. package/build/src/akuma/heart/activity-schema.js +6 -0
  65. package/build/src/akuma/heart/facts.d.ts +16 -12
  66. package/build/src/akuma/heart/facts.js +8 -0
  67. package/build/src/akuma/heart/index.d.ts +61 -9
  68. package/build/src/akuma/heart/index.js +89 -24
  69. package/build/src/akuma/heart/rows.d.ts +3 -3
  70. package/build/src/akuma/heart/rows.js +5 -3
  71. package/build/src/akuma/heart/soul.d.ts +10 -1
  72. package/build/src/akuma/heart/soul.js +34 -24
  73. package/build/src/akuma/heart/storage.d.ts +20 -0
  74. package/build/src/akuma/heart/storage.js +62 -3
  75. package/build/src/akuma/heart/timeline.d.ts +7 -0
  76. package/build/src/akuma/heart/timeline.js +10 -0
  77. package/build/src/akuma/identity.d.ts +0 -1
  78. package/build/src/akuma/identity.js +2 -5
  79. package/build/src/akuma/index.d.ts +6 -2
  80. package/build/src/akuma/index.js +1 -0
  81. package/build/src/akuma/nuke.js +6 -28
  82. package/build/src/akuma/projection.d.ts +25 -11
  83. package/build/src/akuma/projection.js +24 -7
  84. package/build/src/akuma/provider-recipe.d.ts +18 -6
  85. package/build/src/akuma/provider-recipe.js +24 -1
  86. package/build/src/akuma/provider.d.ts +31 -10
  87. package/build/src/akuma/provider.js +105 -14
  88. package/build/src/akuma/providers/acp/events.js +29 -19
  89. package/build/src/akuma/providers/acp/index.js +2 -3
  90. package/build/src/akuma/providers/claude/events.js +110 -69
  91. package/build/src/akuma/providers/claude/index.d.ts +2 -2
  92. package/build/src/akuma/providers/claude/index.js +4 -8
  93. package/build/src/akuma/providers/codex-app-server/events.js +17 -2
  94. package/build/src/akuma/providers/codex-app-server/index.js +17 -11
  95. package/build/src/akuma/providers/decode.d.ts +33 -0
  96. package/build/src/akuma/providers/decode.js +65 -0
  97. package/build/src/akuma/providers/execution-environment.d.ts +2 -1
  98. package/build/src/akuma/providers/execution-environment.js +3 -0
  99. package/build/src/akuma/providers/grok-build/index.js +16 -48
  100. package/build/src/akuma/providers/index.js +2 -0
  101. package/build/src/akuma/providers/lifecycle.d.ts +9 -0
  102. package/build/src/akuma/providers/lifecycle.js +10 -0
  103. package/build/src/akuma/providers/opencode-sdk/event-stream.d.ts +3 -3
  104. package/build/src/akuma/providers/opencode-sdk/event-stream.js +2 -25
  105. package/build/src/akuma/providers/opencode-sdk/events.d.ts +7 -43
  106. package/build/src/akuma/providers/opencode-sdk/events.js +146 -296
  107. package/build/src/akuma/providers/opencode-sdk/index.js +270 -431
  108. package/build/src/akuma/providers/opencode-sdk/native-http.d.ts +9 -0
  109. package/build/src/akuma/providers/opencode-sdk/native-http.js +69 -0
  110. package/build/src/akuma/providers/opencode-sdk/session.d.ts +42 -36
  111. package/build/src/akuma/providers/opencode-sdk/session.js +75 -84
  112. package/build/src/akuma/providers/paseo/events.d.ts +33 -0
  113. package/build/src/akuma/providers/paseo/events.js +204 -0
  114. package/build/src/akuma/providers/paseo/index.d.ts +9 -0
  115. package/build/src/akuma/providers/paseo/index.js +357 -0
  116. package/build/src/akuma/providers/pi/events.d.ts +2 -0
  117. package/build/src/akuma/providers/pi/events.js +36 -38
  118. package/build/src/akuma/providers/pi/index.js +21 -35
  119. package/build/src/akuma/publication.d.ts +2 -0
  120. package/build/src/akuma/publication.js +5 -0
  121. package/build/src/akuma/request-lifecycle.d.ts +4 -2
  122. package/build/src/akuma/request-lifecycle.js +27 -12
  123. package/build/src/akuma/request-rendezvous.js +38 -55
  124. package/build/src/akuma/request-serve.d.ts +1 -1
  125. package/build/src/akuma/request-serve.js +77 -113
  126. package/build/src/akuma/requests.d.ts +3 -1
  127. package/build/src/akuma/requests.js +32 -0
  128. package/build/src/akuma/selection-observation.d.ts +129 -53
  129. package/build/src/akuma/selection-observation.js +3 -9
  130. package/build/src/akuma/turn-drive.d.ts +3 -0
  131. package/build/src/akuma/turn-drive.js +28 -10
  132. package/build/src/akuma-body.js +12 -22
  133. package/build/src/cli/akuma-caller.d.ts +3 -0
  134. package/build/src/cli/akuma-caller.js +31 -0
  135. package/build/src/cli/commands/akuma-grammar.js +10 -16
  136. package/build/src/cli/commands/akuma.js +25 -55
  137. package/build/src/cli/commands/contract-grammar.d.ts +9 -7
  138. package/build/src/cli/commands/contract-grammar.js +40 -47
  139. package/build/src/cli/commands/contract-help.d.ts +17 -7
  140. package/build/src/cli/commands/contract-help.js +50 -11
  141. package/build/src/cli/commands/contract.js +34 -63
  142. package/build/src/cli/commands/debt-grammar.d.ts +19 -0
  143. package/build/src/cli/commands/debt-grammar.js +323 -0
  144. package/build/src/cli/commands/debt-query.d.ts +5 -0
  145. package/build/src/cli/commands/{task-query.js → debt-query.js} +9 -9
  146. package/build/src/cli/commands/{task.d.ts → debt.d.ts} +2 -2
  147. package/build/src/cli/commands/{task.js → debt.js} +87 -164
  148. package/build/src/cli/coordinates.d.ts +1 -1
  149. package/build/src/cli/coordinates.js +1 -1
  150. package/build/src/cli/parse.d.ts +5 -5
  151. package/build/src/cli/parse.js +17 -16
  152. package/build/src/cli/render/akuma-activity.d.ts +11 -83
  153. package/build/src/cli/render/akuma-activity.js +20 -382
  154. package/build/src/cli/render/catalog.d.ts +4 -7
  155. package/build/src/cli/render/catalog.js +5 -5
  156. package/build/src/cli/render/contract-history.js +3 -6
  157. package/build/src/cli/render/contract.js +17 -52
  158. package/build/src/cli/render/debt.d.ts +28 -0
  159. package/build/src/cli/render/{task.js → debt.js} +55 -133
  160. package/build/src/cli/render/kanshi.js +28 -28
  161. package/build/src/cli/render/marks.d.ts +5 -5
  162. package/build/src/cli/render/marks.js +4 -10
  163. package/build/src/cli/render/nuke.js +1 -1
  164. package/build/src/cli/render/receipt.js +3 -10
  165. package/build/src/cli/runtime.d.ts +1 -1
  166. package/build/src/cli/runtime.js +14 -20
  167. package/build/src/cli/scan.d.ts +1 -1
  168. package/build/src/cli/selectors.d.ts +3 -6
  169. package/build/src/cli/selectors.js +22 -53
  170. package/build/src/cli/usage.d.ts +1 -1
  171. package/build/src/cli/usage.js +4 -4
  172. package/build/src/contract-worktree.js +3 -3
  173. package/build/src/debt/board.d.ts +160 -0
  174. package/build/src/{task → debt}/board.js +89 -89
  175. package/build/src/debt/catalog.d.ts +11 -0
  176. package/build/src/debt/catalog.js +59 -0
  177. package/build/src/{task → debt}/context.d.ts +1 -1
  178. package/build/src/{task → debt}/context.js +1 -1
  179. package/build/src/{task → debt}/created-observation.d.ts +6 -10
  180. package/build/src/{task → debt}/created-observation.js +7 -7
  181. package/build/src/debt/document.d.ts +37 -0
  182. package/build/src/{task → debt}/document.js +37 -37
  183. package/build/src/debt/identity.d.ts +21 -0
  184. package/build/src/{task → debt}/identity.js +35 -35
  185. package/build/src/debt/index.d.ts +111 -0
  186. package/build/src/debt/index.js +203 -0
  187. package/build/src/{task → debt}/input.d.ts +8 -8
  188. package/build/src/{task → debt}/input.js +21 -21
  189. package/build/src/debt/lifecycle-operations.d.ts +6 -0
  190. package/build/src/{task → debt}/lifecycle-operations.js +27 -31
  191. package/build/src/debt/mutation-result.d.ts +981 -0
  192. package/build/src/debt/mutation-result.js +109 -0
  193. package/build/src/debt/mutation.d.ts +424 -0
  194. package/build/src/debt/mutation.js +223 -0
  195. package/build/src/debt/operation-types.d.ts +71 -0
  196. package/build/src/debt/operations.d.ts +28 -0
  197. package/build/src/{task → debt}/operations.js +59 -60
  198. package/build/src/debt/query.d.ts +76 -0
  199. package/build/src/{task → debt}/query.js +55 -55
  200. package/build/src/{task → debt}/store.d.ts +13 -13
  201. package/build/src/{task → debt}/store.js +58 -49
  202. package/build/src/debt/view.d.ts +4 -0
  203. package/build/src/debt/view.js +7 -0
  204. package/build/src/dispatch/index.d.ts +3 -3
  205. package/build/src/dispatch/index.js +1 -2
  206. package/build/src/git/observe.d.ts +6 -2
  207. package/build/src/git/observe.js +6 -2
  208. package/build/src/identity/coordinates.d.ts +1 -1
  209. package/build/src/index.d.ts +17 -17
  210. package/build/src/index.js +11 -11
  211. package/build/src/kanshi/index.d.ts +2 -2
  212. package/build/src/kanshi/read.js +54 -39
  213. package/build/src/kanshi/report.d.ts +7 -7
  214. package/build/src/kanshi/select.js +4 -4
  215. package/build/src/library/address.js +2 -4
  216. package/build/src/library/akuma-creation.d.ts +5 -1
  217. package/build/src/library/akuma-creation.js +27 -47
  218. package/build/src/library/akumas.d.ts +7 -7
  219. package/build/src/library/akumas.js +13 -9
  220. package/build/src/library/bind.d.ts +17 -17
  221. package/build/src/library/bind.js +16 -12
  222. package/build/src/library/contract-address.d.ts +9 -0
  223. package/build/src/library/contract-address.js +71 -0
  224. package/build/src/library/contract-composition.d.ts +4 -7
  225. package/build/src/library/contract-composition.js +6 -18
  226. package/build/src/library/contract-creation.d.ts +3 -5
  227. package/build/src/library/contract-creation.js +24 -22
  228. package/build/src/library/contract-execution.js +21 -26
  229. package/build/src/library/contract-outcomes.d.ts +2 -14
  230. package/build/src/library/contract-outcomes.js +2 -13
  231. package/build/src/library/contract-types.d.ts +38 -4
  232. package/build/src/library/delivery.d.ts +0 -2
  233. package/build/src/library/delivery.js +2 -5
  234. package/build/src/library/input.d.ts +2 -2
  235. package/build/src/library/input.js +5 -5
  236. package/build/src/library/invocation.js +2 -2
  237. package/build/src/library/keiyaku.d.ts +0 -5
  238. package/build/src/library/keiyaku.js +6 -12
  239. package/build/src/library/nuke.js +3 -3
  240. package/build/src/library/outcome.d.ts +626 -625
  241. package/build/src/library/outcome.js +13 -3
  242. package/build/src/library/reconcile.js +8 -16
  243. package/build/src/library/refusal.d.ts +2 -2
  244. package/build/src/library/repo.d.ts +3 -2
  245. package/build/src/library/repo.js +10 -5
  246. package/build/src/library/selection.d.ts +5 -8
  247. package/build/src/library/selection.js +22 -73
  248. package/build/src/plugin/akuma-signals.d.ts +2 -0
  249. package/build/src/plugin/akuma-signals.js +4 -0
  250. package/build/src/plugin/public.d.ts +32 -2
  251. package/build/src/plugin/runtime.js +5 -3
  252. package/build/src/protocol/amend.js +3 -2
  253. package/build/src/protocol/attempt.js +3 -8
  254. package/build/src/protocol/bind.d.ts +2 -2
  255. package/build/src/protocol/bind.js +1 -1
  256. package/build/src/protocol/deliver.js +3 -3
  257. package/build/src/protocol/operations.d.ts +1 -3
  258. package/build/src/protocol/operations.js +0 -8
  259. package/build/src/protocol/outcome.d.ts +1 -2
  260. package/build/src/protocol/outcome.js +1 -13
  261. package/build/src/protocol/placement.js +3 -10
  262. package/build/src/protocol/read/status.js +31 -70
  263. package/build/src/protocol/reintegrate.js +3 -10
  264. package/build/src/protocol/review.js +3 -3
  265. package/build/src/protocol/run.d.ts +5 -1
  266. package/build/src/protocol/run.js +3 -3
  267. package/build/src/runtime/proc/windows-launch.exe +0 -0
  268. package/build/src/settlement/fence.d.ts +3 -3
  269. package/build/src/settlement/fence.js +4 -4
  270. package/build/src/settlement/holder.d.ts +16 -16
  271. package/build/src/settlement/holder.js +69 -63
  272. package/build/src/settlement/settle.d.ts +5 -5
  273. package/build/src/settlement/settle.js +53 -53
  274. package/package.json +19 -9
  275. package/plugins/paseo/plugin/index.server.ts +17 -0
  276. package/plugins/paseo/plugin/paseo-plugin.json +4 -0
  277. package/plugins/paseo/plugin/server/attach.ts +52 -0
  278. package/plugins/paseo/plugin/server/keiyaku.ts +44 -0
  279. package/plugins/paseo/plugin/server/message.ts +60 -0
  280. package/plugins/paseo/plugin/server/mirror.ts +193 -0
  281. package/plugins/paseo/plugin/server/model.ts +14 -0
  282. package/plugins/paseo/plugin/server/provider.ts +276 -0
  283. package/plugins/paseo/plugin/server/sdk-worker.ts +237 -0
  284. package/plugins/paseo/plugin/server/sdk.ts +289 -0
  285. package/plugins/paseo/plugin/server/stop.ts +26 -0
  286. package/plugins/paseo/plugin/server/transport.ts +35 -0
  287. package/plugins/paseo/plugin/shared/attach-rpc.ts +10 -0
  288. package/plugins/paseo/plugin/shared/refresh-rpc.ts +6 -0
  289. package/plugins/paseo/plugin/tsconfig.json +6 -0
  290. package/plugins/pi/keiyaku.ts +57 -0
  291. package/skills/keiyaku/SKILL.md +43 -0
  292. package/skills/keiyaku-akuma/SKILL.md +130 -0
  293. package/skills/keiyaku-akuma/references/automation.md +269 -0
  294. package/skills/keiyaku-babysit/SKILL.md +65 -0
  295. package/skills/keiyaku-bind/SKILL.md +216 -0
  296. package/skills/keiyaku-bind/agents/openai.yaml +4 -0
  297. package/skills/keiyaku-debt/SKILL.md +91 -0
  298. package/skills/keiyaku-workflow/SKILL.md +129 -0
  299. package/build/plugins/claude/skills/keiyaku-task/SKILL.md +0 -104
  300. package/build/plugins/codex/skills/keiyaku-task/SKILL.md +0 -104
  301. package/build/plugins/opencode/skills/keiyaku-task/SKILL.md +0 -104
  302. package/build/skills/keiyaku-task/SKILL.md +0 -104
  303. package/build/src/cli/commands/amend.d.ts +0 -12
  304. package/build/src/cli/commands/amend.js +0 -10
  305. package/build/src/cli/commands/bind.d.ts +0 -11
  306. package/build/src/cli/commands/bind.js +0 -23
  307. package/build/src/cli/commands/task-grammar.d.ts +0 -19
  308. package/build/src/cli/commands/task-grammar.js +0 -384
  309. package/build/src/cli/commands/task-query.d.ts +0 -5
  310. package/build/src/cli/render/task.d.ts +0 -41
  311. package/build/src/dispatch/association.d.ts +0 -1
  312. package/build/src/dispatch/association.js +0 -1
  313. package/build/src/task/board.d.ts +0 -168
  314. package/build/src/task/catalog.d.ts +0 -11
  315. package/build/src/task/catalog.js +0 -59
  316. package/build/src/task/compose-language.d.ts +0 -57
  317. package/build/src/task/compose-language.js +0 -364
  318. package/build/src/task/compose-parser.d.ts +0 -32
  319. package/build/src/task/compose-parser.js +0 -180
  320. package/build/src/task/compose.d.ts +0 -16
  321. package/build/src/task/compose.js +0 -189
  322. package/build/src/task/document.d.ts +0 -39
  323. package/build/src/task/identity.d.ts +0 -21
  324. package/build/src/task/index.d.ts +0 -138
  325. package/build/src/task/index.js +0 -269
  326. package/build/src/task/lifecycle-operations.d.ts +0 -6
  327. package/build/src/task/mutation-result.d.ts +0 -1726
  328. package/build/src/task/mutation-result.js +0 -198
  329. package/build/src/task/mutation.d.ts +0 -590
  330. package/build/src/task/mutation.js +0 -262
  331. package/build/src/task/operation-types.d.ts +0 -71
  332. package/build/src/task/operations.d.ts +0 -28
  333. package/build/src/task/query.d.ts +0 -76
  334. package/build/src/task/view.d.ts +0 -4
  335. package/build/src/task/view.js +0 -7
  336. /package/build/src/{task → debt}/operation-types.js +0 -0
@@ -0,0 +1,160 @@
1
+ import { type DebtDocument, type DebtPriority, type DebtState } from "./document.js";
2
+ import { type DebtId } from "./identity.js";
3
+ import { z } from "zod";
4
+ import { type BoundedList } from "../bounded-list.js";
5
+ export type DebtRef = Readonly<{
6
+ id: DebtId;
7
+ title: string | null;
8
+ state: DebtState | "missing";
9
+ }>;
10
+ export declare const debtRowSchema: z.ZodObject<{
11
+ id: z.ZodPipe<z.ZodString, z.ZodTransform<`debt/${string}`, string>>;
12
+ title: z.ZodString;
13
+ state: z.ZodEnum<{
14
+ open: "open";
15
+ done: "done";
16
+ drop: "drop";
17
+ }>;
18
+ priority: z.ZodUnion<readonly [z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>]>;
19
+ disposition: z.ZodEnum<{
20
+ done: "done";
21
+ drop: "drop";
22
+ ready: "ready";
23
+ blocked: "blocked";
24
+ }>;
25
+ updatedAt: z.ZodString;
26
+ bodyPresent: z.ZodBoolean;
27
+ children: z.ZodOptional<z.ZodObject<{
28
+ live: z.ZodNumber;
29
+ total: z.ZodNumber;
30
+ }, z.core.$strict>>;
31
+ }, z.core.$strict>;
32
+ export declare const debtRowsSchema: z.ZodReadonly<z.ZodArray<z.ZodObject<{
33
+ id: z.ZodPipe<z.ZodString, z.ZodTransform<`debt/${string}`, string>>;
34
+ title: z.ZodString;
35
+ state: z.ZodEnum<{
36
+ open: "open";
37
+ done: "done";
38
+ drop: "drop";
39
+ }>;
40
+ priority: z.ZodUnion<readonly [z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>]>;
41
+ disposition: z.ZodEnum<{
42
+ done: "done";
43
+ drop: "drop";
44
+ ready: "ready";
45
+ blocked: "blocked";
46
+ }>;
47
+ updatedAt: z.ZodString;
48
+ bodyPresent: z.ZodBoolean;
49
+ children: z.ZodOptional<z.ZodObject<{
50
+ live: z.ZodNumber;
51
+ total: z.ZodNumber;
52
+ }, z.core.$strict>>;
53
+ }, z.core.$strict>>>;
54
+ export type DebtDisposition = z.infer<typeof debtRowSchema>["disposition"];
55
+ export type DebtRow = z.infer<typeof debtRowSchema>;
56
+ export type BlockedDebtRow = DebtRow & Readonly<{
57
+ blockers: readonly DebtRef[];
58
+ }>;
59
+ export type DebtDetailFacts = Readonly<{
60
+ debt: DebtDocument;
61
+ needs: readonly (DebtRef & Readonly<{
62
+ released: boolean;
63
+ }>)[];
64
+ blockers: readonly DebtRef[];
65
+ blocks: readonly DebtRef[];
66
+ parent: DebtRef | null;
67
+ children: readonly DebtRef[];
68
+ supersedes: readonly DebtRef[];
69
+ supersededBy: readonly DebtRef[];
70
+ related: readonly DebtRef[];
71
+ }>;
72
+ export type DebtTreeNode = Readonly<{
73
+ debt: DebtRef & Readonly<{
74
+ priority: DebtPriority | null;
75
+ }>;
76
+ cycle?: true;
77
+ children: readonly DebtTreeNode[];
78
+ }>;
79
+ export type DebtBoard = Readonly<{
80
+ debts: ReadonlyMap<DebtId, DebtDocument>;
81
+ }>;
82
+ /** The local ids occupied across one namespace of the current board. */
83
+ export declare function occupiedLocalIds(board: DebtBoard, namespace: readonly string[]): Set<string>;
84
+ type DebtRelation = "needs" | "parent" | "supersedes" | "relates";
85
+ export type DebtDoctorIssue = Readonly<{
86
+ kind: "missing-target";
87
+ debtId: DebtId;
88
+ relation: DebtRelation;
89
+ target: DebtId;
90
+ }> | Readonly<{
91
+ kind: "self-relation";
92
+ debtId: DebtId;
93
+ relation: DebtRelation;
94
+ }> | Readonly<{
95
+ kind: "cycle";
96
+ relation: "needs" | "parent" | "supersedes";
97
+ debts: readonly DebtId[];
98
+ }>;
99
+ export declare function debtRef(board: DebtBoard, id: DebtId): DebtRef;
100
+ export type DebtRelationProjection = Readonly<{
101
+ children(id: DebtId): readonly DebtRef[];
102
+ blocks(id: DebtId): readonly DebtRef[];
103
+ supersededBy(id: DebtId): readonly DebtRef[];
104
+ related(id: DebtId): readonly DebtRef[];
105
+ }>;
106
+ export declare function createDebtRelations(board: DebtBoard): DebtRelationProjection;
107
+ export declare function debtDisposition(board: DebtBoard, debt: DebtDocument): DebtDisposition;
108
+ export declare function debtBlocked(board: DebtBoard, debt: DebtDocument): boolean;
109
+ export declare function projectOwnedDetailFacts(board: DebtBoard, id: DebtId): DebtDetailFacts | null;
110
+ export declare function projectDetailFacts(board: DebtBoard, id: DebtId, relations: DebtRelationProjection): DebtDetailFacts | null;
111
+ export declare function projectDebtRow(board: DebtBoard, relations: DebtRelationProjection, debt: DebtDocument): DebtRow;
112
+ export declare function projectRows(board: DebtBoard, relations: DebtRelationProjection, scope: readonly string[] | null, selection: "active" | "closed" | "all"): readonly DebtRow[];
113
+ /**
114
+ * Rows for the identities that created work, grouped by creator. Only documents a
115
+ * requested identity created reach row projection, and each group keeps the
116
+ * established row order.
117
+ */
118
+ export declare function projectCreatedByRows(board: DebtBoard, relations: DebtRelationProjection, createdByIds: readonly string[]): ReadonlyMap<string, readonly DebtRow[]>;
119
+ export declare function projectBlocked(board: DebtBoard, scope: readonly string[] | null, relations: DebtRelationProjection): readonly BlockedDebtRow[];
120
+ export declare function projectStatusRows(board: DebtBoard, relations: DebtRelationProjection, scope: readonly string[] | null): ({
121
+ id: `debt/${string}`;
122
+ title: string;
123
+ state: "open" | "done" | "drop";
124
+ priority: 0 | 1 | 2 | 3;
125
+ disposition: "done" | "drop" | "ready" | "blocked";
126
+ updatedAt: string;
127
+ bodyPresent: boolean;
128
+ children?: {
129
+ live: number;
130
+ total: number;
131
+ } | undefined;
132
+ } | {
133
+ blockers: readonly Readonly<{
134
+ id: DebtId;
135
+ title: string | null;
136
+ state: DebtState | "missing";
137
+ }>[];
138
+ id: `debt/${string}`;
139
+ title: string;
140
+ state: "open" | "done" | "drop";
141
+ priority: 0 | 1 | 2 | 3;
142
+ disposition: "done" | "drop" | "ready" | "blocked";
143
+ updatedAt: string;
144
+ bodyPresent: boolean;
145
+ children?: {
146
+ live: number;
147
+ total: number;
148
+ } | undefined;
149
+ })[];
150
+ export type DebtBoardObservation = Readonly<{
151
+ statusRows: ReturnType<typeof projectStatusRows>;
152
+ selectRecentStatus(limit?: number): BoundedList<ReturnType<typeof projectStatusRows>[number]>;
153
+ selectNamespace(namespace: readonly string[]): readonly DebtRow[];
154
+ selectCreatedBy(createdBy: string): readonly DebtRow[];
155
+ }>;
156
+ export declare function projectDebtBoardObservation(board: DebtBoard): DebtBoardObservation;
157
+ export declare function relationProblem(board: DebtBoard, before: DebtDocument | null, after: DebtDocument): string | null;
158
+ export declare function diagnoseBoard(board: DebtBoard): readonly DebtDoctorIssue[];
159
+ export declare function buildTree(board: DebtBoard, root: DebtId, relations: DebtRelationProjection): DebtTreeNode | null;
160
+ export {};
@@ -1,16 +1,16 @@
1
- import { taskNonblankTextSchema, taskStateSchema, taskPrioritySchema, } from "./document.js";
2
- import { taskIdSchema, parseTaskId, sameNamespace } from "./identity.js";
1
+ import { debtNonblankTextSchema, debtStateSchema, debtPrioritySchema, } from "./document.js";
2
+ import { debtIdSchema, parseDebtId, sameNamespace } from "./identity.js";
3
3
  import { z } from "zod";
4
4
  import { boundedListLimit, projectBoundedList } from "../bounded-list.js";
5
- const taskRowTimestampSchema = z.string().refine((value) => Number.isFinite(Date.parse(value)), "expected timestamp");
6
- export const taskRowSchema = z
5
+ const debtRowTimestampSchema = z.string().refine((value) => Number.isFinite(Date.parse(value)), "expected timestamp");
6
+ export const debtRowSchema = z
7
7
  .object({
8
- id: taskIdSchema,
9
- title: taskNonblankTextSchema,
10
- state: taskStateSchema,
11
- priority: taskPrioritySchema,
12
- disposition: z.enum(["ready", "blocked", "in_progress", "on_hold", "done", "drop"]),
13
- updatedAt: taskRowTimestampSchema,
8
+ id: debtIdSchema,
9
+ title: debtNonblankTextSchema,
10
+ state: debtStateSchema,
11
+ priority: debtPrioritySchema,
12
+ disposition: z.enum(["ready", "blocked", "done", "drop"]),
13
+ updatedAt: debtRowTimestampSchema,
14
14
  bodyPresent: z.boolean(),
15
15
  children: z
16
16
  .object({ live: z.number().int().nonnegative(), total: z.number().int().nonnegative() })
@@ -18,20 +18,20 @@ export const taskRowSchema = z
18
18
  .optional(),
19
19
  })
20
20
  .strict();
21
- export const taskRowsSchema = z.array(taskRowSchema).readonly();
21
+ export const debtRowsSchema = z.array(debtRowSchema).readonly();
22
22
  /** The local ids occupied across one namespace of the current board. */
23
23
  export function occupiedLocalIds(board, namespace) {
24
- return new Set([...board.tasks.values()].flatMap((task) => {
25
- const coordinate = parseTaskId(task.id);
24
+ return new Set([...board.debts.values()].flatMap((debt) => {
25
+ const coordinate = parseDebtId(debt.id);
26
26
  return sameNamespace(coordinate.namespace, namespace) ? [coordinate.localId] : [];
27
27
  }));
28
28
  }
29
29
  const terminal = (state) => state === "done" || state === "drop";
30
30
  const none = Object.freeze([]);
31
31
  const sorted = (values) => [...values].sort((a, b) => Buffer.compare(Buffer.from(a.id), Buffer.from(b.id)));
32
- export function taskRef(board, id) {
33
- const task = board.tasks.get(id);
34
- return task === undefined ? { id, title: null, state: "missing" } : { id, title: task.title, state: task.state };
32
+ export function debtRef(board, id) {
33
+ const debt = board.debts.get(id);
34
+ return debt === undefined ? { id, title: null, state: "missing" } : { id, title: debt.title, state: debt.state };
35
35
  }
36
36
  function append(index, key, value) {
37
37
  const values = index.get(key);
@@ -41,22 +41,22 @@ function append(index, key, value) {
41
41
  values.push(value);
42
42
  }
43
43
  function freezeRefs(board, index) {
44
- return new Map([...index].map(([id, targets]) => [id, sorted(targets.map((target) => taskRef(board, target)))]));
44
+ return new Map([...index].map(([id, targets]) => [id, sorted(targets.map((target) => debtRef(board, target)))]));
45
45
  }
46
- export function createTaskRelations(board) {
46
+ export function createDebtRelations(board) {
47
47
  const children = new Map();
48
48
  const blocks = new Map();
49
49
  const supersededBy = new Map();
50
50
  const incoming = new Map();
51
- for (const task of board.tasks.values()) {
52
- if (task.parent !== null)
53
- append(children, task.parent, task.id);
54
- for (const need of task.needs)
55
- append(blocks, need, task.id);
56
- for (const target of task.supersedes)
57
- append(supersededBy, target, task.id);
58
- for (const target of task.relates)
59
- append(incoming, target, task.id);
51
+ for (const debt of board.debts.values()) {
52
+ if (debt.parent !== null)
53
+ append(children, debt.parent, debt.id);
54
+ for (const need of debt.needs)
55
+ append(blocks, need, debt.id);
56
+ for (const target of debt.supersedes)
57
+ append(supersededBy, target, debt.id);
58
+ for (const target of debt.relates)
59
+ append(incoming, target, debt.id);
60
60
  }
61
61
  const childRefs = freezeRefs(board, children);
62
62
  const blockRefs = freezeRefs(board, blocks);
@@ -67,44 +67,44 @@ export function createTaskRelations(board) {
67
67
  blocks: (id) => blockRefs.get(id) ?? none,
68
68
  supersededBy: (id) => successorRefs.get(id) ?? none,
69
69
  related: (id) => {
70
- const task = board.tasks.get(id);
71
- const ids = new Set(task?.relates ?? []);
70
+ const debt = board.debts.get(id);
71
+ const ids = new Set(debt?.relates ?? []);
72
72
  for (const ref of incomingRefs.get(id) ?? none)
73
73
  ids.add(ref.id);
74
- return ids.size === 0 ? none : sorted([...ids].map((related) => taskRef(board, related)));
74
+ return ids.size === 0 ? none : sorted([...ids].map((related) => debtRef(board, related)));
75
75
  },
76
76
  };
77
77
  }
78
78
  function needReleased(board, id) {
79
- const target = board.tasks.get(id);
79
+ const target = board.debts.get(id);
80
80
  return target !== undefined && terminal(target.state);
81
81
  }
82
- function hasUnresolvedNeeds(board, task) {
83
- return task.needs.some((id) => !needReleased(board, id));
82
+ function hasUnresolvedNeeds(board, debt) {
83
+ return debt.needs.some((id) => !needReleased(board, id));
84
84
  }
85
- export function taskDisposition(board, task) {
86
- if (task.state !== "open")
87
- return task.state;
88
- return hasUnresolvedNeeds(board, task) ? "blocked" : "ready";
85
+ export function debtDisposition(board, debt) {
86
+ if (debt.state !== "open")
87
+ return debt.state;
88
+ return hasUnresolvedNeeds(board, debt) ? "blocked" : "ready";
89
89
  }
90
- export function taskBlocked(board, task) {
91
- return (task.state === "open" || task.state === "in_progress") && hasUnresolvedNeeds(board, task);
90
+ export function debtBlocked(board, debt) {
91
+ return debt.state === "open" && hasUnresolvedNeeds(board, debt);
92
92
  }
93
93
  export function projectOwnedDetailFacts(board, id) {
94
- const task = board.tasks.get(id);
95
- if (task === undefined)
94
+ const debt = board.debts.get(id);
95
+ if (debt === undefined)
96
96
  return null;
97
- const needs = task.needs.map((need) => ({ ...taskRef(board, need), released: needReleased(board, need) }));
97
+ const needs = debt.needs.map((need) => ({ ...debtRef(board, need), released: needReleased(board, need) }));
98
98
  return {
99
- task,
99
+ debt,
100
100
  needs,
101
101
  blockers: needs.filter((need) => !need.released).map(({ released: _released, ...ref }) => ref),
102
102
  blocks: none,
103
- parent: task.parent === null ? null : taskRef(board, task.parent),
103
+ parent: debt.parent === null ? null : debtRef(board, debt.parent),
104
104
  children: none,
105
- supersedes: task.supersedes.map((target) => taskRef(board, target)),
105
+ supersedes: debt.supersedes.map((target) => debtRef(board, target)),
106
106
  supersededBy: none,
107
- related: task.relates.length === 0 ? none : sorted(task.relates.map((target) => taskRef(board, target))),
107
+ related: debt.relates.length === 0 ? none : sorted(debt.relates.map((target) => debtRef(board, target))),
108
108
  };
109
109
  }
110
110
  export function projectDetailFacts(board, id, relations) {
@@ -119,33 +119,33 @@ export function projectDetailFacts(board, id, relations) {
119
119
  related: relations.related(id),
120
120
  };
121
121
  }
122
- function inScope(task, scope) {
123
- return scope === null || sameNamespace(parseTaskId(task.id).namespace, scope);
122
+ function inScope(debt, scope) {
123
+ return scope === null || sameNamespace(parseDebtId(debt.id).namespace, scope);
124
124
  }
125
- export function projectTaskRow(board, relations, task) {
126
- const children = relations.children(task.id);
125
+ export function projectDebtRow(board, relations, debt) {
126
+ const children = relations.children(debt.id);
127
127
  const total = children.length;
128
128
  const live = children.filter((child) => child.state !== "done" && child.state !== "drop").length;
129
129
  return {
130
- id: task.id,
131
- title: task.title,
132
- state: task.state,
133
- priority: task.priority,
134
- disposition: taskDisposition(board, task),
135
- updatedAt: task.updatedAt,
136
- bodyPresent: task.body.length > 0,
130
+ id: debt.id,
131
+ title: debt.title,
132
+ state: debt.state,
133
+ priority: debt.priority,
134
+ disposition: debtDisposition(board, debt),
135
+ updatedAt: debt.updatedAt,
136
+ bodyPresent: debt.body.length > 0,
137
137
  ...(total === 0 ? {} : { children: { live, total } }),
138
138
  };
139
139
  }
140
140
  export function projectRows(board, relations, scope, selection) {
141
- return [...board.tasks.values()]
142
- .filter((task) => inScope(task, scope))
143
- .filter((task) => selection === "all" || (selection === "closed") === terminal(task.state))
144
- .map((task) => projectTaskRow(board, relations, task))
145
- .sort(compareTaskRows);
141
+ return [...board.debts.values()]
142
+ .filter((debt) => inScope(debt, scope))
143
+ .filter((debt) => selection === "all" || (selection === "closed") === terminal(debt.state))
144
+ .map((debt) => projectDebtRow(board, relations, debt))
145
+ .sort(compareDebtRows);
146
146
  }
147
- /** The established Task row order: priority first, then canonical identity bytes. */
148
- function compareTaskRows(left, right) {
147
+ /** The established Debt row order: priority first, then canonical identity bytes. */
148
+ function compareDebtRows(left, right) {
149
149
  return left.priority - right.priority || Buffer.compare(Buffer.from(left.id), Buffer.from(right.id));
150
150
  }
151
151
  /**
@@ -156,13 +156,13 @@ function compareTaskRows(left, right) {
156
156
  export function projectCreatedByRows(board, relations, createdByIds) {
157
157
  const requested = new Set(createdByIds);
158
158
  const attributed = [];
159
- for (const task of board.tasks.values()) {
160
- const createdBy = task.createdBy;
159
+ for (const debt of board.debts.values()) {
160
+ const createdBy = debt.createdBy;
161
161
  if (createdBy === undefined || !requested.has(createdBy))
162
162
  continue;
163
- attributed.push({ createdBy, row: projectTaskRow(board, relations, task) });
163
+ attributed.push({ createdBy, row: projectDebtRow(board, relations, debt) });
164
164
  }
165
- attributed.sort((left, right) => compareTaskRows(left.row, right.row));
165
+ attributed.sort((left, right) => compareDebtRows(left.row, right.row));
166
166
  const grouped = new Map();
167
167
  for (const { createdBy, row } of attributed) {
168
168
  const rows = grouped.get(createdBy);
@@ -175,7 +175,7 @@ export function projectCreatedByRows(board, relations, createdByIds) {
175
175
  }
176
176
  export function projectBlocked(board, scope, relations) {
177
177
  return projectRows(board, relations, scope, "active").flatMap((row) => {
178
- if (!taskBlocked(board, board.tasks.get(row.id)))
178
+ if (!debtBlocked(board, board.debts.get(row.id)))
179
179
  return [];
180
180
  return [{ ...row, blockers: projectDetailFacts(board, row.id, relations).blockers }];
181
181
  });
@@ -187,8 +187,8 @@ export function projectStatusRows(board, relations, scope) {
187
187
  return unresolved === undefined ? row : { ...row, blockers: unresolved };
188
188
  });
189
189
  }
190
- export function projectTaskBoardObservation(board) {
191
- const relations = createTaskRelations(board);
190
+ export function projectDebtBoardObservation(board) {
191
+ const relations = createDebtRelations(board);
192
192
  const rows = projectRows(board, relations, null, "all");
193
193
  const statusRows = projectStatusRows(board, relations, null);
194
194
  return {
@@ -198,11 +198,11 @@ export function projectTaskBoardObservation(board) {
198
198
  .sort((left, right) => right.updatedAt.localeCompare(left.updatedAt) ||
199
199
  Buffer.compare(Buffer.from(left.id), Buffer.from(right.id))), boundedListLimit(limit)),
200
200
  selectNamespace: (namespace) => projectRows(board, relations, namespace, "all"),
201
- selectCreatedBy: (createdBy) => rows.filter((row) => board.tasks.get(row.id)?.createdBy === createdBy),
201
+ selectCreatedBy: (createdBy) => rows.filter((row) => board.debts.get(row.id)?.createdBy === createdBy),
202
202
  };
203
203
  }
204
- function relationIds(task, relation) {
205
- return relation === "parent" ? (task.parent === null ? [] : [task.parent]) : task[relation];
204
+ function relationIds(debt, relation) {
205
+ return relation === "parent" ? (debt.parent === null ? [] : [debt.parent]) : debt[relation];
206
206
  }
207
207
  export function relationProblem(board, before, after) {
208
208
  for (const relation of ["needs", "parent", "supersedes", "relates"]) {
@@ -212,15 +212,15 @@ export function relationProblem(board, before, after) {
212
212
  continue;
213
213
  if (target === after.id)
214
214
  return `${after.id} has a self ${relation} relation`;
215
- if (!board.tasks.has(target))
215
+ if (!board.debts.has(target))
216
216
  return `${after.id} ${relation} target does not exist: ${target}`;
217
217
  }
218
218
  }
219
219
  return null;
220
220
  }
221
221
  function cycleComponents(board, relation) {
222
- const ids = sorted([...board.tasks.keys()].map((id) => ({ id }))).map(({ id }) => id);
223
- const edges = new Map(ids.map((id) => [id, relationIds(board.tasks.get(id), relation).filter((target) => board.tasks.has(target))]));
222
+ const ids = sorted([...board.debts.keys()].map((id) => ({ id }))).map(({ id }) => id);
223
+ const edges = new Map(ids.map((id) => [id, relationIds(board.debts.get(id), relation).filter((target) => board.debts.has(target))]));
224
224
  const reverse = new Map(ids.map((id) => [id, []]));
225
225
  for (const [id, targets] of edges)
226
226
  for (const target of targets)
@@ -268,28 +268,28 @@ function cycleComponents(board, relation) {
268
268
  }
269
269
  export function diagnoseBoard(board) {
270
270
  const issues = [];
271
- for (const task of sorted(board.tasks.values()))
271
+ for (const debt of sorted(board.debts.values()))
272
272
  for (const relation of ["needs", "parent", "supersedes", "relates"]) {
273
- for (const target of relationIds(task, relation)) {
274
- if (target === task.id)
275
- issues.push({ kind: "self-relation", taskId: task.id, relation });
276
- else if (!board.tasks.has(target))
277
- issues.push({ kind: "missing-target", taskId: task.id, relation, target });
273
+ for (const target of relationIds(debt, relation)) {
274
+ if (target === debt.id)
275
+ issues.push({ kind: "self-relation", debtId: debt.id, relation });
276
+ else if (!board.debts.has(target))
277
+ issues.push({ kind: "missing-target", debtId: debt.id, relation, target });
278
278
  }
279
279
  }
280
280
  for (const relation of ["needs", "parent", "supersedes"]) {
281
- for (const tasks of cycleComponents(board, relation))
282
- issues.push({ kind: "cycle", relation, tasks });
281
+ for (const debts of cycleComponents(board, relation))
282
+ issues.push({ kind: "cycle", relation, debts });
283
283
  }
284
284
  return issues;
285
285
  }
286
286
  export function buildTree(board, root, relations) {
287
- if (!board.tasks.has(root))
287
+ if (!board.debts.has(root))
288
288
  return null;
289
289
  const walk = (id, path) => {
290
- const ref = taskRef(board, id);
291
- const task = board.tasks.get(id);
292
- const node = { task: { ...ref, priority: task?.priority ?? null } };
290
+ const ref = debtRef(board, id);
291
+ const debt = board.debts.get(id);
292
+ const node = { debt: { ...ref, priority: debt?.priority ?? null } };
293
293
  if (path.includes(id))
294
294
  return { ...node, cycle: true, children: [] };
295
295
  return { ...node, children: relations.children(id).map((child) => walk(child.id, [...path, id])) };
@@ -0,0 +1,11 @@
1
+ import type { BoundedList } from "../bounded-list.js";
2
+ import type { DebtRef, DebtRow } from "./board.js";
3
+ import type { WorldRoot } from "../world.js";
4
+ export declare function parseDebtNamespaceSelector(value: string): readonly string[];
5
+ export type RecentDebtStatusRow = DebtRow & Readonly<{
6
+ blockers?: readonly DebtRef[];
7
+ }>;
8
+ export declare function observeRecentDebtStatus(world: WorldRoot, input?: Readonly<{
9
+ namespace?: readonly string[];
10
+ limit?: number;
11
+ }>): Promise<BoundedList<RecentDebtStatusRow>>;
@@ -0,0 +1,59 @@
1
+ import { isDebtSegment, parseDebtId } from "./identity.js";
2
+ import { readRecentDebtDocuments, readDebtDocument } from "./store.js";
3
+ export function parseDebtNamespaceSelector(value) {
4
+ if (value === "debt/")
5
+ return [];
6
+ if (!value.startsWith("debt/") || !value.endsWith("/")) {
7
+ throw new TypeError(`invalid Debt namespace selector: ${value}`);
8
+ }
9
+ const body = value.slice("debt/".length, -1);
10
+ const segments = body.split("/");
11
+ if (body.length === 0 || !segments.every(isDebtSegment)) {
12
+ throw new TypeError(`invalid Debt namespace selector: ${value}`);
13
+ }
14
+ return parseDebtId(`debt/${body}/placeholder`).namespace;
15
+ }
16
+ function terminal(debt) {
17
+ return debt?.state === "done" || debt?.state === "drop";
18
+ }
19
+ async function catalogRow(world, debt, documents) {
20
+ const needs = await Promise.all(debt.needs.map(async (id) => documents.get(id) ?? (await readDebtDocument(world, id))));
21
+ const blockers = [];
22
+ if (debt.state === "open") {
23
+ for (const [index, need] of needs.entries()) {
24
+ if (terminal(need))
25
+ continue;
26
+ blockers.push({ id: debt.needs[index], title: need?.title ?? null, state: need?.state ?? "missing" });
27
+ }
28
+ }
29
+ return {
30
+ id: debt.id,
31
+ title: debt.title,
32
+ state: debt.state,
33
+ priority: debt.priority,
34
+ disposition: debt.state === "open" && needs.some((need) => !terminal(need))
35
+ ? "blocked"
36
+ : debt.state === "open"
37
+ ? "ready"
38
+ : debt.state,
39
+ updatedAt: debt.updatedAt,
40
+ bodyPresent: debt.body.length > 0,
41
+ ...(blockers.length === 0 ? {} : { blockers }),
42
+ };
43
+ }
44
+ export async function observeRecentDebtStatus(world, input = {}) {
45
+ const { namespace } = input;
46
+ if (namespace !== undefined && !namespace.every(isDebtSegment)) {
47
+ throw new TypeError("namespace must contain canonical segments");
48
+ }
49
+ const documents = await readRecentDebtDocuments(world, {
50
+ ...(namespace === undefined ? {} : { namespace }),
51
+ selection: "active",
52
+ ...(input.limit === undefined ? {} : { limit: input.limit }),
53
+ });
54
+ const known = new Map(documents.rows.map((document) => [document.id, document]));
55
+ return {
56
+ rows: await Promise.all(documents.rows.map((document) => catalogRow(world, document, known))),
57
+ hasMore: documents.hasMore,
58
+ };
59
+ }
@@ -15,7 +15,7 @@ export type ResolvedNamespaceContext = Readonly<{
15
15
  export declare function readNamespaceContext(coordinates: NamespaceContextInput): Promise<NamespaceContextRead>;
16
16
  export declare function installNamespaceContext(root: string, segments: readonly string[]): Promise<void>;
17
17
  export declare function repairNamespaceContext(root: string, segments: readonly string[]): Promise<"kept" | "installed">;
18
- export declare function resolveTaskNamespaceContext(input: NamespaceContextInput): Promise<ResolvedNamespaceContext | Readonly<{
18
+ export declare function resolveDebtNamespaceContext(input: NamespaceContextInput): Promise<ResolvedNamespaceContext | Readonly<{
19
19
  kind: "invalid-namespace-context";
20
20
  path: string;
21
21
  }>>;
@@ -80,7 +80,7 @@ export async function repairNamespaceContext(root, segments) {
80
80
  await installNamespaceContext(root, segments);
81
81
  return "installed";
82
82
  }
83
- export async function resolveTaskNamespaceContext(input) {
83
+ export async function resolveDebtNamespaceContext(input) {
84
84
  let current = input.directory;
85
85
  for (;;) {
86
86
  const selected = await readAtWithPath(current);
@@ -1,21 +1,17 @@
1
1
  import type { WorldRoot } from "../world.js";
2
2
  import { z } from "zod";
3
- export declare const createdTaskObservationSchema: z.ZodUnion<readonly [z.ZodObject<{
3
+ export declare const createdDebtObservationSchema: z.ZodUnion<readonly [z.ZodObject<{
4
4
  kind: z.ZodLiteral<"present">;
5
5
  rows: z.ZodReadonly<z.ZodArray<z.ZodObject<{
6
- id: z.ZodPipe<z.ZodString, z.ZodTransform<`task/${string}`, string>>;
6
+ id: z.ZodPipe<z.ZodString, z.ZodTransform<`debt/${string}`, string>>;
7
7
  title: z.ZodString;
8
8
  state: z.ZodEnum<{
9
9
  open: "open";
10
- in_progress: "in_progress";
11
- on_hold: "on_hold";
12
10
  done: "done";
13
11
  drop: "drop";
14
12
  }>;
15
13
  priority: z.ZodUnion<readonly [z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>]>;
16
14
  disposition: z.ZodEnum<{
17
- in_progress: "in_progress";
18
- on_hold: "on_hold";
19
15
  done: "done";
20
16
  drop: "drop";
21
17
  ready: "ready";
@@ -32,11 +28,11 @@ export declare const createdTaskObservationSchema: z.ZodUnion<readonly [z.ZodObj
32
28
  kind: z.ZodLiteral<"failed">;
33
29
  diagnostic: z.ZodString;
34
30
  }, z.core.$strict>]>;
35
- export type CreatedTaskObservation = z.infer<typeof createdTaskObservationSchema>;
36
- export declare const EMPTY_CREATED_TASK_OBSERVATION: CreatedTaskObservation;
31
+ export type CreatedDebtObservation = z.infer<typeof createdDebtObservationSchema>;
32
+ export declare const EMPTY_CREATED_DEBT_OBSERVATION: CreatedDebtObservation;
37
33
  /**
38
- * Project Task board rows created by each identity, preserving input order. One complete
34
+ * Project Debt board rows created by each identity, preserving input order. One complete
39
35
  * board and one relationship projection answer every requested identity, and only the
40
36
  * documents those identities created reach row projection.
41
37
  */
42
- export declare function observeCreatedTaskObservations(world: WorldRoot, createdByIds: readonly string[]): Promise<readonly CreatedTaskObservation[]>;
38
+ export declare function observeCreatedDebtObservations(world: WorldRoot, createdByIds: readonly string[]): Promise<readonly CreatedDebtObservation[]>;
@@ -1,20 +1,20 @@
1
1
  import { z } from "zod";
2
- import { createTaskRelations, projectCreatedByRows, taskRowsSchema } from "./board.js";
2
+ import { createDebtRelations, projectCreatedByRows, debtRowsSchema } from "./board.js";
3
3
  import { readBoard } from "./store.js";
4
- export const createdTaskObservationSchema = z.union([
5
- z.object({ kind: z.literal("present"), rows: taskRowsSchema }).strict(),
4
+ export const createdDebtObservationSchema = z.union([
5
+ z.object({ kind: z.literal("present"), rows: debtRowsSchema }).strict(),
6
6
  z.object({ kind: z.literal("failed"), diagnostic: z.string() }).strict(),
7
7
  ]);
8
- export const EMPTY_CREATED_TASK_OBSERVATION = { kind: "present", rows: [] };
8
+ export const EMPTY_CREATED_DEBT_OBSERVATION = { kind: "present", rows: [] };
9
9
  function observationDiagnostic(error) {
10
10
  return error instanceof Error ? error.message : String(error);
11
11
  }
12
12
  /**
13
- * Project Task board rows created by each identity, preserving input order. One complete
13
+ * Project Debt board rows created by each identity, preserving input order. One complete
14
14
  * board and one relationship projection answer every requested identity, and only the
15
15
  * documents those identities created reach row projection.
16
16
  */
17
- export async function observeCreatedTaskObservations(world, createdByIds) {
17
+ export async function observeCreatedDebtObservations(world, createdByIds) {
18
18
  if (createdByIds.length === 0)
19
19
  return [];
20
20
  let board;
@@ -25,6 +25,6 @@ export async function observeCreatedTaskObservations(world, createdByIds) {
25
25
  const failed = { kind: "failed", diagnostic: observationDiagnostic(error) };
26
26
  return createdByIds.map(() => failed);
27
27
  }
28
- const rows = projectCreatedByRows(board, createTaskRelations(board), createdByIds);
28
+ const rows = projectCreatedByRows(board, createDebtRelations(board), createdByIds);
29
29
  return createdByIds.map((createdBy) => ({ kind: "present", rows: rows.get(createdBy) ?? [] }));
30
30
  }