@astrosheep/keiyaku 4.6.3 → 4.6.6

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 (193) hide show
  1. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +47 -11
  2. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/references/automation.md +2 -2
  3. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-babysit/SKILL.md +1 -1
  4. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +8 -9
  5. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +37 -25
  6. package/build/src/akuma/akuma-observe.d.ts +18 -15
  7. package/build/src/akuma/akuma-observe.js +75 -16
  8. package/build/src/akuma/akuma-wait.d.ts +4 -3
  9. package/build/src/akuma/akuma-wait.js +75 -53
  10. package/build/src/akuma/akuma.d.ts +6 -4
  11. package/build/src/akuma/akuma.js +4 -0
  12. package/build/src/akuma/call-initial-tell.d.ts +2 -2
  13. package/build/src/akuma/call-initial-tell.js +1 -1
  14. package/build/src/akuma/call-request.d.ts +2 -2
  15. package/build/src/akuma/heart/index.d.ts +7 -2
  16. package/build/src/akuma/heart/index.js +50 -5
  17. package/build/src/akuma/heart/tells.d.ts +33 -2
  18. package/build/src/akuma/heart/tells.js +24 -18
  19. package/build/src/akuma/heart/timeline.d.ts +23 -1
  20. package/build/src/akuma/heart/timeline.js +28 -21
  21. package/build/src/akuma/projection.d.ts +10 -10
  22. package/build/src/akuma/providers/pi/index.js +72 -39
  23. package/build/src/akuma/selection-observation.d.ts +20 -20
  24. package/build/src/akuma-body.js +1 -0
  25. package/build/src/alias/index.d.ts +0 -1
  26. package/build/src/alias/index.js +0 -4
  27. package/build/src/body/amend.d.ts +0 -4
  28. package/build/src/body/amend.js +0 -3
  29. package/build/src/body/region.d.ts +0 -1
  30. package/build/src/body/region.js +0 -3
  31. package/build/src/body/verification.d.ts +0 -1
  32. package/build/src/cli/commands/akuma-grammar.js +23 -66
  33. package/build/src/cli/commands/akuma.js +17 -30
  34. package/build/src/cli/commands/contract-grammar.d.ts +14 -1
  35. package/build/src/cli/commands/contract-grammar.js +54 -21
  36. package/build/src/cli/commands/contract-help.d.ts +9 -8
  37. package/build/src/cli/commands/contract-help.js +14 -7
  38. package/build/src/cli/commands/contract.js +57 -117
  39. package/build/src/cli/commands/install.d.ts +5 -5
  40. package/build/src/cli/commands/install.js +1 -4
  41. package/build/src/cli/commands/task-grammar.js +10 -66
  42. package/build/src/cli/commands/task.d.ts +0 -1
  43. package/build/src/cli/commands/task.js +34 -53
  44. package/build/src/cli/coordinates.d.ts +1 -2
  45. package/build/src/cli/coordinates.js +1 -4
  46. package/build/src/cli/parse.d.ts +2 -3
  47. package/build/src/cli/parse.js +24 -66
  48. package/build/src/cli/render/akuma.d.ts +3 -16
  49. package/build/src/cli/render/akuma.js +1 -13
  50. package/build/src/cli/render/audit.js +1 -1
  51. package/build/src/cli/render/contract.js +34 -32
  52. package/build/src/cli/render/kanshi-akuma.d.ts +8 -2
  53. package/build/src/cli/render/kanshi-akuma.js +14 -7
  54. package/build/src/cli/render/kanshi.d.ts +3 -1
  55. package/build/src/cli/render/kanshi.js +44 -32
  56. package/build/src/cli/render/receipt.js +6 -1
  57. package/build/src/cli/render/task.d.ts +1 -1
  58. package/build/src/cli/render/task.js +3 -27
  59. package/build/src/cli/render/terminal.d.ts +6 -2
  60. package/build/src/cli/render/terminal.js +8 -2
  61. package/build/src/cli/runtime.js +3 -16
  62. package/build/src/cli/scan.d.ts +26 -0
  63. package/build/src/cli/scan.js +82 -0
  64. package/build/src/cli/streams.d.ts +5 -0
  65. package/build/src/cli/streams.js +11 -0
  66. package/build/src/contract-worktree.js +38 -21
  67. package/build/src/core/facts/codec.d.ts +1 -2
  68. package/build/src/core/facts/codec.js +5 -11
  69. package/build/src/core/facts/types.d.ts +16 -2
  70. package/build/src/core/facts/types.js +15 -0
  71. package/build/src/core/verbs/abandon.js +3 -9
  72. package/build/src/core/verbs/amend.js +2 -9
  73. package/build/src/core/verbs/arc.js +6 -13
  74. package/build/src/core/verbs/attestation.js +2 -9
  75. package/build/src/core/verbs/bind.js +2 -9
  76. package/build/src/core/verbs/deliver.js +2 -9
  77. package/build/src/core/verbs/placement.d.ts +1 -1
  78. package/build/src/core/verbs/placement.js +2 -9
  79. package/build/src/core/verbs/reintegrate.d.ts +1 -1
  80. package/build/src/core/verbs/reintegrate.js +2 -9
  81. package/build/src/dispatch/index.d.ts +2 -2
  82. package/build/src/dispatch/index.js +33 -11
  83. package/build/src/git/hooks.d.ts +2 -4
  84. package/build/src/git/hooks.js +0 -12
  85. package/build/src/git/integration.d.ts +5 -3
  86. package/build/src/git/integration.js +36 -25
  87. package/build/src/git/nuke.js +4 -4
  88. package/build/src/git/observe.d.ts +4 -4
  89. package/build/src/git/observe.js +5 -5
  90. package/build/src/git/process.d.ts +1 -4
  91. package/build/src/git/process.js +1 -11
  92. package/build/src/git/read-observation.js +1 -1
  93. package/build/src/git/reconcile.d.ts +1 -1
  94. package/build/src/git/reconcile.js +15 -13
  95. package/build/src/git/repository.d.ts +2 -6
  96. package/build/src/git/repository.js +18 -31
  97. package/build/src/git/scratch.d.ts +6 -6
  98. package/build/src/git/scratch.js +110 -46
  99. package/build/src/git/target-placement.d.ts +5 -5
  100. package/build/src/git/target-placement.js +18 -33
  101. package/build/src/git/tender.d.ts +6 -2
  102. package/build/src/git/tender.js +19 -12
  103. package/build/src/git/terminal-reconcile.js +24 -13
  104. package/build/src/git/terminal-seal.d.ts +2 -5
  105. package/build/src/git/terminal-seal.js +5 -3
  106. package/build/src/git/workspace.d.ts +17 -13
  107. package/build/src/git/workspace.js +58 -41
  108. package/build/src/kanshi/index.d.ts +2 -2
  109. package/build/src/kanshi/index.js +1 -1
  110. package/build/src/kanshi/read.d.ts +8 -1
  111. package/build/src/kanshi/read.js +72 -7
  112. package/build/src/kanshi/report.d.ts +12 -0
  113. package/build/src/library/akuma-creation.d.ts +4 -4
  114. package/build/src/library/bind.d.ts +1 -63
  115. package/build/src/library/bind.js +3 -9
  116. package/build/src/library/contract-creation.js +2 -30
  117. package/build/src/library/contract-execution.d.ts +0 -1
  118. package/build/src/library/contract-execution.js +9 -34
  119. package/build/src/library/contract-operations.d.ts +5 -1
  120. package/build/src/library/contract-operations.js +7 -3
  121. package/build/src/library/contract-types.d.ts +1 -1
  122. package/build/src/library/delivery.d.ts +91 -93
  123. package/build/src/library/delivery.js +2 -1
  124. package/build/src/library/input.d.ts +0 -2
  125. package/build/src/library/input.js +0 -4
  126. package/build/src/library/invocation.d.ts +0 -1
  127. package/build/src/library/invocation.js +3 -25
  128. package/build/src/library/outcome.d.ts +651 -602
  129. package/build/src/library/outcome.js +4 -4
  130. package/build/src/library/reconcile.d.ts +6 -0
  131. package/build/src/library/reconcile.js +31 -1
  132. package/build/src/library/repo.d.ts +0 -1
  133. package/build/src/library/selection.d.ts +1 -10
  134. package/build/src/library/selection.js +14 -15
  135. package/build/src/protocol/abandon.d.ts +1 -1
  136. package/build/src/protocol/abandon.js +3 -10
  137. package/build/src/protocol/amend.js +2 -5
  138. package/build/src/protocol/arc.d.ts +1 -1
  139. package/build/src/protocol/arc.js +2 -9
  140. package/build/src/protocol/attempt.d.ts +3 -20
  141. package/build/src/protocol/attempt.js +6 -5
  142. package/build/src/protocol/audit.d.ts +1 -0
  143. package/build/src/protocol/audit.js +10 -11
  144. package/build/src/protocol/completion.d.ts +129 -55
  145. package/build/src/protocol/completion.js +62 -73
  146. package/build/src/protocol/deliver.d.ts +7 -5
  147. package/build/src/protocol/deliver.js +74 -44
  148. package/build/src/protocol/execution-observation.d.ts +2 -4
  149. package/build/src/protocol/execution-observation.js +3 -7
  150. package/build/src/protocol/intent.d.ts +1 -1
  151. package/build/src/protocol/intent.js +1 -0
  152. package/build/src/protocol/operations.d.ts +24 -12
  153. package/build/src/protocol/operations.js +36 -15
  154. package/build/src/protocol/placement.d.ts +2 -1
  155. package/build/src/protocol/placement.js +21 -5
  156. package/build/src/protocol/progress.d.ts +1 -1
  157. package/build/src/protocol/read/status.js +58 -41
  158. package/build/src/protocol/reintegrate.d.ts +1 -1
  159. package/build/src/protocol/reintegrate.js +10 -19
  160. package/build/src/protocol/review.d.ts +3 -28
  161. package/build/src/protocol/review.js +10 -37
  162. package/build/src/protocol/run.d.ts +19 -7
  163. package/build/src/protocol/run.js +19 -9
  164. package/build/src/runtime/proc/windows-launch.exe +0 -0
  165. package/build/src/settlement/holder.d.ts +2 -4
  166. package/build/src/settlement/holder.js +3 -6
  167. package/build/src/task/board.d.ts +6 -0
  168. package/build/src/task/board.js +30 -1
  169. package/build/src/task/catalog.js +1 -4
  170. package/build/src/task/compose.d.ts +0 -1
  171. package/build/src/task/compose.js +0 -1
  172. package/build/src/task/context.d.ts +0 -1
  173. package/build/src/task/context.js +0 -3
  174. package/build/src/task/created-observation.d.ts +5 -1
  175. package/build/src/task/created-observation.js +12 -5
  176. package/build/src/task/index.d.ts +1 -1
  177. package/build/src/task/index.js +7 -6
  178. package/build/src/task/input.d.ts +0 -6
  179. package/build/src/task/input.js +2 -14
  180. package/build/src/task/mutation.d.ts +3 -4
  181. package/build/src/task/mutation.js +11 -39
  182. package/build/src/task/operations.d.ts +2 -7
  183. package/build/src/task/operations.js +37 -49
  184. package/build/src/task/query.d.ts +0 -1
  185. package/build/src/task/query.js +1 -4
  186. package/build/src/task/store.d.ts +0 -2
  187. package/build/src/task/store.js +27 -11
  188. package/build/src/verification/declaration.js +3 -2
  189. package/build/src/verification/execution.d.ts +3 -2
  190. package/build/src/verification/execution.js +10 -6
  191. package/build/src/workspace-place.d.ts +0 -1
  192. package/build/src/workspace-place.js +0 -11
  193. package/package.json +7 -3
