@astrosheep/keiyaku 4.5.11 → 4.5.13

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 (272) hide show
  1. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +135 -377
  2. package/build/integrations/pi/keiyaku.ts +11 -116
  3. package/build/src/akuma/akuma-errors.d.ts +1 -0
  4. package/build/src/akuma/akuma-errors.js +1 -0
  5. package/build/src/akuma/akuma-handle.d.ts +1 -0
  6. package/build/src/akuma/akuma-handle.js +6 -7
  7. package/build/src/akuma/akuma-product.d.ts +6 -8
  8. package/build/src/akuma/akuma-product.js +141 -57
  9. package/build/src/akuma/akuma.d.ts +5 -7
  10. package/build/src/akuma/akuma.js +1 -22
  11. package/build/src/akuma/archetype.d.ts +6 -5
  12. package/build/src/akuma/archetype.js +137 -38
  13. package/build/src/akuma/body.d.ts +5 -5
  14. package/build/src/akuma/body.js +223 -63
  15. package/build/src/akuma/call-input.d.ts +4 -0
  16. package/build/src/akuma/call-input.js +21 -0
  17. package/build/src/akuma/call-request.d.ts +5 -8
  18. package/build/src/akuma/call-request.js +28 -73
  19. package/build/src/akuma/fleet-execution.d.ts +26 -0
  20. package/build/src/akuma/fleet-execution.js +109 -0
  21. package/build/src/{library/fleet-result.d.ts → akuma/fleet-observation.d.ts} +13 -57
  22. package/build/src/{library/fleet-result.js → akuma/fleet-observation.js} +4 -25
  23. package/build/src/akuma/fleet-request.d.ts +122 -0
  24. package/build/src/akuma/fleet-request.js +168 -0
  25. package/build/src/akuma/heart/facts.d.ts +23 -0
  26. package/build/src/akuma/heart/facts.js +7 -0
  27. package/build/src/akuma/heart/index.d.ts +43 -4
  28. package/build/src/akuma/heart/index.js +107 -7
  29. package/build/src/akuma/heart/request-authority.d.ts +2 -0
  30. package/build/src/akuma/heart/request-authority.js +28 -3
  31. package/build/src/akuma/heart/request-rows.d.ts +2 -0
  32. package/build/src/akuma/heart/request-rows.js +24 -5
  33. package/build/src/akuma/heart/rows.d.ts +4 -1
  34. package/build/src/akuma/heart/rows.js +46 -19
  35. package/build/src/akuma/heart/schema.d.ts +1 -1
  36. package/build/src/akuma/heart/schema.js +28 -6
  37. package/build/src/akuma/heart/storage.d.ts +1 -1
  38. package/build/src/akuma/heart/tells.d.ts +29 -0
  39. package/build/src/akuma/heart/tells.js +136 -5
  40. package/build/src/akuma/heart/timeline.js +9 -3
  41. package/build/src/akuma/projection-read.js +36 -3
  42. package/build/src/akuma/projection.js +3 -4
  43. package/build/src/akuma/provider.d.ts +4 -0
  44. package/build/src/akuma/provider.js +56 -3
  45. package/build/src/akuma/providers/claude/index.js +3 -0
  46. package/build/src/akuma/providers/codex-app-server/index.js +14 -12
  47. package/build/src/akuma/providers/pi/index.js +7 -1
  48. package/build/src/akuma/publication.js +65 -49
  49. package/build/src/akuma/request-lifecycle.d.ts +5 -4
  50. package/build/src/akuma/request-lifecycle.js +29 -16
  51. package/build/src/akuma/request-rendezvous.d.ts +15 -12
  52. package/build/src/akuma/request-rendezvous.js +80 -51
  53. package/build/src/akuma/request-serve.d.ts +1 -2
  54. package/build/src/akuma/request-serve.js +94 -39
  55. package/build/src/akuma/request-wire.d.ts +57 -26
  56. package/build/src/akuma/request-wire.js +64 -25
  57. package/build/src/akuma/turn-drive.d.ts +5 -4
  58. package/build/src/akuma/turn-drive.js +27 -11
  59. package/build/src/akuma-body.d.ts +4 -6
  60. package/build/src/akuma-body.js +19 -17
  61. package/build/src/bounded-list.d.ts +8 -0
  62. package/build/src/bounded-list.js +14 -0
  63. package/build/src/cli/accepted.d.ts +1 -1
  64. package/build/src/cli/accepted.js +1 -0
  65. package/build/src/cli/commands/akuma-invoke.js +1 -25
  66. package/build/src/cli/commands/contract-help.d.ts +5 -2
  67. package/build/src/cli/commands/contract-help.js +62 -12
  68. package/build/src/cli/commands/contract-invoke.d.ts +5 -0
  69. package/build/src/cli/commands/contract-invoke.js +26 -1
  70. package/build/src/cli/commands/contract.js +50 -18
  71. package/build/src/cli/commands/task-invoke.js +10 -2
  72. package/build/src/cli/commands/task-query.js +3 -4
  73. package/build/src/cli/coordinates.d.ts +13 -0
  74. package/build/src/cli/coordinates.js +38 -24
  75. package/build/src/cli/draft.d.ts +1 -1
  76. package/build/src/cli/invoke.js +14 -1
  77. package/build/src/cli/render/akuma-activity.d.ts +0 -1
  78. package/build/src/cli/render/akuma-activity.js +5 -38
  79. package/build/src/cli/render/akuma.js +4 -1
  80. package/build/src/cli/render/audit.js +4 -1
  81. package/build/src/cli/render/catalog.js +13 -39
  82. package/build/src/cli/render/contract.js +4 -14
  83. package/build/src/cli/render/kanshi-akuma.js +3 -8
  84. package/build/src/cli/render/kanshi.js +8 -34
  85. package/build/src/cli/render/nuke.js +7 -3
  86. package/build/src/cli/render/receipt.d.ts +1 -0
  87. package/build/src/cli/render/receipt.js +8 -0
  88. package/build/src/cli/render/refusal.js +4 -3
  89. package/build/src/cli/render/task.js +4 -37
  90. package/build/src/cli/render/terminal.d.ts +2 -6
  91. package/build/src/cli/render/terminal.js +4 -9
  92. package/build/src/cli/result.d.ts +2 -1
  93. package/build/src/contract-guidance.js +13 -3
  94. package/build/src/contract-worktree.d.ts +1 -0
  95. package/build/src/contract-worktree.js +26 -2
  96. package/build/src/core/facts/codec.d.ts +2 -1
  97. package/build/src/core/facts/codec.js +3 -0
  98. package/build/src/core/facts/gate.d.ts +2 -1
  99. package/build/src/core/facts/gate.js +63 -0
  100. package/build/src/core/verbs/abandon.d.ts +2 -1
  101. package/build/src/core/verbs/abandon.js +16 -0
  102. package/build/src/core/verbs/amend.d.ts +2 -1
  103. package/build/src/core/verbs/amend.js +20 -0
  104. package/build/src/core/verbs/arc.d.ts +2 -1
  105. package/build/src/core/verbs/arc.js +16 -0
  106. package/build/src/core/verbs/attestation.d.ts +2 -1
  107. package/build/src/core/verbs/attestation.js +16 -0
  108. package/build/src/core/verbs/bind.d.ts +2 -1
  109. package/build/src/core/verbs/bind.js +16 -0
  110. package/build/src/core/verbs/deliver.d.ts +2 -1
  111. package/build/src/core/verbs/deliver.js +16 -0
  112. package/build/src/core/verbs/placement.d.ts +2 -1
  113. package/build/src/core/verbs/placement.js +58 -1
  114. package/build/src/dispatch/association.d.ts +13 -0
  115. package/build/src/dispatch/association.js +20 -0
  116. package/build/src/dispatch/index.d.ts +6 -0
  117. package/build/src/dispatch/index.js +27 -3
  118. package/build/src/git/hooks.d.ts +9 -1
  119. package/build/src/git/hooks.js +79 -1
  120. package/build/src/git/nuke.d.ts +2 -1
  121. package/build/src/git/nuke.js +6 -11
  122. package/build/src/git/private-state-seat.d.ts +26 -1
  123. package/build/src/git/private-state-seat.js +78 -13
  124. package/build/src/git/process.d.ts +2 -0
  125. package/build/src/git/reconcile.d.ts +1 -2
  126. package/build/src/git/reconcile.js +0 -6
  127. package/build/src/git/repository.d.ts +0 -2
  128. package/build/src/git/repository.js +27 -25
  129. package/build/src/git/result-codec.d.ts +29 -0
  130. package/build/src/git/result-codec.js +306 -0
  131. package/build/src/git/target-placement.js +2 -8
  132. package/build/src/git/workspace.d.ts +2 -0
  133. package/build/src/git/workspace.js +4 -0
  134. package/build/src/index.d.ts +1 -0
  135. package/build/src/kanshi/fleet.js +1 -1
  136. package/build/src/kanshi/read.js +55 -28
  137. package/build/src/kanshi/report.d.ts +4 -3
  138. package/build/src/kanshi/select.js +14 -1
  139. package/build/src/library/address.d.ts +1 -0
  140. package/build/src/library/address.js +4 -7
  141. package/build/src/library/akuma-creation.d.ts +5 -3
  142. package/build/src/library/akuma-creation.js +90 -33
  143. package/build/src/library/audit.js +2 -1
  144. package/build/src/library/catalog.d.ts +10 -2
  145. package/build/src/library/catalog.js +65 -25
  146. package/build/src/library/composition.d.ts +1 -0
  147. package/build/src/library/composition.js +1 -0
  148. package/build/src/library/configuration.d.ts +4 -21
  149. package/build/src/library/configuration.js +2 -158
  150. package/build/src/library/continuation.d.ts +20 -1
  151. package/build/src/library/continuation.js +36 -0
  152. package/build/src/library/contract-bind.d.ts +1 -0
  153. package/build/src/library/contract-bind.js +16 -5
  154. package/build/src/library/contract-forwarding.d.ts +2 -2
  155. package/build/src/library/contract-forwarding.js +18 -4
  156. package/build/src/library/contract-handle.js +4 -3
  157. package/build/src/library/contract-operations.d.ts +5 -9
  158. package/build/src/library/contract-operations.js +34 -47
  159. package/build/src/library/contract.d.ts +11 -2
  160. package/build/src/library/contract.js +21 -1
  161. package/build/src/library/delivery.d.ts +4 -1
  162. package/build/src/library/delivery.js +47 -0
  163. package/build/src/library/fleet.d.ts +4 -136
  164. package/build/src/library/fleet.js +31 -315
  165. package/build/src/library/keiyaku.d.ts +7 -3
  166. package/build/src/library/keiyaku.js +1 -0
  167. package/build/src/library/mutation.d.ts +431 -3
  168. package/build/src/library/mutation.js +192 -19
  169. package/build/src/library/nuke.d.ts +7 -1
  170. package/build/src/library/nuke.js +18 -4
  171. package/build/src/library/reconcile.d.ts +14 -0
  172. package/build/src/library/reconcile.js +22 -8
  173. package/build/src/library/refusal.d.ts +9 -1
  174. package/build/src/library/refusal.js +76 -0
  175. package/build/src/library/region.d.ts +0 -8
  176. package/build/src/library/region.js +1 -29
  177. package/build/src/library/result-codec.d.ts +2 -0
  178. package/build/src/library/result-codec.js +12 -0
  179. package/build/src/markdown/lex.js +9 -2
  180. package/build/src/markdown/types.d.ts +2 -1
  181. package/build/src/markdown/types.js +3 -1
  182. package/build/src/plugin/akuma-signals.d.ts +12 -0
  183. package/build/src/plugin/akuma-signals.js +14 -0
  184. package/build/src/plugin/public.d.ts +51 -0
  185. package/build/src/plugin/public.js +1 -0
  186. package/build/src/plugin/runtime.d.ts +14 -0
  187. package/build/src/plugin/runtime.js +357 -0
  188. package/build/src/protocol/amend.js +3 -3
  189. package/build/src/protocol/attempt.d.ts +2 -1
  190. package/build/src/protocol/attempt.js +1 -1
  191. package/build/src/protocol/audit.d.ts +1 -1
  192. package/build/src/protocol/audit.js +1 -1
  193. package/build/src/protocol/bind.d.ts +3 -1
  194. package/build/src/protocol/bind.js +26 -0
  195. package/build/src/protocol/completion.js +0 -1
  196. package/build/src/protocol/deliver.d.ts +1 -1
  197. package/build/src/protocol/deliver.js +136 -57
  198. package/build/src/protocol/intent.d.ts +0 -1
  199. package/build/src/protocol/intent.js +0 -1
  200. package/build/src/protocol/operations.d.ts +9 -2
  201. package/build/src/protocol/operations.js +16 -1
  202. package/build/src/protocol/outcome.d.ts +3 -0
  203. package/build/src/protocol/outcome.js +17 -1
  204. package/build/src/protocol/placement.js +10 -3
  205. package/build/src/protocol/read/status.d.ts +8 -0
  206. package/build/src/protocol/read/status.js +49 -0
  207. package/build/src/protocol/reintegrate.js +10 -3
  208. package/build/src/protocol/result-codec.d.ts +22 -0
  209. package/build/src/protocol/result-codec.js +442 -0
  210. package/build/src/protocol/review.d.ts +1 -1
  211. package/build/src/protocol/review.js +81 -46
  212. package/build/src/protocol/run.d.ts +22 -2
  213. package/build/src/protocol/run.js +119 -29
  214. package/build/src/runtime/proc/lifecycle.js +1 -1
  215. package/build/src/runtime/proc/line-rpc.d.ts +7 -1
  216. package/build/src/runtime/proc/line-rpc.js +49 -9
  217. package/build/src/runtime/proc/run.d.ts +0 -1
  218. package/build/src/runtime/proc/run.js +1 -11
  219. package/build/src/runtime/proc/termination.d.ts +1 -0
  220. package/build/src/runtime/proc/termination.js +63 -18
  221. package/build/src/runtime/proc/windows-launch.exe +0 -0
  222. package/build/src/settings.d.ts +10 -0
  223. package/build/src/settings.js +88 -2
  224. package/build/src/settlement/result-codec.d.ts +2 -0
  225. package/build/src/settlement/result-codec.js +56 -0
  226. package/build/src/settlement/settle.d.ts +5 -12
  227. package/build/src/settlement/settle.js +60 -55
  228. package/build/src/task/board.d.ts +3 -0
  229. package/build/src/task/board.js +22 -4
  230. package/build/src/task/catalog.d.ts +13 -2
  231. package/build/src/task/catalog.js +59 -5
  232. package/build/src/task/compose.d.ts +4 -2
  233. package/build/src/task/compose.js +56 -30
  234. package/build/src/task/created-observation.d.ts +39 -0
  235. package/build/src/task/created-observation.js +26 -0
  236. package/build/src/task/identity.d.ts +6 -0
  237. package/build/src/task/identity.js +48 -7
  238. package/build/src/task/index.d.ts +4 -3
  239. package/build/src/task/index.js +19 -16
  240. package/build/src/task/input.d.ts +3 -1
  241. package/build/src/task/input.js +7 -4
  242. package/build/src/task/lifecycle-operations.d.ts +6 -0
  243. package/build/src/task/lifecycle-operations.js +116 -0
  244. package/build/src/task/mutation-result.d.ts +762 -20
  245. package/build/src/task/mutation-result.js +34 -9
  246. package/build/src/task/mutation.d.ts +4 -9
  247. package/build/src/task/mutation.js +17 -52
  248. package/build/src/task/operation-types.d.ts +114 -0
  249. package/build/src/task/operation-types.js +1 -0
  250. package/build/src/task/operations.d.ts +6 -113
  251. package/build/src/task/operations.js +75 -117
  252. package/build/src/task/query.d.ts +8 -11
  253. package/build/src/task/query.js +7 -14
  254. package/build/src/task/store.d.ts +11 -1
  255. package/build/src/task/store.js +169 -55
  256. package/build/src/task/view.d.ts +4 -0
  257. package/build/src/task/view.js +7 -0
  258. package/build/src/verification/declaration.d.ts +1 -0
  259. package/build/src/verification/declaration.js +18 -1
  260. package/build/src/verification/execution.d.ts +0 -1
  261. package/build/src/verification/execution.js +5 -5
  262. package/build/src/world.d.ts +0 -2
  263. package/build/src/world.js +3 -7
  264. package/package.json +17 -5
  265. package/build/src/cli/square-edge.d.ts +0 -7
  266. package/build/src/cli/square-edge.js +0 -159
  267. package/build/src/git/ref-migration.d.ts +0 -22
  268. package/build/src/git/ref-migration.js +0 -55
  269. package/build/src/library/contract-forwarding-reconciliation-result.d.ts +0 -102
  270. package/build/src/library/contract-forwarding-reconciliation-result.js +0 -92
  271. package/build/src/library/contract-forwarding-result.d.ts +0 -4270
  272. package/build/src/library/contract-forwarding-result.js +0 -521
