@astrosheep/keiyaku 4.0.0 → 4.0.2

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 (308) hide show
  1. package/README.md +133 -8
  2. package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +2 -2
  3. package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +4 -4
  4. package/build/integrations/marketplace/plugins/keiyaku/opencode.js +2 -2
  5. package/build/integrations/marketplace/plugins/keiyaku/package.json +2 -2
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +13 -5
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +91 -32
  8. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +134 -0
  9. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/agents/openai.yaml +4 -0
  10. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +41 -6
  11. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +262 -46
  12. package/build/src/akuma/abort.d.ts +2 -0
  13. package/build/src/akuma/abort.js +50 -0
  14. package/build/src/akuma/akuma.d.ts +50 -33
  15. package/build/src/akuma/akuma.js +175 -127
  16. package/build/src/akuma/archetype.d.ts +14 -5
  17. package/build/src/akuma/archetype.js +85 -39
  18. package/build/src/akuma/body.d.ts +3 -5
  19. package/build/src/akuma/body.js +490 -183
  20. package/build/src/akuma/coordinate.d.ts +9 -0
  21. package/build/src/akuma/coordinate.js +22 -0
  22. package/build/src/akuma/heart/facts.d.ts +88 -45
  23. package/build/src/akuma/heart/facts.js +19 -8
  24. package/build/src/akuma/heart/index.d.ts +64 -55
  25. package/build/src/akuma/heart/index.js +172 -252
  26. package/build/src/akuma/heart/rows.d.ts +38 -83
  27. package/build/src/akuma/heart/rows.js +117 -155
  28. package/build/src/akuma/heart/schema.d.ts +1 -1
  29. package/build/src/akuma/heart/schema.js +61 -22
  30. package/build/src/akuma/heart/soul.d.ts +8 -0
  31. package/build/src/akuma/heart/soul.js +136 -0
  32. package/build/src/akuma/heart/storage.d.ts +47 -0
  33. package/build/src/akuma/heart/storage.js +224 -0
  34. package/build/src/akuma/heart/tells.d.ts +12 -0
  35. package/build/src/akuma/heart/tells.js +79 -0
  36. package/build/src/akuma/heart/timeline.d.ts +15 -0
  37. package/build/src/akuma/heart/timeline.js +86 -0
  38. package/build/src/akuma/identity.d.ts +2 -2
  39. package/build/src/akuma/identity.js +9 -9
  40. package/build/src/akuma/index.d.ts +10 -3
  41. package/build/src/akuma/index.js +7 -1
  42. package/build/src/akuma/projection.d.ts +176 -0
  43. package/build/src/akuma/projection.js +256 -0
  44. package/build/src/akuma/provider-recipe.d.ts +24 -0
  45. package/build/src/akuma/provider-recipe.js +100 -0
  46. package/build/src/akuma/provider.d.ts +67 -13
  47. package/build/src/akuma/provider.js +172 -105
  48. package/build/src/akuma/providers/acp/core.d.ts +19 -0
  49. package/build/src/akuma/providers/acp/core.js +159 -0
  50. package/build/src/akuma/providers/acp/events.d.ts +20 -0
  51. package/build/src/akuma/providers/acp/events.js +73 -0
  52. package/build/src/akuma/providers/acp/index.d.ts +12 -0
  53. package/build/src/akuma/providers/acp/index.js +94 -0
  54. package/build/src/akuma/providers/{claude.d.ts → claude/events.d.ts} +9 -41
  55. package/build/src/akuma/providers/claude/events.js +238 -0
  56. package/build/src/akuma/providers/claude/index.d.ts +47 -0
  57. package/build/src/akuma/providers/claude/index.js +279 -0
  58. package/build/src/akuma/providers/claude/input.d.ts +13 -0
  59. package/build/src/akuma/providers/claude/input.js +109 -0
  60. package/build/src/akuma/providers/codex-app-server/events.d.ts +1 -1
  61. package/build/src/akuma/providers/codex-app-server/events.js +15 -12
  62. package/build/src/akuma/providers/codex-app-server/index.d.ts +15 -13
  63. package/build/src/akuma/providers/codex-app-server/index.js +77 -33
  64. package/build/src/akuma/providers/grok-build/index.d.ts +4 -0
  65. package/build/src/akuma/providers/grok-build/index.js +70 -0
  66. package/build/src/akuma/providers/index.d.ts +5 -3
  67. package/build/src/akuma/providers/index.js +35 -56
  68. package/build/src/akuma/providers/opencode-sdk/events.d.ts +54 -0
  69. package/build/src/akuma/providers/opencode-sdk/events.js +235 -0
  70. package/build/src/akuma/providers/opencode-sdk/index.d.ts +33 -0
  71. package/build/src/akuma/providers/opencode-sdk/index.js +308 -0
  72. package/build/src/akuma/providers/opencode-sdk/session.d.ts +26 -0
  73. package/build/src/akuma/providers/opencode-sdk/session.js +63 -0
  74. package/build/src/akuma/providers/pi/events.d.ts +33 -0
  75. package/build/src/akuma/providers/pi/events.js +166 -0
  76. package/build/src/akuma/providers/pi/index.d.ts +11 -0
  77. package/build/src/akuma/providers/pi/index.js +191 -0
  78. package/build/src/akuma/publication.d.ts +3 -3
  79. package/build/src/akuma/publication.js +28 -40
  80. package/build/src/akuma/requests.d.ts +9 -6
  81. package/build/src/akuma/requests.js +95 -65
  82. package/build/src/alias/index.d.ts +4 -3
  83. package/build/src/alias/index.js +12 -13
  84. package/build/src/body/decode.js +7 -1
  85. package/build/src/body/region.d.ts +2 -0
  86. package/build/src/body/region.js +77 -7
  87. package/build/src/body/render.js +2 -1
  88. package/build/src/body/shape.js +7 -1
  89. package/build/src/body/verification.js +19 -4
  90. package/build/src/cli/accepted.d.ts +18 -12
  91. package/build/src/cli/accepted.js +73 -34
  92. package/build/src/cli/actor.js +3 -3
  93. package/build/src/cli/commands/akuma-invoke.d.ts +44 -19
  94. package/build/src/cli/commands/akuma-invoke.js +101 -52
  95. package/build/src/cli/commands/akuma.d.ts +27 -9
  96. package/build/src/cli/commands/akuma.js +151 -80
  97. package/build/src/cli/commands/contract.d.ts +155 -0
  98. package/build/src/cli/commands/contract.js +20 -0
  99. package/build/src/cli/commands/install.js +2 -0
  100. package/build/src/cli/commands/task-invoke.d.ts +19 -4
  101. package/build/src/cli/commands/task-invoke.js +65 -17
  102. package/build/src/cli/commands/task-query.d.ts +5 -0
  103. package/build/src/cli/commands/task-query.js +247 -0
  104. package/build/src/cli/commands/task.d.ts +3 -1
  105. package/build/src/cli/commands/task.js +52 -14
  106. package/build/src/cli/coordinates.d.ts +18 -0
  107. package/build/src/cli/coordinates.js +120 -0
  108. package/build/src/cli/draft.d.ts +8 -0
  109. package/build/src/cli/draft.js +96 -0
  110. package/build/src/cli/invoke.d.ts +9 -3
  111. package/build/src/cli/invoke.js +287 -108
  112. package/build/src/cli/main.js +54 -7
  113. package/build/src/cli/parse.d.ts +21 -117
  114. package/build/src/cli/parse.js +79 -84
  115. package/build/src/cli/render/akuma-tool-command.d.ts +6 -0
  116. package/build/src/cli/render/akuma-tool-command.js +144 -0
  117. package/build/src/cli/render/akuma-tool.d.ts +4 -2
  118. package/build/src/cli/render/akuma-tool.js +35 -5
  119. package/build/src/cli/render/akuma.d.ts +3 -1
  120. package/build/src/cli/render/akuma.js +247 -212
  121. package/build/src/cli/render/audit.d.ts +3 -0
  122. package/build/src/cli/render/audit.js +104 -0
  123. package/build/src/cli/render/catalog.d.ts +2 -0
  124. package/build/src/cli/render/catalog.js +16 -0
  125. package/build/src/cli/render/contract.d.ts +3 -3
  126. package/build/src/cli/render/contract.js +200 -54
  127. package/build/src/cli/render/kanshi.js +272 -129
  128. package/build/src/cli/render/receipt.d.ts +19 -0
  129. package/build/src/cli/render/receipt.js +106 -0
  130. package/build/src/cli/render/refusal.d.ts +16 -2
  131. package/build/src/cli/render/refusal.js +88 -3
  132. package/build/src/cli/render/region.d.ts +2 -0
  133. package/build/src/cli/render/region.js +17 -0
  134. package/build/src/cli/render/task.d.ts +2 -1
  135. package/build/src/cli/render/task.js +223 -60
  136. package/build/src/cli/render/terminal.d.ts +20 -0
  137. package/build/src/cli/render/terminal.js +121 -0
  138. package/build/src/cli/render/text.js +11 -3
  139. package/build/src/cli/result.d.ts +126 -19
  140. package/build/src/cli/usage.d.ts +1 -0
  141. package/build/src/cli/usage.js +3 -0
  142. package/build/src/contract-worktree.d.ts +44 -0
  143. package/build/src/contract-worktree.js +251 -0
  144. package/build/src/coordination/durable-file.d.ts +5 -1
  145. package/build/src/coordination/durable-file.js +57 -10
  146. package/build/src/coordination/sqlite-transaction-lock.d.ts +4 -0
  147. package/build/src/coordination/sqlite-transaction-lock.js +22 -5
  148. package/build/src/core/facts/codec.js +23 -4
  149. package/build/src/core/facts/eligibility.d.ts +1 -10
  150. package/build/src/core/facts/eligibility.js +0 -49
  151. package/build/src/core/facts/fold.js +1 -6
  152. package/build/src/core/facts/gate.d.ts +1 -0
  153. package/build/src/core/facts/gate.js +1 -0
  154. package/build/src/core/facts/observation.d.ts +3 -0
  155. package/build/src/core/facts/observation.js +12 -0
  156. package/build/src/core/facts/types.d.ts +10 -3
  157. package/build/src/core/subject.js +2 -2
  158. package/build/src/core/verbs/amend.d.ts +1 -1
  159. package/build/src/core/verbs/amend.js +3 -18
  160. package/build/src/core/verbs/bind.js +2 -16
  161. package/build/src/core/verbs/deliver.d.ts +1 -1
  162. package/build/src/core/verbs/deliver.js +14 -4
  163. package/build/src/core/verbs/placement.d.ts +1 -1
  164. package/build/src/core/verbs/placement.js +7 -9
  165. package/build/src/dispatch/index.d.ts +5 -3
  166. package/build/src/dispatch/index.js +30 -21
  167. package/build/src/duration.d.ts +10 -0
  168. package/build/src/duration.js +22 -0
  169. package/build/src/git/admission.d.ts +2 -2
  170. package/build/src/git/admission.js +33 -23
  171. package/build/src/git/hooks.d.ts +15 -0
  172. package/build/src/git/hooks.js +70 -18
  173. package/build/src/git/identity.d.ts +5 -1
  174. package/build/src/git/identity.js +23 -4
  175. package/build/src/git/integration.d.ts +48 -0
  176. package/build/src/git/integration.js +250 -0
  177. package/build/src/git/observe.d.ts +29 -15
  178. package/build/src/git/observe.js +185 -76
  179. package/build/src/git/read-observation.d.ts +41 -0
  180. package/build/src/git/read-observation.js +361 -0
  181. package/build/src/git/reconcile.d.ts +17 -5
  182. package/build/src/git/reconcile.js +305 -109
  183. package/build/src/git/repository.d.ts +41 -18
  184. package/build/src/git/repository.js +220 -114
  185. package/build/src/git/scratch.d.ts +17 -0
  186. package/build/src/git/scratch.js +73 -0
  187. package/build/src/git/target-placement.d.ts +92 -0
  188. package/build/src/git/target-placement.js +375 -0
  189. package/build/src/git/tender.d.ts +49 -0
  190. package/build/src/git/tender.js +63 -0
  191. package/build/src/git/terminal-seal.d.ts +24 -0
  192. package/build/src/git/terminal-seal.js +89 -0
  193. package/build/src/git/tree.d.ts +2 -2
  194. package/build/src/git/tree.js +4 -0
  195. package/build/src/git/workspace.d.ts +53 -0
  196. package/build/src/git/workspace.js +139 -0
  197. package/build/src/identity/selector.d.ts +6 -0
  198. package/build/src/identity/selector.js +19 -0
  199. package/build/src/index.d.ts +4 -2
  200. package/build/src/index.js +2 -1
  201. package/build/src/kanshi/index.d.ts +2 -2
  202. package/build/src/kanshi/index.js +1 -1
  203. package/build/src/kanshi/read.d.ts +7 -3
  204. package/build/src/kanshi/read.js +245 -45
  205. package/build/src/kanshi/report.d.ts +81 -6
  206. package/build/src/kanshi/select.d.ts +5 -0
  207. package/build/src/kanshi/select.js +33 -1
  208. package/build/src/library/address.d.ts +57 -0
  209. package/build/src/library/address.js +165 -0
  210. package/build/src/library/akuma-creation.d.ts +16 -7
  211. package/build/src/library/akuma-creation.js +96 -22
  212. package/build/src/library/audit.d.ts +18 -0
  213. package/build/src/library/audit.js +44 -0
  214. package/build/src/library/bind.d.ts +21 -0
  215. package/build/src/library/bind.js +56 -0
  216. package/build/src/library/catalog.d.ts +58 -0
  217. package/build/src/library/catalog.js +69 -0
  218. package/build/src/library/configuration.d.ts +6 -15
  219. package/build/src/library/configuration.js +14 -17
  220. package/build/src/library/contract.d.ts +23 -49
  221. package/build/src/library/contract.js +171 -185
  222. package/build/src/library/delivery.d.ts +24 -0
  223. package/build/src/library/delivery.js +21 -0
  224. package/build/src/library/fleet.d.ts +65 -0
  225. package/build/src/library/fleet.js +153 -0
  226. package/build/src/library/input.d.ts +3 -0
  227. package/build/src/library/input.js +19 -0
  228. package/build/src/library/keiyaku.d.ts +18 -3
  229. package/build/src/library/keiyaku.js +12 -1
  230. package/build/src/library/mutation.d.ts +39 -0
  231. package/build/src/library/mutation.js +37 -0
  232. package/build/src/library/reconcile.d.ts +29 -0
  233. package/build/src/library/reconcile.js +179 -0
  234. package/build/src/library/refusal.d.ts +21 -0
  235. package/build/src/library/refusal.js +29 -0
  236. package/build/src/library/region.d.ts +14 -1
  237. package/build/src/library/region.js +18 -4
  238. package/build/src/library/repo.d.ts +4 -13
  239. package/build/src/library/repo.js +14 -24
  240. package/build/src/protocol/attempt.d.ts +16 -3
  241. package/build/src/protocol/attempt.js +41 -10
  242. package/build/src/protocol/bind.d.ts +9 -2
  243. package/build/src/protocol/bind.js +48 -40
  244. package/build/src/protocol/intent.d.ts +57 -20
  245. package/build/src/protocol/intent.js +55 -79
  246. package/build/src/protocol/operations.d.ts +152 -43
  247. package/build/src/protocol/operations.js +482 -166
  248. package/build/src/protocol/outcome.d.ts +14 -3
  249. package/build/src/protocol/outcome.js +11 -3
  250. package/build/src/protocol/placement.d.ts +41 -0
  251. package/build/src/protocol/placement.js +147 -0
  252. package/build/src/protocol/read/documents.d.ts +2 -2
  253. package/build/src/protocol/read/documents.js +4 -4
  254. package/build/src/protocol/read/status.d.ts +18 -5
  255. package/build/src/protocol/read/status.js +73 -13
  256. package/build/src/protocol/run.d.ts +49 -7
  257. package/build/src/protocol/run.js +53 -25
  258. package/build/src/runtime/proc/line-rpc.d.ts +4 -8
  259. package/build/src/runtime/proc/line-rpc.js +22 -28
  260. package/build/src/runtime/proc/run.d.ts +23 -21
  261. package/build/src/runtime/proc/run.js +123 -89
  262. package/build/src/runtime/proc/stdio.d.ts +18 -0
  263. package/build/src/runtime/proc/stdio.js +58 -0
  264. package/build/src/settings.d.ts +7 -1
  265. package/build/src/settings.js +32 -17
  266. package/build/src/settlement/fence.d.ts +5 -0
  267. package/build/src/settlement/fence.js +14 -0
  268. package/build/src/settlement/holder.d.ts +35 -4
  269. package/build/src/settlement/holder.js +127 -28
  270. package/build/src/settlement/settle.d.ts +9 -1
  271. package/build/src/settlement/settle.js +74 -37
  272. package/build/src/task/board.d.ts +23 -5
  273. package/build/src/task/board.js +17 -10
  274. package/build/src/task/compose.d.ts +2 -2
  275. package/build/src/task/compose.js +18 -10
  276. package/build/src/task/context.d.ts +3 -3
  277. package/build/src/task/context.js +15 -20
  278. package/build/src/task/document.d.ts +2 -1
  279. package/build/src/task/document.js +15 -5
  280. package/build/src/task/index.d.ts +27 -15
  281. package/build/src/task/index.js +57 -35
  282. package/build/src/task/operations.d.ts +38 -13
  283. package/build/src/task/operations.js +80 -46
  284. package/build/src/task/query.d.ts +67 -0
  285. package/build/src/task/query.js +279 -0
  286. package/build/src/task/store.d.ts +5 -7
  287. package/build/src/task/store.js +43 -28
  288. package/build/src/verification/declaration.d.ts +1 -0
  289. package/build/src/verification/execution.d.ts +51 -0
  290. package/build/src/verification/execution.js +108 -0
  291. package/build/src/workspace-place.d.ts +41 -0
  292. package/build/src/workspace-place.js +386 -0
  293. package/build/src/world.d.ts +24 -0
  294. package/build/src/world.js +136 -0
  295. package/package.json +8 -4
  296. package/build/src/akuma/activity.d.ts +0 -66
  297. package/build/src/akuma/activity.js +0 -139
  298. package/build/src/akuma/providers/claude.js +0 -305
  299. package/build/src/context-root.d.ts +0 -4
  300. package/build/src/context-root.js +0 -15
  301. package/build/src/git/delivery.d.ts +0 -20
  302. package/build/src/git/delivery.js +0 -109
  303. package/build/src/git/verification.d.ts +0 -14
  304. package/build/src/git/verification.js +0 -56
  305. package/build/src/protocol/read/audit.d.ts +0 -25
  306. package/build/src/protocol/read/audit.js +0 -39
  307. package/build/src/verification/producer.d.ts +0 -23
  308. package/build/src/verification/producer.js +0 -54