@@ -41,7 +41,7 @@ async function catalogRow(world, task, documents) {
41
41
  ...(blockers.length === 0 ? {} : { blockers }),
42
42
  };
43
43
  }
44
- async function recentTaskStatus(world, input) {
44
+ export async function observeRecentTaskStatus(world, input = {}) {
45
45
  const { namespace } = input;
46
46
  if (namespace !== undefined && !namespace.every(isTaskSegment)) {
47
47
  throw new TypeError("namespace must contain canonical segments");
@@ -57,6 +57,3 @@ async function recentTaskStatus(world, input) {
57
57
  hasMore: documents.hasMore,
58
58
  };
59
59
  }
60
- export async function observeRecentTaskStatus(world, input = {}) {
61
- return recentTaskStatus(world, input);
62
- }
@@ -3,7 +3,6 @@ import type { TaskCompositionResult } from "./mutation-result.js";
3
3
  import { type AcceptedComposition } from "./compose-language.js";
4
4
  export type { TaskCompositionAdmission, TaskCompositionBodyPreview, TaskCompositionPlanAlias, TaskCompositionPlanOrder, } from "./compose-language.js";
5
5
  export type { TaskCompositionAlias } from "./compose-language.js";
6
- export { taskCompositionNamespaceHeader } from "./compose-language.js";
7
6
  export type TaskDocumentChange = Readonly<AcceptedComposition["documentChanges"][number]>;
8
7
  export type TaskCompositionFacts = Readonly<Pick<AcceptedComposition, "aliases" | "admissionOrder" | "admissions">>;
9
8
  export type { TaskCompositionResult } from "./mutation-result.js";
@@ -3,7 +3,6 @@ import { planTaskComposition, } from "./compose-language.js";
3
3
  import { serializeTaskDocument } from "./document.js";
4
4
  import { parseTaskId, taskAuthorityPath } from "./identity.js";
5
5
  import { readBoard, replaceAuthority, withTaskLocks } from "./store.js";
6
- export { taskCompositionNamespaceHeader } from "./compose-language.js";
7
6
  function refusal(diagnostics) {
8
7
  return { kind: "refused", refusal: { kind: "invalid-composition", diagnostics } };
9
8
  }
@@ -19,4 +19,3 @@ export declare function resolveTaskNamespaceContext(input: NamespaceContextInput
19
19
  kind: "invalid-namespace-context";
20
20
  path: string;
21
21
  }>>;
22
- export declare function writeTaskNamespaceContext(directory: string, value: readonly string[]): Promise<void>;
@@ -101,6 +101,3 @@ export async function resolveTaskNamespaceContext(input) {
101
101
  current = resolvedParent;
102
102
  }
103
103
  }
104
- export async function writeTaskNamespaceContext(directory, value) {
105
- await installNamespaceContext(directory, value);
106
- }
@@ -34,5 +34,9 @@ export declare const createdTaskObservationSchema: z.ZodUnion<readonly [z.ZodObj
34
34
  }, z.core.$strict>]>;