@@ -1,16 +1,17 @@
1
1
  import { documentDiff } from "../markdown/diff.js";
2
- import { createTaskRelations, projectDetailFacts, projectTaskBoardObservation, relationProblem, projectBlocked, projectRows, } from "./board.js";
2
+ import { createTaskRelations, projectOwnedDetailFacts, projectTaskBoardObservation, relationProblem, projectBlocked, projectRows, } from "./board.js";
3
3
  import { parseTaskCreationDocument, serializeTaskDocument, } from "./document.js";
4
4
  import { allocateLocalId, deriveLocalStem, formatTaskId, parseTaskId, sameNamespace } from "./identity.js";
5
- import { authorityPath, nukeTaskAuthority, readBoard, replaceAuthority, withTaskLocks } from "./store.js";
6
- import { DEFAULT_TASK_LIMIT, projectPage, projectQuery, queryUnderTargets, underExpression, } from "./query.js";
5
+ import { nukeTaskAuthority, readBoard, readTaskDocument, replaceAuthority, withTaskLocks } from "./store.js";
6
+ import { projectBoundedList } from "../bounded-list.js";
7
+ import { taskRowViewLimit } from "./input.js";
8
+ import { projectQuery, projectQueryRows, queryUnderTargets, underExpression, } from "./query.js";
9
+ import { advanceTaskTimestamp, taskView } from "./view.js";
10
+ export { advanceTaskTimestamp, taskView } from "./view.js";
7
11
  export async function nukeTask(world, options) {
8
12
  if ((await nukeTaskAuthority(world, options)) === "busy")
9
13
  throw new Error("Task reset lock contention");
10
14
  }