@@ -1,6 +1,6 @@
1
- import { lstatSync, mkdirSync, readFileSync, } from "node:fs";
1
+ import { lstat, mkdir, readFile } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
- import { replaceFileDurably } from "../coordination/durable-file.js";
3
+ import { repairDerivedFile, replaceFileDurably } from "../coordination/durable-file.js";
4
4
  import { normalizeIdentityStem } from "../identity/normalize.js";
5
5
  function directory(root) { return join(root, ".keiyaku", "namespace"); }
6
6
  function currentPath(root) { return join(directory(root), "current"); }
@@ -10,13 +10,13 @@ function validNamespaceSegments(value) {
10
10
  && segment.length > 0 && normalizeIdentityStem({ source: segment }) === segment
11
11
  && !segment.includes("/") && segment !== "." && segment !== "..");
12
12
  }
13
- export function readNamespaceContext(root) {
13
+ export async function readNamespaceContext(root) {
14
14
  let bytes;
15
15
  try {
16
- const path = currentPath(root), stat = lstatSync(path);
16
+ const path = currentPath(root), stat = await lstat(path);
17
17
  if (!stat.isFile() || stat.isSymbolicLink())
18
18
  return "malformed";
19
- bytes = readFileSync(path, "utf8");
19
+ bytes = await readFile(path, "utf8");
20
20
  }
21
21
  catch (error) {
22
22
  if (error.code === "ENOENT")
@@ -29,28 +29,23 @@ export function readNamespaceContext(root) {
29
29
  const segments = content === "" ? [] : content.split("/");
30
30
  return validNamespaceSegments(segments) ? segments : "malformed";
31
31
  }
32
- export function installNamespaceContext(root, segments) {
32
+ export async function installNamespaceContext(root, segments) {
33
33
  if (!validNamespaceSegments(segments))
34
34
  throw new TypeError("namespace must contain normalized segments");
35
35
  const parent = directory(root);
36
- mkdirSync(parent, { recursive: true });
37
- installIgnore(root);
38
- replaceFileDurably(currentPath(root), `${segments.join("/")}\n`);
36
+ await mkdir(parent, { recursive: true });
37
+ await installIgnore(root);
38
+ await replaceFileDurably(currentPath(root), `${segments.join("/")}\n`);
39
39
  }
40
- function installIgnore(root) {
41
- const ignore = ignorePath(root);
42
- const stat = lstatSync(ignore, { throwIfNoEntry: false });
43
- if (stat !== undefined && (!stat.isFile() || stat.isSymbolicLink()))
44
- throw new Error(`namespace ignore is not a regular file: ${ignore}`);
45
- if (stat === undefined || readFileSync(ignore, "utf8") !== "*\n")
46
- replaceFileDurably(ignore, "*\n");
40
+ async function installIgnore(root) {
41
+ await repairDerivedFile(ignorePath(root), "*\n");
47
42
  }
48
- export function repairNamespaceContext(root, segments) {
49
- const current = readNamespaceContext(root);
43
+ export async function repairNamespaceContext(root, segments) {
44
+ const current = await readNamespaceContext(root);
50
45
  if (Array.isArray(current)) {
51
- installIgnore(root);
46
+ await installIgnore(root);
52
47
  return "kept";
53
48
  }
54
- installNamespaceContext(root, segments);
49
+ await installNamespaceContext(root, segments);
55
50
  return "installed";
56
51
  }
@@ -11,11 +11,12 @@ export type TaskDocument = Readonly<{
11
11
  supersedes: readonly TaskId[];
12
12
  relates: readonly TaskId[];
13
13
  note: string;
14
+ createdBy?: string;
14
15
  createdAt: string;
15
16
  updatedAt: string;
16
17
  body: string;
17
18
  }>;
18
- export type TaskCreationDocument = Omit<TaskDocument, "id" | "createdAt" | "updatedAt">;
19
+ export type TaskCreationDocument = Omit<TaskDocument, "id" | "createdBy" | "createdAt" | "updatedAt">;
19
20
  export declare class TaskAuthorityCorruptionError extends Error {
20
21
  constructor(message: string, options?: ErrorOptions);
21
22
  }
@@ -4,7 +4,8 @@ export class TaskAuthorityCorruptionError extends Error {
4
4
  constructor(message, options) { super(message, options); this.name = "TaskAuthorityCorruptionError"; }
5
5
  }
6
6
  const STATES = new Set(["open", "in_progress", "on_hold", "done", "drop"]);
7
- const STORED_KEYS = ["id", "title", "state", "priority", "needs", "parent", "supersedes", "relates", "note", "createdAt", "updatedAt"];
7
+ const REQUIRED_STORED_KEYS = ["id", "title", "state", "priority", "needs", "parent", "supersedes", "relates", "note", "createdAt", "updatedAt"];
8
+ const STORED_KEYS = [...REQUIRED_STORED_KEYS, "createdBy"];
8
9
  const CREATION_KEYS = ["title", "state", "priority", "needs", "parent", "supersedes", "relates", "note"];
9
10
  function frontMatter(markdown, fail) {
10
11
  if (!markdown.startsWith("---\n"))
@@ -73,6 +74,11 @@ function taskIds(value, field, fail) {
73
74
  function nullableTaskId(value, field, fail) {
74
75
  return value === null ? null : taskId(value, field, fail);
75
76
  }
77
+ function createdBy(value, fail) {
78
+ if (typeof value !== "string" || value.trim().length === 0)
79
+ fail("createdBy must be a nonblank string");
80
+ return value;
81
+ }
76
82
  function fields(value, body, fail) {
77
83
  return {
78
84
  title: title(value.title, fail),
@@ -88,14 +94,17 @@ function fields(value, body, fail) {
88
94
  export function parseTaskDocument(bytes, expected) {
89
95
  const fail = (message, cause) => { throw new TaskAuthorityCorruptionError(message, cause === undefined ? {} : { cause }); };
90
96
  const { value, body } = frontMatter(Buffer.from(bytes).toString("utf8"), fail);
91
- closed(value, STORED_KEYS, STORED_KEYS, fail);
97
+ closed(value, STORED_KEYS, REQUIRED_STORED_KEYS, fail);
92
98
  const id = taskId(value.id, "id", fail);
93
99
  if (id !== formatTaskId(expected))
94
100
  fail(`task document ID ${id} does not match its authority path`);
95
101
  const createdAt = timestamp(value.createdAt, "createdAt", fail), updatedAt = timestamp(value.updatedAt, "updatedAt", fail);
96
102
  if (Date.parse(updatedAt) < Date.parse(createdAt))
97
103
  fail("updatedAt must not precede createdAt");
98
- return { id, state: state(value.state, fail), createdAt, updatedAt, ...fields(value, body, fail) };
104
+ return {
105
+ id, state: state(value.state, fail), createdAt, updatedAt, ...fields(value, body, fail),
106
+ ...(Object.hasOwn(value, "createdBy") ? { createdBy: createdBy(value.createdBy, fail) } : {}),
107
+ };
99
108
  }
100
109
  export function parseTaskCreationDocument(markdown) {
101
110
  const fail = (message) => { throw new TypeError(message); };
@@ -111,8 +120,9 @@ export function serializeTaskDocument(document) {
111
120
  const value = {
112
121
  id: document.id, title: document.title, state: document.state, priority: document.priority,
113
122
  needs: [...document.needs], parent: document.parent, supersedes: [...document.supersedes],
114
- relates: [...document.relates], note: document.note, createdAt: document.createdAt,
115
- updatedAt: document.updatedAt,
123
+ relates: [...document.relates], note: document.note,
124
+ ...(document.createdBy === undefined ? {} : { createdBy: document.createdBy }),
125
+ createdAt: document.createdAt, updatedAt: document.updatedAt,
116
126
  };
117
127
  return Buffer.from(`---\n${stringify(value, { lineWidth: 0 })}---\n${document.body}`);
118
128
  }
@@ -1,29 +1,30 @@
1
- import { type BlockedTaskRow, type TaskDetailFacts, type TaskDoctorIssue, type TaskRow, type TaskTreeNode } from "./board.js";
1
+ import type { WorldRoot } from "../world.js";
2
+ export type { WorldRoot } from "../world.js";
3
+ import { type BlockedTaskRow, type TaskDetailFacts, type TaskDoctorIssue, type TaskRef, type TaskRow, type TaskTreeNode } from "./board.js";
2
4
  import { type TaskCompositionResult } from "./compose.js";
3
5
  import { TaskAuthorityCorruptionError, type TaskPriority, type TaskState } from "./document.js";
4
6
  import { type TaskId } from "./identity.js";
5
7
  import { type AddTaskDocumentInput, type AddTaskInput, type TaskBatchResult, type TaskMutationResult, type TaskOutcome, type TaskRefusal, type TaskRetry, type TaskUpdateResult, type TaskView, type UpdateTaskInput } from "./operations.js";
6
- import { type TaskWorld } from "./store.js";
8
+ import { type TaskPage, type TaskQueryExpression, type TaskQueryPredicate, type TaskQueryRow, type TaskQuerySort } from "./query.js";
7
9
  export type TaskDetail = Omit<TaskDetailFacts, "task"> & Readonly<{
8
10
  task: TaskView;
9
11
  }>;
10
- export type TaskList = TaskOutcome<readonly TaskRow[]>;
11
- export type BlockedTaskList = TaskOutcome<readonly BlockedTaskRow[]>;
12
+ export type TaskList = TaskOutcome<TaskPage<TaskRow>>;
13
+ export type BlockedTaskList = TaskOutcome<TaskPage<BlockedTaskRow>>;
14
+ export type TaskQueryResult = TaskOutcome<TaskPage<TaskQueryRow>>;
12
15
  export type TaskNamespaceResult = TaskOutcome<readonly string[]>;
13
16
  export type TaskDoctorReport = Readonly<{
14
17
  issues: readonly TaskDoctorIssue[];
15
18
  }>;
16
- export type TaskDependencyTree = TaskOutcome<TaskTreeNode>;
17
- export type { AddTaskDocumentInput, AddTaskInput, BlockedTaskRow, TaskBatchResult, TaskCompositionResult, TaskDoctorIssue, TaskId, TaskMutationResult, TaskOutcome, TaskPriority, TaskRefusal, TaskRetry, TaskRow, TaskState, TaskUpdateResult, TaskView, UpdateTaskInput };
19
+ export type TaskDecompositionTree = TaskOutcome<TaskTreeNode>;
20
+ export type { AddTaskDocumentInput, AddTaskInput, BlockedTaskRow, TaskBatchResult, TaskCompositionResult, TaskDoctorIssue, TaskId, TaskMutationResult, TaskOutcome, TaskPriority, TaskRef, TaskRefusal, TaskRetry, TaskRow, TaskState, TaskTreeNode, TaskUpdateResult, TaskView, UpdateTaskInput, TaskPage, TaskQueryExpression, TaskQueryPredicate, TaskQueryRow, TaskQuerySort };
18
21
  export { TaskAuthorityCorruptionError };
19
22
  declare class TaskHandle {
20
23
  readonly id: TaskId;
21
24
  private readonly world;
22
- constructor(id: TaskId, world: TaskWorld);
25
+ constructor(id: TaskId, world: WorldRoot);
23
26
  read(): Promise<TaskDetail | null>;
24
- tree(input?: Readonly<{
25
- full?: boolean;
26
- }>): Promise<TaskDependencyTree>;
27
+ tree(): Promise<TaskDecompositionTree>;
27
28
  update(input: UpdateTaskInput): Promise<TaskUpdateResult>;
28
29
  private lifecycle;
29
30
  start(input?: {
@@ -39,6 +40,7 @@ declare class TaskHandle {
39
40
  signal?: AbortSignal;
40
41
  }): Promise<TaskMutationResult>;
41
42
  done(input?: {
43
+ note?: string;
42
44
  signal?: AbortSignal;
43
45
  }): Promise<TaskMutationResult>;
44
46
  drop(input?: {
@@ -48,9 +50,9 @@ declare class TaskHandle {
48
50
  }
49
51
  export type Task = TaskHandle;
50
52
  declare class TasksHandle {
51
- readonly root: string;
52
53
  private readonly world;
53
- constructor(path?: string);
54
+ readonly root: WorldRoot;
55
+ constructor(world: WorldRoot);
54
56
  namespace(): Promise<TaskNamespaceResult>;
55
57
  setNamespace(input: Readonly<{
56
58
  namespace: readonly string[];
@@ -63,13 +65,24 @@ declare class TasksHandle {
63
65
  list(input?: Readonly<{
64
66
  selection?: "active" | "closed" | "all";
65
67
  scope?: "namespace" | "world";
68
+ limit?: number;
66
69
  }>): Promise<TaskList>;
67
70
  ready(input?: Readonly<{
68
71
  scope?: "namespace" | "world";
72
+ parent?: string;
73
+ limit?: number;
69
74
  }>): Promise<TaskList>;
70
75
  blocked(input?: Readonly<{
71
76
  scope?: "namespace" | "world";
77
+ parent?: string;
78
+ limit?: number;
72
79
  }>): Promise<BlockedTaskList>;
80
+ query(input?: Readonly<{
81
+ where?: TaskQueryExpression;
82
+ scope?: "namespace" | "world";
83
+ sort?: TaskQuerySort;
84
+ limit?: number;
85
+ }>): Promise<TaskQueryResult>;
73
86
  doctor(): Promise<TaskDoctorReport>;
74
87
  batch(input: Readonly<{
75
88
  verb: "done" | "drop" | "hold";
@@ -79,12 +92,11 @@ declare class TasksHandle {
79
92
  }>): Promise<TaskBatchResult>;
80
93
  compose(input: Readonly<{
81
94
  markdown: string;
95
+ actor?: string;
82
96
  signal?: AbortSignal;
83
97
  }>): Promise<TaskCompositionResult>;
84
98
  }
85
99
  export type Tasks = TasksHandle;
86
100
  export declare const Tasks: Readonly<{
87
- at(input?: Readonly<{
88
- path?: string;
89
- }>): Tasks;
101
+ of(root: WorldRoot): Tasks;
90
102
  }>;
@@ -1,10 +1,10 @@
1
- import { resolveContextRoot } from "../context-root.js";
2
1
  import { buildTree, diagnoseBoard, projectDetailFacts } from "./board.js";
3
2
  import { composeTasks } from "./compose.js";
4
3
  import { TaskAuthorityCorruptionError } from "./document.js";
5
4
  import { isTaskSegment, parseTaskId } from "./identity.js";
6
- import { addTask, addTaskDocument, batchTasks, blockedTasks, currentNamespace, lifecycleTask, listTasks, readyTasks, setCurrentNamespace, taskView, updateTask, } from "./operations.js";
5
+ import { addTask, addTaskDocument, batchTasks, blockedTasks, currentNamespace, lifecycleTask, listTasks, queryTasks, readyTasks, setCurrentNamespace, taskView, updateTask, } from "./operations.js";
7
6
  import { readBoard } from "./store.js";
7
+ import { isValidTaskLimit, normalizeTaskQuery, MAX_TASK_LIMIT, DEFAULT_TASK_LIMIT } from "./query.js";
8
8
  export { TaskAuthorityCorruptionError };
9
9
  function record(value, label) {
10
10
  if (typeof value !== "object" || value === null || Array.isArray(value))
@@ -49,9 +49,26 @@ function namespace(value) {
49
49
  function text(value, label) { if (value === undefined)
50
50
  return undefined; if (typeof value !== "string")
51
51
  throw new TypeError(`${label} must be a string`); return value; }
52
+ function actor(value) {
53
+ if (value === undefined)
54
+ return undefined;
55
+ if (typeof value !== "string" || value.trim().length === 0)
56
+ throw new TypeError("actor must be a nonblank string");
57
+ return value;
58
+ }
52
59
  function priority(value) { if (value === undefined)
53
60
  return undefined; if (!Number.isInteger(value) || typeof value !== "number" || value < 0 || value > 3)
54
61
  throw new TypeError("priority must be 0..3"); return value; }
62
+ function limit(value) { if (value === undefined)
63
+ return undefined; if (typeof value !== "number" || !isValidTaskLimit(value))
64
+ throw new TypeError(`limit must be an integer from 1 to ${MAX_TASK_LIMIT}`); return value; }
65
+ function sort(value) {
66
+ if (value === undefined)
67
+ return undefined;
68
+ if (value !== "priority" && value !== "created" && value !== "updated" && value !== "id")
69
+ throw new TypeError("sort is invalid");
70
+ return value;
71
+ }
55
72
  function state(value) {
56
73
  if (value === undefined)
57
74
  return undefined;
@@ -62,17 +79,18 @@ function state(value) {
62
79
  function nullableId(value) { return value === undefined || value === null ? value : id(value); }
63
80
  function addInput(input) {
64
81
  const v = record(input, "add input");
65
- closed(v, ["title", "namespace", "body", "note", "state", "priority", "needs", "parent", "supersedes", "relates", "signal"], "add input");
82
+ closed(v, ["title", "namespace", "body", "note", "state", "priority", "needs", "parent", "supersedes", "relates", "actor", "signal"], "add input");
66
83
  const title = text(v.title, "title");
67
84
  if (title === undefined || title.trim() === "")
68
85
  throw new TypeError("title is required");
69
86
  const ns = namespace(v.namespace), body = text(v.body, "body"), note = text(v.note, "note"), initialState = state(v.state), pri = priority(v.priority);
70
87
  const needs = taskIds(v.needs, "needs"), parent = nullableId(v.parent), supersedes = taskIds(v.supersedes, "supersedes"), relates = taskIds(v.relates, "relates");
71
- const abort = signal(v.signal);
88
+ const createdBy = actor(v.actor), abort = signal(v.signal);
72
89
  return { title, ...(ns === undefined ? {} : { namespace: ns }), ...(body === undefined ? {} : { body }), ...(note === undefined ? {} : { note }),
73
90
  ...(initialState === undefined ? {} : { state: initialState }), ...(pri === undefined ? {} : { priority: pri }),
74
91
  ...(needs === undefined ? {} : { needs }), ...(parent === undefined ? {} : { parent }),
75
92
  ...(supersedes === undefined ? {} : { supersedes }), ...(relates === undefined ? {} : { relates }),
93
+ ...(createdBy === undefined ? {} : { actor: createdBy }),
76
94
  ...(abort === undefined ? {} : { signal: abort }) };
77
95
  }
78
96
  function updateInput(input) {
@@ -121,22 +139,20 @@ class TaskHandle {
121
139
  this.world = world;
122
140
  }
123
141
  async read() {
124
- const facts = projectDetailFacts(readBoard(this.world).board, this.id);
142
+ const facts = projectDetailFacts((await readBoard(this.world)).board, this.id);
125
143
  return facts === null ? null : { ...facts, task: taskView(facts.task) };
126
144
  }
127
- async tree(input) {
128
- const value = record(input ?? {}, "tree input");
129
- closed(value, ["full"], "tree input");
130
- if (value.full !== undefined && typeof value.full !== "boolean")
131
- throw new TypeError("full must be a boolean");
132
- const node = buildTree(readBoard(this.world).board, this.id, value.full ?? false);
145
+ async tree() {
146
+ if (arguments.length > 0)
147
+ throw new TypeError("tree accepts no input");
148
+ const node = buildTree((await readBoard(this.world)).board, this.id);
133
149
  return node === null ? { kind: "refused", refusal: { kind: "task-missing", taskId: this.id } } : { kind: "accepted", value: node };
134
150
  }
135
151
  update(input) { return updateTask(this.world, this.id, updateInput(input)); }
136
152
  lifecycle(verb, input) {
137
153
  const value = record(input ?? {}, `${verb} input`);
138
- closed(value, verb === "drop" ? ["note", "signal"] : ["signal"], `${verb} input`);
139
- const note = verb === "drop" ? text(value.note, "note") : undefined;
154
+ closed(value, verb === "drop" || verb === "done" ? ["note", "signal"] : ["signal"], `${verb} input`);
155
+ const note = verb === "drop" || verb === "done" ? text(value.note, "note") : undefined;
140
156
  return lifecycleTask(this.world, this.id, verb, signal(value.signal), note);
141
157
  }
142
158
  start(input) { return this.lifecycle("start", input); }
@@ -147,33 +163,39 @@ class TaskHandle {
147
163
  drop(input) { return this.lifecycle("drop", input); }
148
164
  }
149
165
  class TasksHandle {
150
- root;
151
166
  world;
152
- constructor(path) {
153
- const root = resolveContextRoot({ from: path ?? process.cwd(), marker: ".keiyaku" });
154
- this.world = { root };
155
- this.root = root;
167
+ root;
168
+ constructor(world) {
169
+ this.world = world;
170
+ this.root = world;
156
171
  }
157
- async namespace() { const value = currentNamespace(this.world); return "kind" in value ? { kind: "refused", refusal: value } : { kind: "accepted", value }; }
172
+ async namespace() { const value = await currentNamespace(this.world); return "kind" in value ? { kind: "refused", refusal: value } : { kind: "accepted", value }; }
158
173
  async setNamespace(input) { const v = record(input, "setNamespace input"); closed(v, ["namespace"], "setNamespace input"); const ns = namespace(v.namespace); if (ns === undefined)
159
- throw new TypeError("namespace is required"); setCurrentNamespace(this.world, ns); }
174
+ throw new TypeError("namespace is required"); await setCurrentNamespace(this.world, ns); }
160
175
  task(input) { const v = record(input, "task input"); closed(v, ["id"], "task input"); return new TaskHandle(id(v.id), this.world); }
161
176
  add(input) { return addTask(this.world, addInput(input)); }
162
- addDocument(input) { const v = record(input, "addDocument input"); closed(v, ["markdown", "namespace", "signal"], "addDocument input"); const markdown = text(v.markdown, "markdown"); if (markdown === undefined)
163
- throw new TypeError("markdown is required"); const ns = namespace(v.namespace), abort = signal(v.signal); return addTaskDocument(this.world, { markdown, ...(ns === undefined ? {} : { namespace: ns }), ...(abort === undefined ? {} : { signal: abort }) }); }
164
- async list(input = {}) { const v = record(input, "list input"); closed(v, ["selection", "scope"], "list input"); if (v.selection !== undefined && v.selection !== "active" && v.selection !== "closed" && v.selection !== "all")
177
+ addDocument(input) { const v = record(input, "addDocument input"); closed(v, ["markdown", "namespace", "actor", "signal"], "addDocument input"); const markdown = text(v.markdown, "markdown"); if (markdown === undefined)
178
+ throw new TypeError("markdown is required"); const ns = namespace(v.namespace), createdBy = actor(v.actor), abort = signal(v.signal); return addTaskDocument(this.world, { markdown, ...(ns === undefined ? {} : { namespace: ns }), ...(createdBy === undefined ? {} : { actor: createdBy }), ...(abort === undefined ? {} : { signal: abort }) }); }
179
+ async list(input = {}) { const v = record(input, "list input"); closed(v, ["selection", "scope", "limit"], "list input"); if (v.selection !== undefined && v.selection !== "active" && v.selection !== "closed" && v.selection !== "all")
165
180
  throw new TypeError("selection must be active, closed, or all"); if (v.scope !== undefined && v.scope !== "namespace" && v.scope !== "world")
166
- throw new TypeError("scope must be namespace or world"); return listTasks(this.world, v.selection ?? "active", v.scope); }
167
- async ready(input = {}) { const v = record(input, "ready input"); closed(v, ["scope"], "ready input"); if (v.scope !== undefined && v.scope !== "namespace" && v.scope !== "world")
168
- throw new TypeError("scope must be namespace or world"); return readyTasks(this.world, v.scope); }
169
- async blocked(input = {}) { const v = record(input, "blocked input"); closed(v, ["scope"], "blocked input"); if (v.scope !== undefined && v.scope !== "namespace" && v.scope !== "world")
170
- throw new TypeError("scope must be namespace or world"); return blockedTasks(this.world, v.scope); }
171
- async doctor() { return { issues: diagnoseBoard(readBoard(this.world).board) }; }
181
+ throw new TypeError("scope must be namespace or world"); return listTasks(this.world, v.selection ?? "active", v.scope, limit(v.limit) ?? DEFAULT_TASK_LIMIT); }
182
+ async ready(input = {}) { const v = record(input, "ready input"); closed(v, ["scope", "parent", "limit"], "ready input"); if (v.scope !== undefined && v.scope !== "namespace" && v.scope !== "world")
183
+ throw new TypeError("scope must be namespace or world"); const parent = v.parent === undefined ? undefined : id(v.parent); return readyTasks(this.world, v.scope, parent, limit(v.limit) ?? DEFAULT_TASK_LIMIT); }
184
+ async blocked(input = {}) { const v = record(input, "blocked input"); closed(v, ["scope", "parent", "limit"], "blocked input"); if (v.scope !== undefined && v.scope !== "namespace" && v.scope !== "world")
185
+ throw new TypeError("scope must be namespace or world"); const parent = v.parent === undefined ? undefined : id(v.parent); return blockedTasks(this.world, v.scope, parent, limit(v.limit) ?? DEFAULT_TASK_LIMIT); }
186
+ async query(input = {}) { const v = record(input, "query input"); closed(v, ["where", "scope", "sort", "limit"], "query input"); if (v.scope !== undefined && v.scope !== "namespace" && v.scope !== "world")
187
+ throw new TypeError("scope must be namespace or world"); const expression = v.where === undefined ? { kind: "and", terms: [{ kind: "predicate", predicate: { field: "state", operator: "!=", value: "done" } }, { kind: "predicate", predicate: { field: "state", operator: "!=", value: "drop" } }] } : normalizeTaskQuery(v.where); return queryTasks(this.world, expression, v.scope, sort(v.sort) ?? "priority", limit(v.limit) ?? DEFAULT_TASK_LIMIT); }
188
+ async doctor() { return { issues: diagnoseBoard((await readBoard(this.world)).board) }; }
172
189
  batch(input) { const v = record(input, "batch input"); closed(v, ["verb", "ids", "note", "signal"], "batch input"); const verb = v.verb; if (verb !== "done" && verb !== "drop" && verb !== "hold")
173
- throw new TypeError("batch verb is invalid"); const note = text(v.note, "note"); if (note !== undefined && verb !== "drop")
174
- throw new TypeError("batch note is valid only for drop"); return batchTasks(this.world, verb, taskIds(v.ids, "ids") ?? [], signal(v.signal), note); }
175
- compose(input) { const v = record(input, "compose input"); closed(v, ["markdown", "signal"], "compose input"); const markdown = text(v.markdown, "markdown"); if (markdown === undefined)
176
- throw new TypeError("markdown is required"); return composeTasks(this.world, markdown, signal(v.signal)); }
190
+ throw new TypeError("batch verb is invalid"); const note = text(v.note, "note"); if (note !== undefined && verb !== "done" && verb !== "drop")
191
+ throw new TypeError("batch note is valid only for done or drop"); return batchTasks(this.world, verb, taskIds(v.ids, "ids") ?? [], signal(v.signal), note); }
192
+ compose(input) { const v = record(input, "compose input"); closed(v, ["markdown", "actor", "signal"], "compose input"); const markdown = text(v.markdown, "markdown"); if (markdown === undefined)
193
+ throw new TypeError("markdown is required"); return composeTasks(this.world, markdown, signal(v.signal), actor(v.actor)); }
177
194
  }
178
- export const Tasks = Object.freeze({ at(input) { if (input === undefined)
179
- return new TasksHandle(); const value = record(input, "Tasks.at input"); closed(value, ["path"], "Tasks.at input"); return new TasksHandle(text(value.path, "path")); } });
195
+ export const Tasks = Object.freeze({
196
+ of(root) {
197
+ if (typeof root !== "string")
198
+ throw new TypeError("Tasks.of root must be a WorldRoot");
199
+ return new TasksHandle(root);
200
+ },
201
+ });
@@ -1,7 +1,8 @@
1
1
  import { type BlockedTaskRow, type TaskRow } from "./board.js";
2
2
  import { type TaskDocument, type TaskPriority, type TaskState } from "./document.js";
3
3
  import { type TaskId } from "./identity.js";
4
- import { type TaskWorld } from "./store.js";
4
+ import type { WorldRoot } from "../world.js";
5
+ import { type TaskPage, type TaskQueryExpression, type TaskQueryRow, type TaskQuerySort } from "./query.js";
5
6
  export type TaskView = Readonly<TaskDocument & {
6
7
  namespace: readonly string[];
7
8
  }>;
@@ -51,7 +52,7 @@ export type TaskBatchResult = Readonly<{
51
52
  outcome: TaskMutationResult;
52
53
  }>[];
53
54
  }>;
54
- export type SettledTaskAction = "done" | "reopened";
55
+ export type SettledTaskAction = "done";
55
56
  export type SettledTaskResult = Readonly<{
56
57
  kind: "changed";
57
58
  task: TaskView;
@@ -76,11 +77,13 @@ export type AddTaskInput = Readonly<{
76
77
  parent?: TaskId | null;
77
78
  supersedes?: readonly TaskId[];
78
79
  relates?: readonly TaskId[];
80
+ actor?: string;
79
81
  signal?: AbortSignal;
80
82
  }>;
81
83
  export type AddTaskDocumentInput = Readonly<{
82
84
  markdown: string;
83
85
  namespace?: readonly string[];
86
+ actor?: string;
84
87
  signal?: AbortSignal;
85
88
  }>;
86
89
  export type UpdateTaskInput = Readonly<{
@@ -102,14 +105,36 @@ export type UpdateTaskInput = Readonly<{
102
105
  signal?: AbortSignal;
103
106
  }>;
104
107
  export declare function taskView(document: TaskDocument): TaskView;
105
- export declare function addTask(world: TaskWorld, input: AddTaskInput): Promise<TaskMutationResult>;
106
- export declare function addTaskDocument(world: TaskWorld, input: AddTaskDocumentInput): Promise<TaskMutationResult>;
107
- export declare function updateTask(world: TaskWorld, id: TaskId, input: UpdateTaskInput): Promise<TaskUpdateResult>;
108
- export declare function lifecycleTask(world: TaskWorld, id: TaskId, verb: TaskLifecycleVerb, signal?: AbortSignal, note?: string): Promise<TaskMutationResult>;
109
- export declare function batchTasks(world: TaskWorld, verb: "done" | "drop" | "hold", ids: readonly TaskId[], signal?: AbortSignal, note?: string): Promise<TaskBatchResult>;
110
- export declare function settleTask(world: TaskWorld, id: TaskId, desired: "done" | "open-from-done"): Promise<SettledTaskResult>;
111
- export declare function listTasks(world: TaskWorld, selection: "active" | "closed" | "all", scope?: "namespace" | "world"): TaskOutcome<readonly TaskRow[]>;
112
- export declare function readyTasks(world: TaskWorld, scope?: "namespace" | "world"): TaskOutcome<readonly TaskRow[]>;
113
- export declare function blockedTasks(world: TaskWorld, scope?: "namespace" | "world"): TaskOutcome<readonly BlockedTaskRow[]>;
114
- export declare function setCurrentNamespace(world: TaskWorld, namespace: readonly string[]): void;
115
- export declare function currentNamespace(world: TaskWorld): readonly string[] | TaskRefusal;
108
+ export declare function addTask(world: WorldRoot, input: AddTaskInput): Promise<TaskMutationResult>;
109
+ export declare function addTaskDocument(world: WorldRoot, input: AddTaskDocumentInput): Promise<TaskMutationResult>;
110
+ export declare function updateTask(world: WorldRoot, id: TaskId, input: UpdateTaskInput): Promise<TaskUpdateResult>;
111
+ export declare function lifecycleTask(world: WorldRoot, id: TaskId, verb: TaskLifecycleVerb, signal?: AbortSignal, note?: string): Promise<TaskMutationResult>;
112
+ export declare function batchTasks(world: WorldRoot, verb: "done" | "drop" | "hold", ids: readonly TaskId[], signal?: AbortSignal, note?: string): Promise<TaskBatchResult>;
113
+ export declare function settleTask(world: WorldRoot, id: TaskId): Promise<SettledTaskResult>;
114
+ export declare function listTasks(world: WorldRoot, selection: "active" | "closed" | "all", scope?: "namespace" | "world", limit?: number): Promise<TaskOutcome<TaskPage<TaskRow>>>;
115
+ export declare function readyTasks(world: WorldRoot, scope?: "namespace" | "world", parent?: TaskId, limit?: number): Promise<TaskOutcome<TaskPage<TaskRow>>>;
116
+ export declare function blockedTasks(world: WorldRoot, scope?: "namespace" | "world", parent?: TaskId, limit?: number): Promise<TaskOutcome<TaskPage<BlockedTaskRow>>>;
117
+ export declare function queryTasks(world: WorldRoot, expression: TaskQueryExpression, scope?: "namespace" | "world", sort?: TaskQuerySort, limit?: number): Promise<TaskOutcome<TaskPage<TaskQueryRow>>>;
118
+ /** Internal composite observation from one complete Task board read. */
119
+ export declare function observeTaskStatusRows(world: WorldRoot): Promise<(Readonly<{
120
+ id: TaskId;
121
+ title: string;
122
+ state: TaskState;
123
+ priority: TaskPriority;
124
+ disposition: import("./board.js").TaskDisposition;
125
+ }> | {
126
+ blockers: readonly Readonly<{
127
+ id: TaskId;
128
+ title: string | null;
129
+ state: TaskState | "missing";
130
+ }>[];
131
+ id: TaskId;
132
+ title: string;
133
+ state: TaskState;
134
+ priority: TaskPriority;
135
+ disposition: import("./board.js").TaskDisposition;
136
+ })[]>;
137
+ /** Internal identity catalog from one complete Task board read. */
138
+ export declare function observeTaskCatalogRows(world: WorldRoot): Promise<readonly TaskRow[]>;
139
+ export declare function setCurrentNamespace(world: WorldRoot, namespace: readonly string[]): Promise<void>;
140
+ export declare function currentNamespace(world: WorldRoot): Promise<readonly string[] | TaskRefusal>;