35
35
  export type CreatedTaskObservation = z.infer<typeof createdTaskObservationSchema>;
36
36
  export declare const EMPTY_CREATED_TASK_OBSERVATION: CreatedTaskObservation;
37
- /** Project Task board rows created by each identity, preserving input order. */
37
+ /**
38
+ * Project Task board rows created by each identity, preserving input order. One complete
39
+ * board and one relationship projection answer every requested identity, and only the
40
+ * documents those identities created reach row projection.
41
+ */
38
42
  export declare function observeCreatedTaskObservations(world: WorldRoot, createdByIds: readonly string[]): Promise<readonly CreatedTaskObservation[]>;
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
- import { taskRowsSchema } from "./board.js";
3
- import { observeTaskBoard } from "./operations.js";
2
+ import { createTaskRelations, projectCreatedByRows, taskRowsSchema } from "./board.js";
3
+ import { readBoard } from "./store.js";
4
4
  export const createdTaskObservationSchema = z.union([
5
5
  z.object({ kind: z.literal("present"), rows: taskRowsSchema }).strict(),
6
6
  z.object({ kind: z.literal("failed"), diagnostic: z.string() }).strict(),
@@ -9,15 +9,22 @@ export const EMPTY_CREATED_TASK_OBSERVATION = { kind: "present", rows: [] };
9
9
  function observationDiagnostic(error) {
10
10
  return error instanceof Error ? error.message : String(error);
11
11
  }
12
- /** Project Task board rows created by each identity, preserving input order. */
12
+ /**
13
+ * Project Task board rows created by each identity, preserving input order. One complete
14
+ * board and one relationship projection answer every requested identity, and only the
15
+ * documents those identities created reach row projection.
16
+ */
13
17
  export async function observeCreatedTaskObservations(world, createdByIds) {
18
+ if (createdByIds.length === 0)
19
+ return [];
14
20
  let board;
15
21
  try {
16
- board = await observeTaskBoard(world);
22
+ board = (await readBoard(world)).board;
17
23
  }
18
24
  catch (error) {
19
25
  const failed = { kind: "failed", diagnostic: observationDiagnostic(error) };
20
26
  return createdByIds.map(() => failed);
21
27
  }
22
- return createdByIds.map((createdBy) => ({ kind: "present", rows: board.selectCreatedBy(createdBy) }));
28
+ const rows = projectCreatedByRows(board, createTaskRelations(board), createdByIds);
29
+ return createdByIds.map((createdBy) => ({ kind: "present", rows: rows.get(createdBy) ?? [] }));
23
30
  }
@@ -26,7 +26,7 @@ export type { AddTaskDocumentInput, AddTaskInput, BlockedTaskRow, TaskBatchResul
26
26
  export type { LibraryExecution } from "../akuma/requests.js";
27
27
  export { TaskAuthorityCorruptionError, TASK_RELATION_PREDICATE_FIELDS };
28
28
  export { observeRecentTaskStatus, type RecentTaskStatusRow } from "./catalog.js";
29
- export { taskRowViewLimit } from "./input.js";
29
+ export { boundedListLimit as taskRowViewLimit } from "../bounded-list.js";
30
30
  type ComposeValues = Readonly<{
31
31
  markdown: string;
32
32
  namespace?: readonly string[];
@@ -4,12 +4,13 @@ import { buildTree, createTaskRelations, diagnoseBoard, } from "./board.js";
4
4
  import { composeTasks, } from "./compose.js";
5
5
  import { TaskAuthorityCorruptionError } from "./document.js";
6
6
  import { addTask, addTaskDocument, batchTasks, blockedTasks, lifecycleTask, listTasks, queryTasks, readTaskDetail, readyTasks, taskView, updateTask, } from "./operations.js";
7
+ import { boundedListLimit } from "../bounded-list.js";
7
8
  import { readBoard } from "./store.js";
8
- import { actor, addInput, closed, namespace, record, signal, sort, taskRowViewLimit, taskId as id, taskIds, text, updateInput, } from "./input.js";
9
+ import { actor, addInput, closed, namespace, record, signal, sort, taskId as id, taskIds, text, updateInput, } from "./input.js";
9
10
  import { normalizeTaskQuery, taskQuerySelection, TASK_RELATION_PREDICATE_FIELDS, } from "./query.js";
10
11
  export { TaskAuthorityCorruptionError, TASK_RELATION_PREDICATE_FIELDS };
11
12
  export { observeRecentTaskStatus } from "./catalog.js";
12
- export { taskRowViewLimit } from "./input.js";
13
+ export { boundedListLimit as taskRowViewLimit } from "../bounded-list.js";
13
14
  function taskRoute(execution) {
14
15
  const channel = executionChannel(execution);
15
16
  return channel.kind === "body-request" ? { kind: "forwarded", directory: channel.directory } : { kind: "local" };
@@ -162,7 +163,7 @@ class TasksHandle {
162
163
  throw new TypeError("selection must be active, closed, or all");
163
164
  if (v.scope !== undefined && v.scope !== "namespace" && v.scope !== "world")
164
165
  throw new TypeError("scope must be namespace or world");
165
- const selectedLimit = taskRowViewLimit(v.limit);
166
+ const selectedLimit = boundedListLimit(v.limit);
166
167
  return listTasks(this.world, namespace(v.namespace), v.selection ?? "active", v.scope, selectedLimit);
167
168
  }
168
169
  async ready(input = {}) {
@@ -171,7 +172,7 @@ class TasksHandle {
171
172
  if (v.scope !== undefined && v.scope !== "namespace" && v.scope !== "world")
172
173
  throw new TypeError("scope must be namespace or world");
173
174
  const parent = v.parent === undefined ? undefined : id(v.parent);
174
- const selectedLimit = taskRowViewLimit(v.limit);
175
+ const selectedLimit = boundedListLimit(v.limit);
175
176
  return readyTasks(this.world, namespace(v.namespace), v.scope, parent, selectedLimit);
176
177
  }
177
178
  async blocked(input = {}) {
@@ -180,7 +181,7 @@ class TasksHandle {
180
181
  if (v.scope !== undefined && v.scope !== "namespace" && v.scope !== "world")
181
182
  throw new TypeError("scope must be namespace or world");
182
183
  const parent = v.parent === undefined ? undefined : id(v.parent);
183
- const selectedLimit = taskRowViewLimit(v.limit);
184
+ const selectedLimit = boundedListLimit(v.limit);
184
185
  return blockedTasks(this.world, namespace(v.namespace), v.scope, parent, selectedLimit);
185
186
  }
186
187
  async query(input = {}) {
@@ -190,7 +191,7 @@ class TasksHandle {
190
191
  throw new TypeError("scope must be namespace or world");
191
192
  const expression = v.where === undefined ? taskQuerySelection() : normalizeTaskQuery(v.where);
192
193
  const selected = namespace(v.namespace);
193
- const selectedLimit = taskRowViewLimit(v.limit);
194
+ const selectedLimit = boundedListLimit(v.limit);
194
195
  return queryTasks({
195
196
  world: this.world,
196
197
  ...(selected === undefined ? {} : { namespace: selected }),
@@ -1,4 +1,3 @@
1
- import { type TaskPriority, type TaskState } from "./document.js";
2
1
  import { type TaskId } from "./identity.js";
3
2
  import type { AddTaskInput, UpdateTaskInput } from "./operations.js";
4
3
  import type { TaskQuerySort } from "./query.js";
@@ -10,11 +9,6 @@ export declare function taskIds(value: unknown, label: string): readonly TaskId[
10
9
  export declare function namespace(value: unknown): readonly string[] | undefined;
11
10
  export declare function text(value: unknown, label: string): string | undefined;
12
11
  export declare function actor(value: unknown): string | undefined;
13
- export declare function priority(value: unknown): TaskPriority | undefined;
14
- export declare function limit(value: unknown): number | undefined;
15
- /** Validates and supplies the shared bounded-list limit for Task row views. */
16
- export declare function taskRowViewLimit(value: unknown): number;
17
12
  export declare function sort(value: unknown): TaskQuerySort | undefined;
18
- export declare function state(value: unknown): TaskState | undefined;
19
13
  export declare function addInput(input: unknown): AddTaskInput;
20
14
  export declare function updateInput(input: unknown): UpdateTaskInput;
@@ -1,5 +1,4 @@
1
1
  import { isTaskSegment, parseTaskId } from "./identity.js";
2
- import { boundedListLimit } from "../bounded-list.js";
3
2
  export function record(value, label) {
4
3
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
5
4
  throw new TypeError(`${label} must be an object`);
@@ -63,7 +62,7 @@ export function actor(value) {
63
62
  }
64
63
  return value;
65
64
  }
66
- export function priority(value) {
65
+ function priority(value) {
67
66
  if (value === undefined)
68
67
  return undefined;
69
68
  if (!Number.isInteger(value) || typeof value !== "number" || value < 0 || value > 3) {
@@ -71,17 +70,6 @@ export function priority(value) {
71
70
  }
72
71
  return value;
73
72
  }
74
- export function limit(value) {
75
- if (value === undefined)
76
- return undefined;
77
- if (typeof value !== "number")
78
- throw new TypeError("limit must be a number");
79
- return value;
80
- }
81
- /** Validates and supplies the shared bounded-list limit for Task row views. */
82
- export function taskRowViewLimit(value) {
83
- return boundedListLimit(value);
84
- }
85
73
  export function sort(value) {
86
74
  if (value === undefined)
87
75
  return undefined;
@@ -90,7 +78,7 @@ export function sort(value) {
90
78
  }
91
79
  return value;
92
80
  }
93
- export function state(value) {
81
+ function state(value) {
94
82
  if (value === undefined)
95
83
  return undefined;
96
84
  if (value !== "open" && value !== "in_progress" && value !== "on_hold" && value !== "done" && value !== "drop") {
@@ -4,7 +4,6 @@ import type { AddTaskDocumentInput, AddTaskInput, TaskBatchResult, TaskMutationR
4
4
  import type { TaskCompositionResult } from "./compose.js";
5
5
  import { type TaskMutationExecutionResult } from "./mutation-result.js";
6
6
  import { z } from "zod";
7
- export type { TaskMutationExecutionResult } from "./mutation-result.js";
8
7
  export declare const TASK_MUTATION_ACTIONS: readonly ["task.add", "task.addDocument", "task.compose", "task.done", "task.drop", "task.hold", "task.resume", "task.start", "task.stop", "task.update"];
9
8
  declare const taskMutationActionSchema: z.ZodEnum<{
10
9
  "task.add": "task.add";
@@ -489,7 +488,7 @@ declare const taskBodyRequestSchema: z.ZodObject<{
489
488
  }>>]>)[]>;
490
489
  }, z.core.$strict>;
491
490
  export type TaskMutationBodyRequest = z.infer<typeof taskBodyRequestSchema>;
492
- export declare const taskMutationServiceSchema: z.ZodObject<{
491
+ declare const taskMutationServiceSchema: z.ZodObject<{
493
492
  action: z.ZodEnum<{
494
493
  "task.add": "task.add";
495
494
  "task.addDocument": "task.addDocument";
@@ -503,7 +502,7 @@ export declare const taskMutationServiceSchema: z.ZodObject<{
503
502
  "task.update": "task.update";
504
503
  }>;
505
504
  }, z.core.$strict>;
506
- export type TaskMutationService = z.infer<typeof taskMutationServiceSchema>;
505
+ type TaskMutationService = z.infer<typeof taskMutationServiceSchema>;
507
506
  export declare const forwardedTaskReferenceSchema: z.ZodObject<{
508
507
  kind: z.ZodLiteral<"served-reference">;
509
508
  action: z.ZodEnum<{
@@ -588,4 +587,4 @@ export declare function requestForwardedTask<Request extends TaskMutationRequest
588
587
  request: Request;
589
588
  signal?: AbortSignal;
590
589
  }>): Promise<TaskMutationResultForRequest<Request> | ForwardedTaskReference>;
591
- export declare function decodeTaskMutationRequest(action: TaskMutationAction, value: unknown): TaskMutationRequest;
590
+ export {};
@@ -110,7 +110,7 @@ const worldPathSchema = z.string().min(1);
110
110
  const taskBodyRequestSchema = z
111
111
  .object({ world: worldPathSchema, request: z.union(Object.values(taskRequestSchemas)) })
112
112
  .strict();
113
- export const taskMutationServiceSchema = z.object({ action: taskMutationActionSchema }).strict();
113
+ const taskMutationServiceSchema = z.object({ action: taskMutationActionSchema }).strict();
114
114
  export const forwardedTaskReferenceSchema = z
115
115
  .object({ kind: z.literal("served-reference"), action: taskMutationActionSchema })
116
116
  .strict();
@@ -245,46 +245,18 @@ export async function requestForwardedTask(input) {
245
245
  return response.reference;
246
246
  return response.result;
247
247
  }
248
- export function decodeTaskMutationRequest(action, value) {
249
- const parsed = taskRequestSchemas[action].safeParse(value);
250
- if (!parsed.success)
251
- throw new TypeError(`invalid ${action} request`);
252
- return parsed.data;
248
+ /** Absent optional fields are omitted, never republished as an explicit undefined. */
249
+ function definedFields(fields, additions = {}) {
250
+ const selected = {};
251
+ for (const [key, value] of Object.entries({ ...fields, ...additions })) {
252
+ if (value !== undefined)
253
+ selected[key] = value;
254
+ }
255
+ return selected;
253
256
  }
254
257
  function addTaskOptions(input, actor, signal) {
255
- const { body, note, state, priority, needs, parent, supersedes, relates, ...required } = input;
256
- return {
257
- ...required,
258
- actor,
259
- ...(body === undefined ? {} : { body }),
260
- ...(note === undefined ? {} : { note }),
261
- ...(state === undefined ? {} : { state }),
262
- ...(priority === undefined ? {} : { priority }),
263
- ...(needs === undefined ? {} : { needs }),
264
- ...(parent === undefined ? {} : { parent }),
265
- ...(supersedes === undefined ? {} : { supersedes }),
266
- ...(relates === undefined ? {} : { relates }),
267
- ...(signal === undefined ? {} : { signal }),
268
- };
258
+ return definedFields(input, { actor, signal });
269
259
  }
270
260
  function updateTaskOptions(input, signal) {
271
- const { title, body, appendBody, note, priority, needs, addNeeds, dropNeeds, parent, supersedes, addSupersedes, dropSupersedes, relates, addRelates, dropRelates, } = input;
272
- return {
273
- ...(title === undefined ? {} : { title }),
274
- ...(body === undefined ? {} : { body }),
275
- ...(appendBody === undefined ? {} : { appendBody }),
276
- ...(note === undefined ? {} : { note }),
277
- ...(priority === undefined ? {} : { priority }),
278
- ...(needs === undefined ? {} : { needs }),
279
- ...(addNeeds === undefined ? {} : { addNeeds }),
280
- ...(dropNeeds === undefined ? {} : { dropNeeds }),
281
- ...(parent === undefined ? {} : { parent }),
282
- ...(supersedes === undefined ? {} : { supersedes }),
283
- ...(addSupersedes === undefined ? {} : { addSupersedes }),
284
- ...(dropSupersedes === undefined ? {} : { dropSupersedes }),
285
- ...(relates === undefined ? {} : { relates }),
286
- ...(addRelates === undefined ? {} : { addRelates }),
287
- ...(dropRelates === undefined ? {} : { dropRelates }),
288
- ...(signal === undefined ? {} : { signal }),
289
- };
261
+ return definedFields(input, { signal });
290
262
  }
@@ -3,23 +3,18 @@ import { type TaskId } from "./identity.js";
3
3
  import type { WorldRoot } from "../world.js";
4
4
  import { type TaskPage, type TaskQueryExpression, type TaskQueryRow, type TaskQuerySort } from "./query.js";
5
5
  export { advanceTaskTimestamp, taskView } from "./view.js";
6
- export type { AddTaskDocumentInput, AddTaskInput, TaskCleanupFailure, SettledTaskAction, SettledTaskResult, TaskBatchResult, TaskCompositionDiagnostic, TaskLifecycleVerb, TaskMutationResult, TaskOutcome, TaskRefusal, TaskRetry, TaskUpdateResult, TaskView, UpdateTaskInput, } from "./operation-types.js";
7
- import type { AddTaskDocumentInput, AddTaskInput, TaskMutationResult, TaskOutcome, TaskUpdateResult, TaskView, UpdateTaskInput } from "./operation-types.js";
6
+ export type { AddTaskDocumentInput, AddTaskInput, TaskCleanupFailure, SettledTaskResult, TaskBatchResult, TaskCompositionDiagnostic, TaskMutationResult, TaskOutcome, TaskRefusal, TaskRetry, TaskUpdateResult, TaskView, UpdateTaskInput, } from "./operation-types.js";
7
+ import type { AddTaskDocumentInput, AddTaskInput, TaskMutationResult, TaskOutcome, TaskUpdateResult, UpdateTaskInput } from "./operation-types.js";
8
8
  export declare function nukeTask(world: WorldRoot, options?: Readonly<{
9
9
  timeoutMs?: number;
10
10
  onRemoved?(count: number): void;
11
11
  }>): Promise<number>;
12
- export type { TaskState } from "./document.js";
13
12
  export declare function addTask(world: WorldRoot, input: AddTaskInput): Promise<TaskMutationResult>;
14
13
  export declare function addTaskDocument(world: WorldRoot, input: AddTaskDocumentInput): Promise<TaskMutationResult>;
15
14
  export declare function updateTask(world: WorldRoot, id: TaskId, input: UpdateTaskInput): Promise<TaskUpdateResult>;
16
15
  export { batchTasks, lifecycleTask, settleTask } from "./lifecycle-operations.js";
17
16
  export declare function listTasks(world: WorldRoot, namespace: readonly string[] | undefined, selection: "active" | "closed" | "all", scope?: "namespace" | "world", limit?: number): Promise<TaskOutcome<TaskPage<TaskRow>>>;
18
17
  export declare function readTaskDetail(world: WorldRoot, id: TaskId): Promise<TaskDetailFacts | null>;
19
- export declare function readTaskDetails(world: WorldRoot, ids: readonly TaskId[]): Promise<TaskOutcome<readonly TaskDetailFacts[]>>;
20
- export declare function observeTaskDetails(world: WorldRoot, ids: readonly TaskId[]): Promise<TaskOutcome<readonly (Omit<TaskDetailFacts, "task"> & Readonly<{
21
- task: TaskView;
22
- }>)[]>>;
23
18
  export declare function readyTasks(world: WorldRoot, namespace: readonly string[] | undefined, scope?: "namespace" | "world", parent?: TaskId, limit?: number): Promise<TaskOutcome<TaskPage<TaskRow>>>;
24
19
  export declare function blockedTasks(world: WorldRoot, namespace: readonly string[] | undefined, scope?: "namespace" | "world", parent?: TaskId, limit?: number): Promise<TaskOutcome<TaskPage<BlockedTaskRow>>>;
25
20
  export declare function queryTasks(input: Readonly<{
@@ -4,8 +4,7 @@ import { createTaskRelations, projectOwnedDetailFacts, projectTaskBoardObservati
4
4
  import { parseTaskCreationDocument, serializeTaskDocument, } from "./document.js";
5
5
  import { allocateLocalId, deriveLocalStem, formatTaskId } from "./identity.js";
6
6
  import { nukeTaskAuthority, readBoard, readTaskDocument, replaceAuthority, withTaskLocks } from "./store.js";
7
- import { projectBoundedList } from "../bounded-list.js";
8
- import { taskRowViewLimit } from "./input.js";
7
+ import { boundedListLimit, projectBoundedList } from "../bounded-list.js";
9
8
  import { projectQuery, projectQueryRows, queryUnderTargets, underExpression, } from "./query.js";
10
9
  import { advanceTaskTimestamp, taskView } from "./view.js";
11
10
  export { advanceTaskTimestamp, taskView } from "./view.js";
@@ -184,7 +183,7 @@ function readScope(namespace, scope) {
184
183
  return scope === "world" ? null : (namespace ?? []);
185
184
  }
186
185
  export async function listTasks(world, namespace, selection, scope, limit) {
187
- const selectedLimit = taskRowViewLimit(limit);
186
+ const selectedLimit = boundedListLimit(limit);
188
187
  const selected = readScope(namespace, scope);
189
188
  const board = (await readBoard(world)).board;
190
189
  return {
@@ -212,62 +211,51 @@ export async function readTaskDetail(world, id) {
212
211
  }
213
212
  return projectOwnedDetailFacts({ tasks: selected }, id);
214
213
  }
215
- export async function readTaskDetails(world, ids) {
216
- const details = [];
217
- for (const id of ids) {
218
- const detail = await readTaskDetail(world, id);
219
- if (detail === null)
220
- return { kind: "refused", refusal: { kind: "task-missing", taskId: id } };
221
- details.push(detail);
222
- }
223
- return { kind: "accepted", value: details };
224
- }
225
- export async function observeTaskDetails(world, ids) {
226
- const observed = await readTaskDetails(world, ids);
227
- if (observed.kind !== "accepted")
228
- return observed;
229
- return { kind: "accepted", value: observed.value.map((facts) => ({ ...facts, task: taskView(facts.task) })) };
214
+ /** One board observation and predicate projection shared by the ready and blocked views. */
215
+ async function readTaskQueryContext(input) {
216
+ const board = (await readBoard(input.world)).board;
217
+ if (input.parent !== undefined && !board.tasks.has(input.parent))
218
+ return { kind: "refused", refusal: { kind: "task-missing", taskId: input.parent } };
219
+ const relations = createTaskRelations(board);
220
+ const scope = readScope(input.namespace, input.scope);
221
+ const predicate = {
222
+ kind: "predicate",
223
+ predicate: { field: input.field, operator: "=", value: true },
224
+ };
225
+ return {
226
+ kind: "accepted",
227
+ value: {
228
+ limit: boundedListLimit(input.limit),
229
+ board,
230
+ scope,
231
+ relations,
232
+ rows: projectQueryRows(board, relations, {
233
+ scope,
234
+ expression: input.parent === undefined ? predicate : { kind: "and", terms: [predicate, underExpression(input.parent)] },
235
+ }),
236
+ },
237
+ };
230
238
  }
231
239
  export async function readyTasks(world, namespace, scope, parent, limit) {
232
- const selectedLimit = taskRowViewLimit(limit);
233
- const selected = readScope(namespace, scope);
234
- const board = (await readBoard(world)).board;
235
- if (parent !== undefined && !board.tasks.has(parent))
236
- return { kind: "refused", refusal: { kind: "task-missing", taskId: parent } };
237
- const relations = createTaskRelations(board);
238
- const ready = { kind: "predicate", predicate: { field: "ready", operator: "=", value: true } };
239
- const expression = parent === undefined ? ready : { kind: "and", terms: [ready, underExpression(parent)] };
240
- const selectedRows = projectQueryRows(board, relations, {
241
- scope: selected,
242
- expression,
243
- });
244
- const rows = selectedRows.map(({ parent: _parent, needs: _needs, blocks: _blocks, createdAt: _createdAt, ...row }) => row);
245
- return { kind: "accepted", value: projectBoundedList(rows, selectedLimit) };
240
+ const queried = await readTaskQueryContext({ world, field: "ready", namespace, scope, parent, limit });
241
+ if (queried.kind !== "accepted")
242
+ return queried;
243
+ const rows = queried.value.rows.map(({ parent: _parent, needs: _needs, blocks: _blocks, createdAt: _createdAt, ...row }) => row);
244
+ return { kind: "accepted", value: projectBoundedList(rows, queried.value.limit) };
246
245
  }
247
246
  export async function blockedTasks(world, namespace, scope, parent, limit) {
248
- const selectedLimit = taskRowViewLimit(limit);
249
- const selected = readScope(namespace, scope);
250
- const board = (await readBoard(world)).board;
251
- if (parent !== undefined && !board.tasks.has(parent))
252
- return { kind: "refused", refusal: { kind: "task-missing", taskId: parent } };
253
- const relations = createTaskRelations(board);
254
- const blocked = {
255
- kind: "predicate",
256
- predicate: { field: "blocked", operator: "=", value: true },
257
- };
258
- const expression = parent === undefined ? blocked : { kind: "and", terms: [blocked, underExpression(parent)] };
259
- const selectedRows = projectQueryRows(board, relations, {
260
- scope: selected,
261
- expression,
262
- });
263
- const ids = new Set(selectedRows.map((row) => row.id));
247
+ const queried = await readTaskQueryContext({ world, field: "blocked", namespace, scope, parent, limit });
248
+ if (queried.kind !== "accepted")
249
+ return queried;
250
+ const { board, scope: selected, relations, limit: selectedLimit, rows } = queried.value;
251
+ const ids = new Set(rows.map((row) => row.id));
264
252
  return {
265
253
  kind: "accepted",
266
254
  value: projectBoundedList(projectBlocked(board, selected, relations).filter((row) => ids.has(row.id)), selectedLimit),
267
255
  };
268
256
  }
269
257
  export async function queryTasks(input) {
270
- const selectedLimit = taskRowViewLimit(input.limit);
258
+ const selectedLimit = boundedListLimit(input.limit);
271
259
  const selected = readScope(input.namespace, input.scope);
272
260
  const board = (await readBoard(input.world)).board;
273
261
  const relations = createTaskRelations(board);
@@ -4,7 +4,6 @@ import type { TaskBoard, TaskRef, TaskRelationProjection, TaskRow } from "./boar
4
4
  import { type BoundedList } from "../bounded-list.js";
5
5
  export declare const TASK_RELATION_PREDICATE_FIELDS: readonly ["under", "needs", "blocks"];
6
6
  export type TaskRelationPredicateField = (typeof TASK_RELATION_PREDICATE_FIELDS)[number];
7
- export type TaskQueryComparison = "=" | "!=" | "<" | "<=" | ">" | ">=" | "~";
8
7
  export type TaskQueryPredicate = Readonly<{
9
8
  field: "state";
10
9
  operator: "=" | "!=";
@@ -2,9 +2,6 @@ import { formatTaskId, parseTaskId, sameNamespace } from "./identity.js";
2
2
  import { projectTaskRow, taskBlocked, taskDisposition, taskRef } from "./board.js";
3
3
  import { projectBoundedList } from "../bounded-list.js";
4
4
  export const TASK_RELATION_PREDICATE_FIELDS = ["under", "needs", "blocks"];
5
- function isTaskRelationPredicateField(value) {
6
- return TASK_RELATION_PREDICATE_FIELDS.includes(value);
7
- }
8
5
  const states = ["open", "in_progress", "on_hold", "done", "drop"];
9
6
  const comparisons = ["=", "!=", "<", "<=", ">", ">=", "~"];
10
7
  function fail(message) {
@@ -129,7 +126,7 @@ export function normalizeTaskQueryPredicate(value) {
129
126
  case "updated":
130
127
  return normalizeTimestampPredicate(input, "updated", operator);
131
128
  default:
132
- if (isTaskRelationPredicateField(field))
129
+ if (field === "under" || field === "needs" || field === "blocks")
133
130
  return normalizeRelationPredicate(input, field, operator);
134
131
  return invalidPredicate(`unknown query field: ${field}`, "field");
135
132
  }
@@ -7,7 +7,6 @@ export type BoardSnapshot = Readonly<{
7
7
  board: TaskBoard;
8
8
  bytes: ReadonlyMap<TaskId, Uint8Array>;
9
9
  }>;
10
- export declare const DEFAULT_TASK_LOCK_TIMEOUT_MS = 3000;
11
10
  export declare function readBoard(world: WorldRoot): Promise<BoardSnapshot>;
12
11
  export declare function readRecentTaskDocuments(world: WorldRoot, input: Readonly<{
13
12
  namespace?: readonly string[];
@@ -33,4 +32,3 @@ export declare function withTaskLocks<T>(input: Readonly<{
33
32
  timeoutMs?: number;
34
33
  signal?: AbortSignal;
35
34
  }>, action: () => Promise<T>): Promise<T | "busy">;
36
- export declare function authorityPath(world: WorldRoot, id: TaskId): string;
@@ -7,7 +7,7 @@ import { syncDirectory } from "../coordination/durable-file.js";
7
7
  import { boundedListLimit, projectBoundedList } from "../bounded-list.js";
8
8
  import { parseTaskDocument } from "./document.js";
9
9
  import { formatTaskId, parseTaskId, physicalTaskSegment, TASK_LOCAL_ID_BYTES, sameNamespace, taskAuthorityPath, } from "./identity.js";
10
- export const DEFAULT_TASK_LOCK_TIMEOUT_MS = 3_000;
10
+ const DEFAULT_TASK_LOCK_TIMEOUT_MS = 3_000;
11
11
  function tasksDirectory(world) {
12
12
  return resolve(world, ".keiyaku", "tasks");
13
13
  }
@@ -130,16 +130,35 @@ async function removeEmptyTaskDirectories(directory, removeSelf) {
130
130
  }
131
131
  export async function readBoard(world) {
132
132
  const directory = tasksDirectory(world);
133
+ const paths = await authorityFiles(directory);
134
+ const reads = new Array(paths.length);
135
+ let next = 0;
136
+ const worker = async () => {
137
+ while (next < paths.length) {
138
+ const index = next++;
139
+ const path = paths[index];
140
+ try {
141
+ const stat = await lstat(path);
142
+ if (!stat.isFile() || stat.isSymbolicLink()) {
143
+ throw new Error(`Task authority is not a regular file: ${path}`);
144
+ }
145
+ const coordinate = coordinateFromPath(directory, path);
146
+ reads[index] = { kind: "read", coordinate, source: await readFile(path) };
147
+ }
148
+ catch (error) {
149
+ reads[index] = { kind: "failed", error };
150
+ }
151
+ }
152
+ };
153
+ // Drain all owned reads; authority and errors are then judged in canonical path order.
154
+ await Promise.all(Array.from({ length: Math.min(8, paths.length) }, worker));
133
155
  const tasks = new Map();
134
156
  const bytes = new Map();
135
- for (const path of await authorityFiles(directory)) {
136
- const stat = await lstat(path);
137
- if (!stat.isFile() || stat.isSymbolicLink()) {
138
- throw new Error(`Task authority is not a regular file: ${path}`);
139
- }
140
- const coordinate = coordinateFromPath(directory, path);
157
+ for (const read of reads) {
158
+ if (read.kind === "failed")
159
+ throw read.error;
160
+ const { coordinate, source } = read;
141
161
  const id = formatTaskId(coordinate);
142
- const source = await readFile(path);
143
162
  tasks.set(id, parseTaskDocument(source, coordinate));
144
163
  bytes.set(id, source);
145
164
  }
@@ -315,6 +334,3 @@ export async function withTaskLocks(input, action) {
315
334
  }
316
335
  return result;
317
336
  }
318
- export function authorityPath(world, id) {
319
- return taskAuthorityPath(tasksDirectory(world), parseTaskId(id));
320
- }
@@ -1,9 +1,10 @@
1
1
  import { gate } from "../core/facts/types.js";
2
2
  export const VERIFIED = gate("verified");
3
3
  export function prepareVerificationDeclaration(input) {
4
- if (input.definition !== null || !input.gates.includes(VERIFIED)) {
4
+ if (!input.gates.includes(VERIFIED))
5
+ return { kind: "prepared", data: null };
6
+ if (input.definition !== null)
5
7
  return { kind: "prepared", data: input.definition };
6
- }
7
8
  return {
8
9
  kind: "refused",
9
10
  refusal: {
@@ -1,4 +1,4 @@
1
- import type { SnapshotId } from "../core/facts/types.js";
1
+ import type { ContractId, SnapshotId } from "../core/facts/types.js";
2
2
  import { type HookFailure } from "../git/hooks.js";
3
3
  import type { MaterializedScratchCandidate, WorktreeLeak } from "../git/scratch.js";
4
4
  import type { GitRepository } from "../git/process.js";
@@ -51,8 +51,9 @@ export type VerificationExecution = Readonly<{
51
51
  export type ExecuteVerificationInput = Readonly<{
52
52
  repository: GitRepository;
53
53
  candidate: SnapshotId;
54
+ contractId: ContractId;
54
55
  declarations: readonly VerificationDeclaration[];
55
- materializeScratchCandidate: (repository: GitRepository, candidate: SnapshotId) => Promise<MaterializedScratchCandidate>;
56
+ materializeScratchCandidate: (repository: GitRepository, candidate: SnapshotId, contract: ContractId) => Promise<MaterializedScratchCandidate>;
56
57
  projectSettings: (root: string) => Promise<Settings>;
57
58
  observe?: (event: VerificationObservation) => void;
58
59
  signal?: AbortSignal;