11
- export function taskView(document) {
12
- return { ...document, namespace: parseTaskId(document.id).namespace };
13
- }
14
15
  function refused(refusal) {
15
16
  return { kind: "refused", refusal };
16
17
  }
@@ -27,9 +28,6 @@ function currentTimestamp() {
27
28
  return new Date().toISOString();
28
29
  }
29
30
  /** Internal Task timestamp rule shared by ordinary mutations and compose. */
30
- export function advanceTaskTimestamp(previous, candidate) {
31
- return candidate > previous ? candidate : new Date(Date.parse(previous) + 1).toISOString();
32
- }
33
31
  function addDocument(base, namespace, board, at, actor) {
34
32
  const localId = allocateLocalId(deriveLocalStem(base.title), occupied(board, namespace));
35
33
  return {
@@ -46,20 +44,30 @@ function boardWith(board, document) {
46
44
  return { tasks };
47
45
  }
48
46
  async function create(world, base, namespace, signal, actor) {
49
- const result = await withTaskLocks({ world, allocation: true, ids: [], ...(signal === undefined ? {} : { signal }) }, async () => {
50
- const snapshot = await readBoard(world), next = addDocument(base, namespace, snapshot.board, currentTimestamp(), actor);
51
- const problem = relationProblem(boardWith(snapshot.board, next), null, next);
52
- if (problem !== null)
53
- return refused({ kind: "invalid-graph", diagnostic: problem });
54
- const replaced = await replaceAuthority({
55
- path: authorityPath(world, next.id),
56
- expected: null,
57
- next: serializeTaskDocument(next),
47
+ let result;
48
+ try {
49
+ result = await withTaskLocks({ world, allocation: true, ids: [], ...(signal === undefined ? {} : { signal }) }, async () => {
50
+ const snapshot = await readBoard(world), next = addDocument(base, namespace, snapshot.board, currentTimestamp(), actor);
51
+ const problem = relationProblem(boardWith(snapshot.board, next), null, next);
52
+ if (problem !== null)
53
+ return refused({ kind: "invalid-graph", diagnostic: problem });
54
+ const replaced = await replaceAuthority({
55
+ world,
56
+ id: next.id,
57
+ expected: null,
58
+ next: serializeTaskDocument(next),
59
+ });
60
+ return replaced === "replaced"
61
+ ? { kind: "accepted", value: taskView(next) }
62
+ : retry("concurrent-modification");
58
63
  });
59
- return replaced === "replaced"
60
- ? { kind: "accepted", value: taskView(next) }
61
- : retry("concurrent-modification");
62
- });
64
+ }
65
+ catch (error) {
66
+ if (error instanceof TypeError &&
67
+ /task identity (?:cannot fit the physical filename budget|contains a Windows-reserved physical segment)/u.test(error.message))
68
+ return refused({ kind: "invalid-namespace-context", path: namespace.join("/") });
69
+ throw error;
70
+ }
63
71
  return result === "busy" ? retry("busy") : result;
64
72
  }
65
73
  export async function addTask(world, input) {
@@ -137,8 +145,7 @@ export async function updateTask(world, id, input) {
137
145
  const afterBytes = serializeTaskDocument(next);
138
146
  const after = Buffer.from(afterBytes).toString("utf8");
139
147
  if (before !== after &&
140
- (await replaceAuthority({ path: authorityPath(world, id), expected: predecessor, next: afterBytes })) !==
141
- "replaced") {
148
+ (await replaceAuthority({ world, id, expected: predecessor, next: afterBytes })) !== "replaced") {
142
149
  return { kind: "retry", reason: "concurrent-modification" };
143
150
  }
144
151
  const label = `${id}.md`;
@@ -149,98 +156,48 @@ export async function updateTask(world, id, input) {
149
156
  });
150
157
  return result === "busy" ? { kind: "retry", reason: "busy" } : result;
151
158
  }
152
- const TRANSITIONS = {
153
- start: { open: "in_progress" },
154
- stop: { in_progress: "open" },
155
- hold: { open: "on_hold", in_progress: "on_hold" },
156
- resume: { on_hold: "open" },
157
- done: { open: "done", in_progress: "done", on_hold: "done" },
158
- drop: { open: "drop", in_progress: "drop", on_hold: "drop" },
159
- };
160
- export async function lifecycleTask(world, id, verb, signal, note) {
161
- const result = await withTaskLocks({ world, allocation: false, ids: [id], ...(signal === undefined ? {} : { signal }) }, async () => {
162
- const snapshot = await readBoard(world), current = snapshot.board.tasks.get(id);
163
- if (current === undefined)
164
- return refused({ kind: "task-missing", taskId: id });
165
- const state = TRANSITIONS[verb][current.state];
166
- if (state === undefined) {
167
- return refused({ kind: "invalid-lifecycle-transition", taskId: id, state: current.state, verb });
168
- }
169
- const at = currentTimestamp();
170
- const next = {
171
- ...current,
172
- state,
173
- ...(note === undefined ? {} : { note }),
174
- updatedAt: advanceTaskTimestamp(current.updatedAt, at),
175
- };
176
- const bytes = serializeTaskDocument(next);
177
- return (await replaceAuthority({
178
- path: authorityPath(world, id),
179
- expected: snapshot.bytes.get(id),
180
- next: bytes,
181
- })) === "replaced"
182
- ? { kind: "accepted", value: taskView(next) }
183
- : retry("concurrent-modification");
184
- });
185
- return result === "busy" ? retry("busy") : result;
186
- }
187
- export async function batchTasks(world, verb, ids, signal, note) {
188
- const items = [];
189
- for (const id of ids) {
190
- signal?.throwIfAborted();
191
- items.push({ id, outcome: await lifecycleTask(world, id, verb, signal, note) });
192
- }
193
- return { items };
194
- }
195
- export async function settleTask(world, id) {
196
- const result = await withTaskLocks({ world, allocation: false, ids: [id] }, async () => {
197
- const snapshot = await readBoard(world), current = snapshot.board.tasks.get(id);
198
- if (current === undefined)
199
- return { kind: "refused", refusal: { kind: "task-missing", taskId: id } };
200
- if (current.state === "done")
201
- return { kind: "unchanged" };
202
- if (current.state === "drop") {
203
- return {
204
- kind: "refused",
205
- refusal: { kind: "invalid-lifecycle-transition", taskId: id, state: current.state, verb: "done" },
206
- };
207
- }
208
- const at = currentTimestamp();
209
- const next = {
210
- ...current,
211
- state: "done",
212
- updatedAt: advanceTaskTimestamp(current.updatedAt, at),
213
- };
214
- const replaced = await replaceAuthority({
215
- path: authorityPath(world, id),
216
- expected: snapshot.bytes.get(id),
217
- next: serializeTaskDocument(next),
218
- });
219
- return replaced === "replaced"
220
- ? { kind: "changed", task: taskView(next), action: "done" }
221
- : { kind: "retry", reason: "concurrent-modification" };
222
- });
223
- return result === "busy" ? { kind: "retry", reason: "busy" } : result;
224
- }
159
+ export { batchTasks, lifecycleTask, settleTask } from "./lifecycle-operations.js";
225
160
  function readScope(namespace, scope) {
226
161
  return scope === "world" ? null : (namespace ?? []);
227
162
  }
228
- export async function listTasks(world, namespace, selection, scope, limit = DEFAULT_TASK_LIMIT) {
163
+ export async function listTasks(world, namespace, selection, scope, limit) {
164
+ const selectedLimit = taskRowViewLimit(limit);
229
165
  const selected = readScope(namespace, scope);
230
166
  const board = (await readBoard(world)).board;
231
167
  return {
232
168
  kind: "accepted",
233
- value: projectPage(projectRows(board, createTaskRelations(board), selected, selection), limit),
169
+ value: projectBoundedList(projectRows(board, createTaskRelations(board), selected, selection), selectedLimit),
234
170
  };
235
171
  }
172
+ export async function readTaskDetail(world, id) {
173
+ const task = await readTaskDocument(world, id);
174
+ if (task === undefined)
175
+ return null;
176
+ const selected = new Map([[id, task]]);
177
+ const references = [
178
+ ...task.needs,
179
+ ...(task.parent === null ? [] : [task.parent]),
180
+ ...task.supersedes,
181
+ ...task.relates,
182
+ ];
183
+ for (const reference of references) {
184
+ if (selected.has(reference))
185
+ continue;
186
+ const document = await readTaskDocument(world, reference);
187
+ if (document !== undefined)
188
+ selected.set(reference, document);
189
+ }
190
+ return projectOwnedDetailFacts({ tasks: selected }, id);
191
+ }
236
192
  export async function readTaskDetails(world, ids) {
237
- const board = (await readBoard(world)).board;
238
- const relations = createTaskRelations(board);
239
- const details = ids.map((id) => projectDetailFacts(board, id, relations));
240
- const missing = details.findIndex((detail) => detail === null);
241
- return missing < 0
242
- ? { kind: "accepted", value: details }
243
- : { kind: "refused", refusal: { kind: "task-missing", taskId: ids[missing] } };
193
+ const details = [];
194
+ for (const id of ids) {
195
+ const detail = await readTaskDetail(world, id);
196
+ if (detail === null)
197
+ return { kind: "refused", refusal: { kind: "task-missing", taskId: id } };
198
+ details.push(detail);
199
+ }
200
+ return { kind: "accepted", value: details };
244
201
  }
245
202
  export async function observeTaskDetails(world, ids) {
246
203
  const observed = await readTaskDetails(world, ids);
@@ -248,7 +205,8 @@ export async function observeTaskDetails(world, ids) {
248
205
  return observed;
249
206
  return { kind: "accepted", value: observed.value.map((facts) => ({ ...facts, task: taskView(facts.task) })) };
250
207
  }
251
- export async function readyTasks(world, namespace, scope, parent, limit = DEFAULT_TASK_LIMIT) {
208
+ export async function readyTasks(world, namespace, scope, parent, limit) {
209
+ const selectedLimit = taskRowViewLimit(limit);
252
210
  const selected = readScope(namespace, scope);
253
211
  const board = (await readBoard(world)).board;
254
212
  if (parent !== undefined && !board.tasks.has(parent))
@@ -256,15 +214,15 @@ export async function readyTasks(world, namespace, scope, parent, limit = DEFAUL
256
214
  const relations = createTaskRelations(board);
257
215
  const ready = { kind: "predicate", predicate: { field: "ready", operator: "=", value: true } };
258
216
  const expression = parent === undefined ? ready : { kind: "and", terms: [ready, underExpression(parent)] };
259
- const selectedRows = projectQuery(board, relations, {
217
+ const selectedRows = projectQueryRows(board, relations, {
260
218
  scope: selected,
261
219
  expression,
262
- limit: Math.max(1, board.tasks.size),
263
- }).rows;
220
+ });
264
221
  const rows = selectedRows.map(({ parent: _parent, needs: _needs, blocks: _blocks, createdAt: _createdAt, ...row }) => row);
265
- return { kind: "accepted", value: projectPage(rows, limit) };
222
+ return { kind: "accepted", value: projectBoundedList(rows, selectedLimit) };
266
223
  }
267
- export async function blockedTasks(world, namespace, scope, parent, limit = DEFAULT_TASK_LIMIT) {
224
+ export async function blockedTasks(world, namespace, scope, parent, limit) {
225
+ const selectedLimit = taskRowViewLimit(limit);
268
226
  const selected = readScope(namespace, scope);
269
227
  const board = (await readBoard(world)).board;
270
228
  if (parent !== undefined && !board.tasks.has(parent))
@@ -275,18 +233,18 @@ export async function blockedTasks(world, namespace, scope, parent, limit = DEFA
275
233
  predicate: { field: "blocked", operator: "=", value: true },
276
234
  };
277
235
  const expression = parent === undefined ? blocked : { kind: "and", terms: [blocked, underExpression(parent)] };
278
- const selectedRows = projectQuery(board, relations, {
236
+ const selectedRows = projectQueryRows(board, relations, {
279
237
  scope: selected,
280
238
  expression,
281
- limit: Math.max(1, board.tasks.size),
282
- }).rows;
239
+ });
283
240
  const ids = new Set(selectedRows.map((row) => row.id));
284
241
  return {
285
242
  kind: "accepted",
286
- value: projectPage(projectBlocked(board, selected, relations).filter((row) => ids.has(row.id)), limit),
243
+ value: projectBoundedList(projectBlocked(board, selected, relations).filter((row) => ids.has(row.id)), selectedLimit),
287
244
  };
288
245
  }
289
246
  export async function queryTasks(input) {
247
+ const selectedLimit = taskRowViewLimit(input.limit);
290
248
  const selected = readScope(input.namespace, input.scope);
291
249
  const board = (await readBoard(input.world)).board;
292
250
  const relations = createTaskRelations(board);
@@ -300,7 +258,7 @@ export async function queryTasks(input) {
300
258
  scope: selected,
301
259
  expression: input.expression,
302
260
  sort: input.sort ?? "priority",
303
- limit: input.limit ?? DEFAULT_TASK_LIMIT,
261
+ limit: selectedLimit,
304
262
  }),
305
263
  };
306
264
  }
@@ -1,8 +1,7 @@
1
1
  import type { TaskPriority, TaskState } from "./document.js";
2
2
  import { type TaskId } from "./identity.js";
3
3
  import type { BlockedTaskRow, TaskBoard, TaskRef, TaskRelationProjection, TaskRow } from "./board.js";
4
- export declare const DEFAULT_TASK_LIMIT = 100;
5
- export declare const MAX_TASK_LIMIT = 1000;
4
+ import { type BoundedList } from "../bounded-list.js";
6
5
  export declare const TASK_RELATION_PREDICATE_FIELDS: readonly ["under", "needs", "blocks"];
7
6
  export type TaskRelationPredicateField = (typeof TASK_RELATION_PREDICATE_FIELDS)[number];
8
7
  export type TaskQueryComparison = "=" | "!=" | "<" | "<=" | ">" | ">=" | "~";
@@ -53,22 +52,20 @@ export type TaskQueryRow = TaskRow & Readonly<{
53
52
  createdAt: string;
54
53
  updatedAt: string;
55
54
  }>;
56
- export type TaskPage<Row> = Readonly<{
57
- rows: readonly Row[];
58
- total: number;
59
- returned: number;
60
- truncated: boolean;
61
- }>;
55
+ export type TaskPage<Row> = BoundedList<Row>;
62
56
  export declare function normalizeTaskQuery(value: unknown): TaskQueryExpression;
57
+ export declare function projectQueryRows(board: TaskBoard, relations: TaskRelationProjection, input: Readonly<{
58
+ scope: readonly string[] | null;
59
+ expression: TaskQueryExpression;
60
+ sort?: TaskQuerySort;
61
+ }>): readonly TaskQueryRow[];
63
62
  export declare function projectQuery(board: TaskBoard, relations: TaskRelationProjection, input: Readonly<{
64
63
  scope: readonly string[] | null;
65
64
  expression: TaskQueryExpression;
66
65
  sort?: TaskQuerySort;
67
- limit?: number;
66
+ limit: number;
68
67
  }>): TaskPage<TaskQueryRow>;
69
- export declare function projectPage<Row>(rows: readonly Row[], limit?: number): TaskPage<Row>;
70
68
  export declare function underExpression(parent: TaskId): TaskQueryExpression;
71
69
  export declare function queryUnderTargets(expression: TaskQueryExpression): readonly TaskId[];
72
- export declare function isValidTaskLimit(value: number): boolean;
73
70
  export type TaskQueryPage = TaskPage<TaskQueryRow>;
74
71
  export type TaskBlockedPage = TaskPage<BlockedTaskRow>;
@@ -1,7 +1,6 @@
1
1
  import { formatTaskId, parseTaskId, sameNamespace } from "./identity.js";
2
2
  import { projectTaskRow, taskBlocked, taskDisposition, taskRef } from "./board.js";
3
- export const DEFAULT_TASK_LIMIT = 100;
4
- export const MAX_TASK_LIMIT = 1_000;
3
+ import { projectBoundedList } from "../bounded-list.js";
5
4
  export const TASK_RELATION_PREDICATE_FIELDS = ["under", "needs", "blocks"];
6
5
  function isTaskRelationPredicateField(value) {
7
6
  return TASK_RELATION_PREDICATE_FIELDS.includes(value);
@@ -242,18 +241,15 @@ function sortTasks(tasks, sort) {
242
241
  return (sort === "updated" ? -compared : compared) || tie;
243
242
  });
244
243
  }
245
- export function projectQuery(board, relations, input) {
246
- const { scope, expression, sort = "priority", limit = DEFAULT_TASK_LIMIT } = input;
244
+ export function projectQueryRows(board, relations, input) {
245
+ const { scope, expression, sort = "priority" } = input;
247
246
  const under = new Map(queryUnderTargets(expression).map((target) => [target, descendants(relations, target)]));
248
- const selected = sortTasks([...board.tasks.values()]
247
+ return sortTasks([...board.tasks.values()]
249
248
  .filter((task) => scope === null || sameNamespace(parseTaskId(task.id).namespace, scope))
250
- .filter((task) => matches(board, relations, task, expression, under)), sort);
251
- const rows = selected.slice(0, limit).map((task) => row(board, relations, task));
252
- return { rows, total: selected.length, returned: rows.length, truncated: rows.length < selected.length };
249
+ .filter((task) => matches(board, relations, task, expression, under)), sort).map((task) => row(board, relations, task));
253
250
  }
254
- export function projectPage(rows, limit = DEFAULT_TASK_LIMIT) {
255
- const visible = rows.slice(0, limit);
256
- return { rows: visible, total: rows.length, returned: visible.length, truncated: visible.length < rows.length };
251
+ export function projectQuery(board, relations, input) {
252
+ return projectBoundedList(projectQueryRows(board, relations, input), input.limit);
257
253
  }
258
254
  export function underExpression(parent) {
259
255
  return { kind: "predicate", predicate: { field: "under", operator: "=", value: parent } };
@@ -271,6 +267,3 @@ export function queryUnderTargets(expression) {
271
267
  collect(expression);
272
268
  return [...targets];
273
269
  }
274
- export function isValidTaskLimit(value) {
275
- return Number.isInteger(value) && value > 0 && value <= MAX_TASK_LIMIT;
276
- }
@@ -1,4 +1,6 @@
1
1
  import type { WorldRoot } from "../world.js";
2
+ import { type BoundedList } from "../bounded-list.js";
3
+ import { type TaskDocument } from "./document.js";
2
4
  import { type TaskId } from "./identity.js";
3
5
  import type { TaskBoard } from "./board.js";
4
6
  export type BoardSnapshot = Readonly<{
@@ -7,11 +9,19 @@ export type BoardSnapshot = Readonly<{
7
9
  }>;
8
10
  export declare const DEFAULT_TASK_LOCK_TIMEOUT_MS = 3000;
9
11
  export declare function readBoard(world: WorldRoot): Promise<BoardSnapshot>;
12
+ export declare function readRecentTaskDocuments(world: WorldRoot, input: Readonly<{
13
+ namespace?: readonly string[];
14
+ selection?: "all" | "active";
15
+ limit?: number;
16
+ }>): Promise<BoundedList<TaskDocument>>;
17
+ export declare function readTaskDocument(world: WorldRoot, id: TaskId): Promise<TaskDocument | undefined>;
10
18
  export declare function replaceAuthority(input: Readonly<{
11
- path: string;
19
+ world: WorldRoot;
20
+ id: TaskId;
12
21
  expected: Uint8Array | null;
13
22
  next: Uint8Array;
14
23
  }>): Promise<"replaced" | "concurrent-modification">;
24
+ export declare function authorityBytesMatch(world: WorldRoot, id: TaskId, expected: Uint8Array | null): Promise<boolean>;
15
25
  export declare function nukeTaskAuthority(world: WorldRoot, options?: Readonly<{
16
26
  timeoutMs?: number;
17
27
  }>): Promise<void | "busy">;