@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.
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +135 -377
- package/build/integrations/pi/keiyaku.ts +11 -116
- package/build/src/akuma/akuma-errors.d.ts +1 -0
- package/build/src/akuma/akuma-errors.js +1 -0
- package/build/src/akuma/akuma-handle.d.ts +1 -0
- package/build/src/akuma/akuma-handle.js +6 -7
- package/build/src/akuma/akuma-product.d.ts +6 -8
- package/build/src/akuma/akuma-product.js +141 -57
- package/build/src/akuma/akuma.d.ts +5 -7
- package/build/src/akuma/akuma.js +1 -22
- package/build/src/akuma/archetype.d.ts +6 -5
- package/build/src/akuma/archetype.js +137 -38
- package/build/src/akuma/body.d.ts +5 -5
- package/build/src/akuma/body.js +223 -63
- package/build/src/akuma/call-input.d.ts +4 -0
- package/build/src/akuma/call-input.js +21 -0
- package/build/src/akuma/call-request.d.ts +5 -8
- package/build/src/akuma/call-request.js +28 -73
- package/build/src/akuma/fleet-execution.d.ts +26 -0
- package/build/src/akuma/fleet-execution.js +109 -0
- package/build/src/{library/fleet-result.d.ts → akuma/fleet-observation.d.ts} +13 -57
- package/build/src/{library/fleet-result.js → akuma/fleet-observation.js} +4 -25
- package/build/src/akuma/fleet-request.d.ts +122 -0
- package/build/src/akuma/fleet-request.js +168 -0
- package/build/src/akuma/heart/facts.d.ts +23 -0
- package/build/src/akuma/heart/facts.js +7 -0
- package/build/src/akuma/heart/index.d.ts +43 -4
- package/build/src/akuma/heart/index.js +107 -7
- package/build/src/akuma/heart/request-authority.d.ts +2 -0
- package/build/src/akuma/heart/request-authority.js +28 -3
- package/build/src/akuma/heart/request-rows.d.ts +2 -0
- package/build/src/akuma/heart/request-rows.js +24 -5
- package/build/src/akuma/heart/rows.d.ts +4 -1
- package/build/src/akuma/heart/rows.js +46 -19
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +28 -6
- package/build/src/akuma/heart/storage.d.ts +1 -1
- package/build/src/akuma/heart/tells.d.ts +29 -0
- package/build/src/akuma/heart/tells.js +136 -5
- package/build/src/akuma/heart/timeline.js +9 -3
- package/build/src/akuma/projection-read.js +36 -3
- package/build/src/akuma/projection.js +3 -4
- package/build/src/akuma/provider.d.ts +4 -0
- package/build/src/akuma/provider.js +56 -3
- package/build/src/akuma/providers/claude/index.js +3 -0
- package/build/src/akuma/providers/codex-app-server/index.js +14 -12
- package/build/src/akuma/providers/pi/index.js +7 -1
- package/build/src/akuma/publication.js +65 -49
- package/build/src/akuma/request-lifecycle.d.ts +5 -4
- package/build/src/akuma/request-lifecycle.js +29 -16
- package/build/src/akuma/request-rendezvous.d.ts +15 -12
- package/build/src/akuma/request-rendezvous.js +80 -51
- package/build/src/akuma/request-serve.d.ts +1 -2
- package/build/src/akuma/request-serve.js +94 -39
- package/build/src/akuma/request-wire.d.ts +57 -26
- package/build/src/akuma/request-wire.js +64 -25
- package/build/src/akuma/turn-drive.d.ts +5 -4
- package/build/src/akuma/turn-drive.js +27 -11
- package/build/src/akuma-body.d.ts +4 -6
- package/build/src/akuma-body.js +19 -17
- package/build/src/bounded-list.d.ts +8 -0
- package/build/src/bounded-list.js +14 -0
- package/build/src/cli/accepted.d.ts +1 -1
- package/build/src/cli/accepted.js +1 -0
- package/build/src/cli/commands/akuma-invoke.js +1 -25
- package/build/src/cli/commands/contract-help.d.ts +5 -2
- package/build/src/cli/commands/contract-help.js +62 -12
- package/build/src/cli/commands/contract-invoke.d.ts +5 -0
- package/build/src/cli/commands/contract-invoke.js +26 -1
- package/build/src/cli/commands/contract.js +50 -18
- package/build/src/cli/commands/task-invoke.js +10 -2
- package/build/src/cli/commands/task-query.js +3 -4
- package/build/src/cli/coordinates.d.ts +13 -0
- package/build/src/cli/coordinates.js +38 -24
- package/build/src/cli/draft.d.ts +1 -1
- package/build/src/cli/invoke.js +14 -1
- package/build/src/cli/render/akuma-activity.d.ts +0 -1
- package/build/src/cli/render/akuma-activity.js +5 -38
- package/build/src/cli/render/akuma.js +4 -1
- package/build/src/cli/render/audit.js +4 -1
- package/build/src/cli/render/catalog.js +13 -39
- package/build/src/cli/render/contract.js +4 -14
- package/build/src/cli/render/kanshi-akuma.js +3 -8
- package/build/src/cli/render/kanshi.js +8 -34
- package/build/src/cli/render/nuke.js +7 -3
- package/build/src/cli/render/receipt.d.ts +1 -0
- package/build/src/cli/render/receipt.js +8 -0
- package/build/src/cli/render/refusal.js +4 -3
- package/build/src/cli/render/task.js +4 -37
- package/build/src/cli/render/terminal.d.ts +2 -6
- package/build/src/cli/render/terminal.js +4 -9
- package/build/src/cli/result.d.ts +2 -1
- package/build/src/contract-guidance.js +13 -3
- package/build/src/contract-worktree.d.ts +1 -0
- package/build/src/contract-worktree.js +26 -2
- package/build/src/core/facts/codec.d.ts +2 -1
- package/build/src/core/facts/codec.js +3 -0
- package/build/src/core/facts/gate.d.ts +2 -1
- package/build/src/core/facts/gate.js +63 -0
- package/build/src/core/verbs/abandon.d.ts +2 -1
- package/build/src/core/verbs/abandon.js +16 -0
- package/build/src/core/verbs/amend.d.ts +2 -1
- package/build/src/core/verbs/amend.js +20 -0
- package/build/src/core/verbs/arc.d.ts +2 -1
- package/build/src/core/verbs/arc.js +16 -0
- package/build/src/core/verbs/attestation.d.ts +2 -1
- package/build/src/core/verbs/attestation.js +16 -0
- package/build/src/core/verbs/bind.d.ts +2 -1
- package/build/src/core/verbs/bind.js +16 -0
- package/build/src/core/verbs/deliver.d.ts +2 -1
- package/build/src/core/verbs/deliver.js +16 -0
- package/build/src/core/verbs/placement.d.ts +2 -1
- package/build/src/core/verbs/placement.js +58 -1
- package/build/src/dispatch/association.d.ts +13 -0
- package/build/src/dispatch/association.js +20 -0
- package/build/src/dispatch/index.d.ts +6 -0
- package/build/src/dispatch/index.js +27 -3
- package/build/src/git/hooks.d.ts +9 -1
- package/build/src/git/hooks.js +79 -1
- package/build/src/git/nuke.d.ts +2 -1
- package/build/src/git/nuke.js +6 -11
- package/build/src/git/private-state-seat.d.ts +26 -1
- package/build/src/git/private-state-seat.js +78 -13
- package/build/src/git/process.d.ts +2 -0
- package/build/src/git/reconcile.d.ts +1 -2
- package/build/src/git/reconcile.js +0 -6
- package/build/src/git/repository.d.ts +0 -2
- package/build/src/git/repository.js +27 -25
- package/build/src/git/result-codec.d.ts +29 -0
- package/build/src/git/result-codec.js +306 -0
- package/build/src/git/target-placement.js +2 -8
- package/build/src/git/workspace.d.ts +2 -0
- package/build/src/git/workspace.js +4 -0
- package/build/src/index.d.ts +1 -0
- package/build/src/kanshi/fleet.js +1 -1
- package/build/src/kanshi/read.js +55 -28
- package/build/src/kanshi/report.d.ts +4 -3
- package/build/src/kanshi/select.js +14 -1
- package/build/src/library/address.d.ts +1 -0
- package/build/src/library/address.js +4 -7
- package/build/src/library/akuma-creation.d.ts +5 -3
- package/build/src/library/akuma-creation.js +90 -33
- package/build/src/library/audit.js +2 -1
- package/build/src/library/catalog.d.ts +10 -2
- package/build/src/library/catalog.js +65 -25
- package/build/src/library/composition.d.ts +1 -0
- package/build/src/library/composition.js +1 -0
- package/build/src/library/configuration.d.ts +4 -21
- package/build/src/library/configuration.js +2 -158
- package/build/src/library/continuation.d.ts +20 -1
- package/build/src/library/continuation.js +36 -0
- package/build/src/library/contract-bind.d.ts +1 -0
- package/build/src/library/contract-bind.js +16 -5
- package/build/src/library/contract-forwarding.d.ts +2 -2
- package/build/src/library/contract-forwarding.js +18 -4
- package/build/src/library/contract-handle.js +4 -3
- package/build/src/library/contract-operations.d.ts +5 -9
- package/build/src/library/contract-operations.js +34 -47
- package/build/src/library/contract.d.ts +11 -2
- package/build/src/library/contract.js +21 -1
- package/build/src/library/delivery.d.ts +4 -1
- package/build/src/library/delivery.js +47 -0
- package/build/src/library/fleet.d.ts +4 -136
- package/build/src/library/fleet.js +31 -315
- package/build/src/library/keiyaku.d.ts +7 -3
- package/build/src/library/keiyaku.js +1 -0
- package/build/src/library/mutation.d.ts +431 -3
- package/build/src/library/mutation.js +192 -19
- package/build/src/library/nuke.d.ts +7 -1
- package/build/src/library/nuke.js +18 -4
- package/build/src/library/reconcile.d.ts +14 -0
- package/build/src/library/reconcile.js +22 -8
- package/build/src/library/refusal.d.ts +9 -1
- package/build/src/library/refusal.js +76 -0
- package/build/src/library/region.d.ts +0 -8
- package/build/src/library/region.js +1 -29
- package/build/src/library/result-codec.d.ts +2 -0
- package/build/src/library/result-codec.js +12 -0
- package/build/src/markdown/lex.js +9 -2
- package/build/src/markdown/types.d.ts +2 -1
- package/build/src/markdown/types.js +3 -1
- package/build/src/plugin/akuma-signals.d.ts +12 -0
- package/build/src/plugin/akuma-signals.js +14 -0
- package/build/src/plugin/public.d.ts +51 -0
- package/build/src/plugin/public.js +1 -0
- package/build/src/plugin/runtime.d.ts +14 -0
- package/build/src/plugin/runtime.js +357 -0
- package/build/src/protocol/amend.js +3 -3
- package/build/src/protocol/attempt.d.ts +2 -1
- package/build/src/protocol/attempt.js +1 -1
- package/build/src/protocol/audit.d.ts +1 -1
- package/build/src/protocol/audit.js +1 -1
- package/build/src/protocol/bind.d.ts +3 -1
- package/build/src/protocol/bind.js +26 -0
- package/build/src/protocol/completion.js +0 -1
- package/build/src/protocol/deliver.d.ts +1 -1
- package/build/src/protocol/deliver.js +136 -57
- package/build/src/protocol/intent.d.ts +0 -1
- package/build/src/protocol/intent.js +0 -1
- package/build/src/protocol/operations.d.ts +9 -2
- package/build/src/protocol/operations.js +16 -1
- package/build/src/protocol/outcome.d.ts +3 -0
- package/build/src/protocol/outcome.js +17 -1
- package/build/src/protocol/placement.js +10 -3
- package/build/src/protocol/read/status.d.ts +8 -0
- package/build/src/protocol/read/status.js +49 -0
- package/build/src/protocol/reintegrate.js +10 -3
- package/build/src/protocol/result-codec.d.ts +22 -0
- package/build/src/protocol/result-codec.js +442 -0
- package/build/src/protocol/review.d.ts +1 -1
- package/build/src/protocol/review.js +81 -46
- package/build/src/protocol/run.d.ts +22 -2
- package/build/src/protocol/run.js +119 -29
- package/build/src/runtime/proc/lifecycle.js +1 -1
- package/build/src/runtime/proc/line-rpc.d.ts +7 -1
- package/build/src/runtime/proc/line-rpc.js +49 -9
- package/build/src/runtime/proc/run.d.ts +0 -1
- package/build/src/runtime/proc/run.js +1 -11
- package/build/src/runtime/proc/termination.d.ts +1 -0
- package/build/src/runtime/proc/termination.js +63 -18
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/build/src/settings.d.ts +10 -0
- package/build/src/settings.js +88 -2
- package/build/src/settlement/result-codec.d.ts +2 -0
- package/build/src/settlement/result-codec.js +56 -0
- package/build/src/settlement/settle.d.ts +5 -12
- package/build/src/settlement/settle.js +60 -55
- package/build/src/task/board.d.ts +3 -0
- package/build/src/task/board.js +22 -4
- package/build/src/task/catalog.d.ts +13 -2
- package/build/src/task/catalog.js +59 -5
- package/build/src/task/compose.d.ts +4 -2
- package/build/src/task/compose.js +56 -30
- package/build/src/task/created-observation.d.ts +39 -0
- package/build/src/task/created-observation.js +26 -0
- package/build/src/task/identity.d.ts +6 -0
- package/build/src/task/identity.js +48 -7
- package/build/src/task/index.d.ts +4 -3
- package/build/src/task/index.js +19 -16
- package/build/src/task/input.d.ts +3 -1
- package/build/src/task/input.js +7 -4
- package/build/src/task/lifecycle-operations.d.ts +6 -0
- package/build/src/task/lifecycle-operations.js +116 -0
- package/build/src/task/mutation-result.d.ts +762 -20
- package/build/src/task/mutation-result.js +34 -9
- package/build/src/task/mutation.d.ts +4 -9
- package/build/src/task/mutation.js +17 -52
- package/build/src/task/operation-types.d.ts +114 -0
- package/build/src/task/operation-types.js +1 -0
- package/build/src/task/operations.d.ts +6 -113
- package/build/src/task/operations.js +75 -117
- package/build/src/task/query.d.ts +8 -11
- package/build/src/task/query.js +7 -14
- package/build/src/task/store.d.ts +11 -1
- package/build/src/task/store.js +169 -55
- package/build/src/task/view.d.ts +4 -0
- package/build/src/task/view.js +7 -0
- package/build/src/verification/declaration.d.ts +1 -0
- package/build/src/verification/declaration.js +18 -1
- package/build/src/verification/execution.d.ts +0 -1
- package/build/src/verification/execution.js +5 -5
- package/build/src/world.d.ts +0 -2
- package/build/src/world.js +3 -7
- package/package.json +17 -5
- package/build/src/cli/square-edge.d.ts +0 -7
- package/build/src/cli/square-edge.js +0 -159
- package/build/src/git/ref-migration.d.ts +0 -22
- package/build/src/git/ref-migration.js +0 -55
- package/build/src/library/contract-forwarding-reconciliation-result.d.ts +0 -102
- package/build/src/library/contract-forwarding-reconciliation-result.js +0 -92
- package/build/src/library/contract-forwarding-result.d.ts +0 -4270
- package/build/src/library/contract-forwarding-result.js +0 -521
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
import { type ContractId, type ContractState } from "../core/facts/types.js";
|
|
2
|
+
import { type PrivateStateSeatCloseLag } from "../git/private-state-seat.js";
|
|
2
3
|
import type { GitDecodeChannel } from "../git/read-observation.js";
|
|
3
4
|
import type { Effect } from "../git/reconcile.js";
|
|
4
5
|
import type { GitRepository } from "../git/process.js";
|
|
5
|
-
import type
|
|
6
|
+
import { type TaskId } from "../task/identity.js";
|
|
7
|
+
export { decodeSettlementLag } from "./result-codec.js";
|
|
6
8
|
export type SettlementAction = Readonly<{
|
|
7
9
|
kind: "task";
|
|
8
10
|
taskId: TaskId;
|
|
9
11
|
action: "done";
|
|
10
|
-
}> | Readonly<{
|
|
11
|
-
kind: "namespace-context";
|
|
12
|
-
path: string;
|
|
13
|
-
action: "installed" | "kept";
|
|
14
12
|
}>;
|
|
15
13
|
export type SettlementLag = Readonly<{
|
|
16
14
|
kind: "settlement-failed";
|
|
17
|
-
surface: "task-holder" | "task"
|
|
15
|
+
surface: "task-holder" | "task";
|
|
18
16
|
contractId: ContractId;
|
|
19
17
|
taskId?: TaskId;
|
|
20
18
|
path?: string;
|
|
@@ -23,13 +21,8 @@ export type SettlementLag = Readonly<{
|
|
|
23
21
|
export type SettlementReport = Readonly<{
|
|
24
22
|
actions: readonly SettlementAction[];
|
|
25
23
|
lags: readonly SettlementLag[];
|
|
24
|
+
seatClose?: readonly PrivateStateSeatCloseLag[];
|
|
26
25
|
}>;
|
|
27
|
-
export declare function deferredTaskHolderSettlement(input: Readonly<{
|
|
28
|
-
contractId: ContractId;
|
|
29
|
-
taskId: TaskId;
|
|
30
|
-
diagnostic: string;
|
|
31
|
-
}>): SettlementReport;
|
|
32
|
-
export declare function contractNamespace(id: ContractId): readonly [string];
|
|
33
26
|
export type SettlementInput = Readonly<{
|
|
34
27
|
repository: GitRepository;
|
|
35
28
|
channel: GitDecodeChannel;
|
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
import { contractSegment } from "../core/facts/types.js";
|
|
2
1
|
import { observeContractsForAdmissionAt } from "../git/observe.js";
|
|
3
|
-
import { withPrivateStatePublicationSeat } from "../git/private-state-seat.js";
|
|
4
|
-
import { repairNamespaceContext } from "../task/context.js";
|
|
2
|
+
import { appendPrivateStateSeatClose, withPrivateStatePublicationSeat, } from "../git/private-state-seat.js";
|
|
5
3
|
import { settleTask } from "../task/operations.js";
|
|
6
4
|
import { publishTaskHolderRelease, readTaskHolderProjectionFromDecision, taskHolderObservationSelection, } from "./holder.js";
|
|
7
5
|
import { acquireTaskSettlementFence } from "./fence.js";
|
|
8
6
|
import { World } from "../world.js";
|
|
9
|
-
export
|
|
10
|
-
return { actions: [], lags: [{ kind: "settlement-failed", surface: "task-holder", ...input }] };
|
|
11
|
-
}
|
|
12
|
-
export function contractNamespace(id) {
|
|
13
|
-
return [contractSegment(id)];
|
|
14
|
-
}
|
|
7
|
+
export { decodeSettlementLag } from "./result-codec.js";
|
|
15
8
|
function diagnostic(error) {
|
|
16
9
|
return error instanceof Error ? error.message : String(error);
|
|
17
10
|
}
|
|
@@ -73,6 +66,17 @@ async function completeHeldTask(input) {
|
|
|
73
66
|
}
|
|
74
67
|
if (result.kind === "changed")
|
|
75
68
|
actions.push({ kind: "task", taskId, action: "done" });
|
|
69
|
+
if (result.kind === "changed" && result.cleanup !== undefined) {
|
|
70
|
+
for (const detail of result.cleanup.diagnostics) {
|
|
71
|
+
lags.push({
|
|
72
|
+
kind: "settlement-failed",
|
|
73
|
+
surface: "task",
|
|
74
|
+
contractId: candidate.id,
|
|
75
|
+
taskId,
|
|
76
|
+
diagnostic: detail,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
76
80
|
if (result.kind === "changed" || result.kind === "unchanged")
|
|
77
81
|
return true;
|
|
78
82
|
lags.push({
|
|
@@ -85,16 +89,16 @@ async function completeHeldTask(input) {
|
|
|
85
89
|
return false;
|
|
86
90
|
}
|
|
87
91
|
async function releaseHeldTaskHolder(input) {
|
|
88
|
-
const { repository, channel, candidate, lags, taskId } = input;
|
|
92
|
+
const { repository, channel, candidate, lags, seatClose, taskId } = input;
|
|
89
93
|
try {
|
|
90
|
-
await withPrivateStatePublicationSeat(repository, async (seat) => {
|
|
94
|
+
const outcome = await withPrivateStatePublicationSeat(repository, async (seat) => {
|
|
91
95
|
const observation = await observeContractsForAdmissionAt(repository, channel, [candidate.id], taskHolderObservationSelection());
|
|
92
96
|
const state = observation.journals.get(candidate.id)?.state ?? null;
|
|
93
97
|
if (state === null || state.terminal?.kind !== "claimed")
|
|
94
|
-
return;
|
|
98
|
+
return "inert";
|
|
95
99
|
const holder = (await readTaskHolderProjectionFromDecision(channel, observation)).get(candidate.id) ?? null;
|
|
96
100
|
if (holder === null || holder.disposition !== "held" || holder.taskId !== taskId)
|
|
97
|
-
return;
|
|
101
|
+
return "inert";
|
|
98
102
|
const publication = await publishTaskHolderRelease(repository, channel, observation, candidate.id, seat);
|
|
99
103
|
if (publication.kind === "non-published") {
|
|
100
104
|
lags.push({
|
|
@@ -104,8 +108,14 @@ async function releaseHeldTaskHolder(input) {
|
|
|
104
108
|
taskId,
|
|
105
109
|
diagnostic: `Task holder release requires retry: ${publication.diagnostic}`,
|
|
106
110
|
});
|
|
111
|
+
return "held";
|
|
107
112
|
}
|
|
113
|
+
return publication.kind === "released" ? "released" : "inert";
|
|
108
114
|
});
|
|
115
|
+
if (outcome.closeLag !== undefined) {
|
|
116
|
+
seatClose.push(...appendPrivateStateSeatClose(undefined, outcome.closeLag));
|
|
117
|
+
}
|
|
118
|
+
return outcome.value;
|
|
109
119
|
}
|
|
110
120
|
catch (error) {
|
|
111
121
|
lags.push({
|
|
@@ -115,10 +125,11 @@ async function releaseHeldTaskHolder(input) {
|
|
|
115
125
|
taskId,
|
|
116
126
|
diagnostic: diagnostic(error),
|
|
117
127
|
});
|
|
128
|
+
return "held";
|
|
118
129
|
}
|
|
119
130
|
}
|
|
120
131
|
async function settleTasks(input) {
|
|
121
|
-
const { repository, channel, candidate, actions, lags } = input;
|
|
132
|
+
const { repository, channel, candidate, actions, lags, seatClose } = input;
|
|
122
133
|
const hint = await observeApplicableHolder({ repository, channel, candidate, lags });
|
|
123
134
|
if (hint === null)
|
|
124
135
|
return false;
|
|
@@ -138,14 +149,22 @@ async function settleTasks(input) {
|
|
|
138
149
|
return true;
|
|
139
150
|
}
|
|
140
151
|
let taskSettled = false;
|
|
152
|
+
let holderDisposition = null;
|
|
141
153
|
try {
|
|
142
154
|
const holder = await observeApplicableHolder({ repository, channel, candidate, lags });
|
|
143
155
|
if (holder === null || holder.taskId !== taskId)
|
|
144
156
|
return false;
|
|
145
|
-
|
|
157
|
+
taskSettled = await completeHeldTask({ repository, candidate, actions, lags, taskId });
|
|
158
|
+
if (!taskSettled)
|
|
146
159
|
return true;
|
|
147
|
-
|
|
148
|
-
|
|
160
|
+
holderDisposition = await releaseHeldTaskHolder({
|
|
161
|
+
repository,
|
|
162
|
+
channel,
|
|
163
|
+
candidate,
|
|
164
|
+
taskId,
|
|
165
|
+
lags,
|
|
166
|
+
seatClose,
|
|
167
|
+
});
|
|
149
168
|
return true;
|
|
150
169
|
}
|
|
151
170
|
finally {
|
|
@@ -155,66 +174,52 @@ async function settleTasks(input) {
|
|
|
155
174
|
catch (error) {
|
|
156
175
|
if (!taskSettled)
|
|
157
176
|
throw error;
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
177
|
+
// Post-release fence teardown is custodial residue, not an owed holder publication.
|
|
178
|
+
if (holderDisposition !== "released") {
|
|
179
|
+
lags.push({
|
|
180
|
+
kind: "settlement-failed",
|
|
181
|
+
surface: "task-holder",
|
|
182
|
+
contractId: candidate.id,
|
|
183
|
+
taskId,
|
|
184
|
+
diagnostic: diagnostic(error),
|
|
185
|
+
});
|
|
186
|
+
}
|
|
165
187
|
}
|
|
166
188
|
}
|
|
167
189
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
actions.push({
|
|
175
|
-
kind: "namespace-context",
|
|
176
|
-
path: effect.path,
|
|
177
|
-
action: await repairNamespaceContext(effect.path, contractNamespace(state.id)),
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
catch (error) {
|
|
181
|
-
lags.push({
|
|
182
|
-
kind: "settlement-failed",
|
|
183
|
-
surface: "namespace-context",
|
|
184
|
-
contractId: state.id,
|
|
185
|
-
path: effect.path,
|
|
186
|
-
diagnostic: diagnostic(error),
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
+
function settlementReport(actions, lags, seatClose) {
|
|
191
|
+
return {
|
|
192
|
+
actions,
|
|
193
|
+
lags,
|
|
194
|
+
...(seatClose.length === 0 ? {} : { seatClose }),
|
|
195
|
+
};
|
|
190
196
|
}
|
|
191
197
|
async function settleObserved(input) {
|
|
192
198
|
if (input.state === null)
|
|
193
199
|
return { actions: [], lags: [] };
|
|
194
|
-
const actions = [], lags = [];
|
|
195
|
-
|
|
196
|
-
if (
|
|
200
|
+
const actions = [], lags = [], seatClose = [];
|
|
201
|
+
const candidate = input.state;
|
|
202
|
+
if (candidate.terminal?.kind === "claimed") {
|
|
197
203
|
try {
|
|
198
|
-
|
|
204
|
+
await settleTasks({
|
|
199
205
|
repository: input.repository,
|
|
200
206
|
channel: input.channel,
|
|
201
|
-
candidate
|
|
207
|
+
candidate,
|
|
202
208
|
actions,
|
|
203
209
|
lags,
|
|
210
|
+
seatClose,
|
|
204
211
|
});
|
|
205
212
|
}
|
|
206
213
|
catch (error) {
|
|
207
214
|
lags.push({
|
|
208
215
|
kind: "settlement-failed",
|
|
209
216
|
surface: "task",
|
|
210
|
-
contractId:
|
|
217
|
+
contractId: candidate.id,
|
|
211
218
|
diagnostic: diagnostic(error),
|
|
212
219
|
});
|
|
213
220
|
}
|
|
214
221
|
}
|
|
215
|
-
|
|
216
|
-
await settleNamespace(input.state, input.effects, actions, lags);
|
|
217
|
-
return { actions, lags };
|
|
222
|
+
return settlementReport(actions, lags, seatClose);
|
|
218
223
|
}
|
|
219
224
|
function onPrimaryWorktree(repository) {
|
|
220
225
|
return { ...repository, effectiveCwd: repository.primaryWorktree };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { TaskDocument, TaskPriority, TaskState } from "./document.js";
|
|
2
2
|
import { type TaskId } from "./identity.js";
|
|
3
3
|
import { z } from "zod";
|
|
4
|
+
import { type BoundedList } from "../bounded-list.js";
|
|
4
5
|
export type TaskRef = Readonly<{
|
|
5
6
|
id: TaskId;
|
|
6
7
|
title: string | null;
|
|
@@ -111,6 +112,7 @@ export type TaskRelationProjection = Readonly<{
|
|
|
111
112
|
export declare function createTaskRelations(board: TaskBoard): TaskRelationProjection;
|
|
112
113
|
export declare function taskDisposition(board: TaskBoard, task: TaskDocument): TaskDisposition;
|
|
113
114
|
export declare function taskBlocked(board: TaskBoard, task: TaskDocument): boolean;
|
|
115
|
+
export declare function projectOwnedDetailFacts(board: TaskBoard, id: TaskId): TaskDetailFacts | null;
|
|
114
116
|
export declare function projectDetailFacts(board: TaskBoard, id: TaskId, relations: TaskRelationProjection): TaskDetailFacts | null;
|
|
115
117
|
export declare function projectTaskRow(board: TaskBoard, relations: TaskRelationProjection, task: TaskDocument): TaskRow;
|
|
116
118
|
export declare function projectRows(board: TaskBoard, relations: TaskRelationProjection, scope: readonly string[] | null, selection: "active" | "closed" | "all"): readonly TaskRow[];
|
|
@@ -147,6 +149,7 @@ export declare function projectStatusRows(board: TaskBoard, relations: TaskRelat
|
|
|
147
149
|
})[];
|
|
148
150
|
export type TaskBoardObservation = Readonly<{
|
|
149
151
|
statusRows: ReturnType<typeof projectStatusRows>;
|
|
152
|
+
selectRecentStatus(limit?: number): BoundedList<ReturnType<typeof projectStatusRows>[number]>;
|
|
150
153
|
selectNamespace(namespace: readonly string[]): readonly TaskRow[];
|
|
151
154
|
selectCreatedBy(createdBy: string): readonly TaskRow[];
|
|
152
155
|
}>;
|
package/build/src/task/board.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { formatTaskId, parseTaskId, sameNamespace } from "./identity.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
import { boundedListLimit, projectBoundedList } from "../bounded-list.js";
|
|
3
4
|
const taskRowIdSchema = z.string().transform((value, context) => {
|
|
4
5
|
try {
|
|
5
6
|
const id = formatTaskId(parseTaskId(value));
|
|
@@ -93,7 +94,7 @@ export function taskDisposition(board, task) {
|
|
|
93
94
|
export function taskBlocked(board, task) {
|
|
94
95
|
return (task.state === "open" || task.state === "in_progress") && hasUnresolvedNeeds(board, task);
|
|
95
96
|
}
|
|
96
|
-
export function
|
|
97
|
+
export function projectOwnedDetailFacts(board, id) {
|
|
97
98
|
const task = board.tasks.get(id);
|
|
98
99
|
if (task === undefined)
|
|
99
100
|
return null;
|
|
@@ -102,10 +103,22 @@ export function projectDetailFacts(board, id, relations) {
|
|
|
102
103
|
task,
|
|
103
104
|
needs,
|
|
104
105
|
blockers: needs.filter((need) => !need.released).map(({ released: _released, ...ref }) => ref),
|
|
105
|
-
blocks:
|
|
106
|
+
blocks: none,
|
|
106
107
|
parent: task.parent === null ? null : taskRef(board, task.parent),
|
|
107
|
-
children:
|
|
108
|
+
children: none,
|
|
108
109
|
supersedes: task.supersedes.map((target) => taskRef(board, target)),
|
|
110
|
+
supersededBy: none,
|
|
111
|
+
related: task.relates.length === 0 ? none : sorted(task.relates.map((target) => taskRef(board, target))),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
export function projectDetailFacts(board, id, relations) {
|
|
115
|
+
const owned = projectOwnedDetailFacts(board, id);
|
|
116
|
+
if (owned === null)
|
|
117
|
+
return null;
|
|
118
|
+
return {
|
|
119
|
+
...owned,
|
|
120
|
+
blocks: relations.blocks(id),
|
|
121
|
+
children: relations.children(id),
|
|
109
122
|
supersededBy: relations.supersededBy(id),
|
|
110
123
|
related: relations.related(id),
|
|
111
124
|
};
|
|
@@ -152,8 +165,13 @@ export function projectStatusRows(board, relations, scope) {
|
|
|
152
165
|
export function projectTaskBoardObservation(board) {
|
|
153
166
|
const relations = createTaskRelations(board);
|
|
154
167
|
const rows = projectRows(board, relations, null, "all");
|
|
168
|
+
const statusRows = projectStatusRows(board, relations, null);
|
|
155
169
|
return {
|
|
156
|
-
statusRows
|
|
170
|
+
statusRows,
|
|
171
|
+
selectRecentStatus: (limit) => projectBoundedList(statusRows
|
|
172
|
+
.filter((row) => row.state !== "done" && row.state !== "drop")
|
|
173
|
+
.sort((left, right) => right.updatedAt.localeCompare(left.updatedAt) ||
|
|
174
|
+
Buffer.compare(Buffer.from(left.id), Buffer.from(right.id))), boundedListLimit(limit)),
|
|
157
175
|
selectNamespace: (namespace) => projectRows(board, relations, namespace, "all"),
|
|
158
176
|
selectCreatedBy: (createdBy) => rows.filter((row) => board.tasks.get(row.id)?.createdBy === createdBy),
|
|
159
177
|
};
|
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { BoundedList } from "../bounded-list.js";
|
|
2
|
+
import type { TaskRef, TaskRow } from "./board.js";
|
|
2
3
|
import type { WorldRoot } from "../world.js";
|
|
3
4
|
export declare function parseTaskNamespaceSelector(value: string): readonly string[];
|
|
4
|
-
export
|
|
5
|
+
export type RecentTaskStatusRow = TaskRow & Readonly<{
|
|
6
|
+
blockers?: readonly TaskRef[];
|
|
7
|
+
}>;
|
|
8
|
+
export declare function observeRecentTaskStatus(world: WorldRoot, input?: Readonly<{
|
|
9
|
+
namespace?: readonly string[];
|
|
10
|
+
limit?: number;
|
|
11
|
+
}>): Promise<BoundedList<RecentTaskStatusRow>>;
|
|
12
|
+
export declare function observeTaskCatalog(world: WorldRoot, input?: Readonly<{
|
|
13
|
+
namespace?: readonly string[];
|
|
14
|
+
limit?: number;
|
|
15
|
+
}>): Promise<BoundedList<TaskRow>>;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { createTaskRelations, projectRows } from "./board.js";
|
|
2
1
|
import { isTaskSegment, parseTaskId } from "./identity.js";
|
|
3
|
-
import {
|
|
2
|
+
import { readRecentTaskDocuments, readTaskDocument } from "./store.js";
|
|
4
3
|
export function parseTaskNamespaceSelector(value) {
|
|
5
4
|
if (value === "task/")
|
|
6
5
|
return [];
|
|
@@ -14,10 +13,65 @@ export function parseTaskNamespaceSelector(value) {
|
|
|
14
13
|
}
|
|
15
14
|
return parseTaskId(`task/${body}/placeholder`).namespace;
|
|
16
15
|
}
|
|
17
|
-
|
|
16
|
+
function terminal(task) {
|
|
17
|
+
return task?.state === "done" || task?.state === "drop";
|
|
18
|
+
}
|
|
19
|
+
async function catalogRow(world, task, documents) {
|
|
20
|
+
const needs = await Promise.all(task.needs.map(async (id) => documents.get(id) ?? (await readTaskDocument(world, id))));
|
|
21
|
+
const blockers = [];
|
|
22
|
+
if (task.state === "open" || task.state === "in_progress") {
|
|
23
|
+
for (const [index, need] of needs.entries()) {
|
|
24
|
+
if (terminal(need))
|
|
25
|
+
continue;
|
|
26
|
+
blockers.push({ id: task.needs[index], title: need?.title ?? null, state: need?.state ?? "missing" });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
id: task.id,
|
|
31
|
+
title: task.title,
|
|
32
|
+
state: task.state,
|
|
33
|
+
priority: task.priority,
|
|
34
|
+
disposition: task.state === "open" && needs.some((need) => !terminal(need))
|
|
35
|
+
? "blocked"
|
|
36
|
+
: task.state === "open"
|
|
37
|
+
? "ready"
|
|
38
|
+
: task.state,
|
|
39
|
+
updatedAt: task.updatedAt,
|
|
40
|
+
bodyPresent: task.body.length > 0,
|
|
41
|
+
...(blockers.length === 0 ? {} : { blockers }),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
async function recentTaskStatus(world, input) {
|
|
45
|
+
const { namespace } = input;
|
|
46
|
+
if (namespace !== undefined && !namespace.every(isTaskSegment)) {
|
|
47
|
+
throw new TypeError("namespace must contain canonical segments");
|
|
48
|
+
}
|
|
49
|
+
const documents = await readRecentTaskDocuments(world, {
|
|
50
|
+
...(namespace === undefined ? {} : { namespace }),
|
|
51
|
+
selection: "active",
|
|
52
|
+
...(input.limit === undefined ? {} : { limit: input.limit }),
|
|
53
|
+
});
|
|
54
|
+
const known = new Map(documents.rows.map((document) => [document.id, document]));
|
|
55
|
+
return {
|
|
56
|
+
rows: await Promise.all(documents.rows.map((document) => catalogRow(world, document, known))),
|
|
57
|
+
hasMore: documents.hasMore,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export async function observeRecentTaskStatus(world, input = {}) {
|
|
61
|
+
return recentTaskStatus(world, input);
|
|
62
|
+
}
|
|
63
|
+
export async function observeTaskCatalog(world, input = {}) {
|
|
64
|
+
const { namespace } = input;
|
|
18
65
|
if (namespace !== undefined && !namespace.every(isTaskSegment)) {
|
|
19
66
|
throw new TypeError("namespace must contain canonical segments");
|
|
20
67
|
}
|
|
21
|
-
const
|
|
22
|
-
|
|
68
|
+
const documents = await readRecentTaskDocuments(world, {
|
|
69
|
+
...(namespace === undefined ? {} : { namespace }),
|
|
70
|
+
...(input.limit === undefined ? {} : { limit: input.limit }),
|
|
71
|
+
});
|
|
72
|
+
const known = new Map(documents.rows.map((document) => [document.id, document]));
|
|
73
|
+
return {
|
|
74
|
+
rows: (await Promise.all(documents.rows.map((document) => catalogRow(world, document, known)))).map(({ blockers: _blockers, ...row }) => row),
|
|
75
|
+
hasMore: documents.hasMore,
|
|
76
|
+
};
|
|
23
77
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { WorldRoot } from "../world.js";
|
|
2
2
|
import { type TaskCompositionAlias, type TaskCompositionBodyPreview } from "./compose-language.js";
|
|
3
|
-
import type
|
|
4
|
-
import type { TaskRefusal, TaskRetry } from "./operations.js";
|
|
3
|
+
import { type TaskId } from "./identity.js";
|
|
4
|
+
import type { TaskCleanupFailure, TaskRefusal, TaskRetry } from "./operations.js";
|
|
5
5
|
export type { TaskCompositionAlias, TaskCompositionBodyPreview } from "./compose-language.js";
|
|
6
6
|
export { taskCompositionNamespaceHeader } from "./compose-language.js";
|
|
7
7
|
export type TaskDocumentChange = Readonly<{
|
|
@@ -21,6 +21,7 @@ export type TaskCompositionResult = Readonly<{
|
|
|
21
21
|
}> | Readonly<{
|
|
22
22
|
kind: "accepted";
|
|
23
23
|
documentChanges: readonly TaskDocumentChange[];
|
|
24
|
+
cleanup?: TaskCleanupFailure;
|
|
24
25
|
} & TaskCompositionFacts> | Readonly<{
|
|
25
26
|
kind: "refused";
|
|
26
27
|
refusal: Extract<TaskRefusal, {
|
|
@@ -29,6 +30,7 @@ export type TaskCompositionResult = Readonly<{
|
|
|
29
30
|
}> | (Readonly<{
|
|
30
31
|
kind: "incomplete";
|
|
31
32
|
documentChanges: readonly TaskDocumentChange[];
|
|
33
|
+
cleanup?: TaskCleanupFailure;
|
|
32
34
|
stopped: TaskRefusal | Readonly<{
|
|
33
35
|
kind: "retry";
|
|
34
36
|
reason: TaskRetry;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { documentDiff } from "../markdown/diff.js";
|
|
2
2
|
import { planTaskComposition, } from "./compose-language.js";
|
|
3
3
|
import { serializeTaskDocument } from "./document.js";
|
|
4
|
-
import {
|
|
4
|
+
import { parseTaskId, taskAuthorityPath } from "./identity.js";
|
|
5
|
+
import { readBoard, replaceAuthority, withTaskLocks } from "./store.js";
|
|
5
6
|
export { taskCompositionNamespaceHeader } from "./compose-language.js";
|
|
6
7
|
function refusal(diagnostics) {
|
|
7
8
|
return { kind: "refused", refusal: { kind: "invalid-composition", diagnostics } };
|
|
@@ -57,6 +58,19 @@ function recoveryDraft(namespace, remaining) {
|
|
|
57
58
|
function plannedResult(plan) {
|
|
58
59
|
return { kind: "planned", ...facts(plan), bodies: plan.bodies };
|
|
59
60
|
}
|
|
61
|
+
function physicalPlanDiagnostics(plan) {
|
|
62
|
+
try {
|
|
63
|
+
taskAuthorityPath("", { namespace: plan.namespace, localId: "placeholder" });
|
|
64
|
+
for (const task of plan.tasks)
|
|
65
|
+
taskAuthorityPath("", parseTaskId(task.after.id));
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
return [
|
|
70
|
+
{ line: 1, reason: error instanceof Error ? error.message : String(error), token: plan.namespace.join("/") },
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
60
74
|
function planAgainst(markdown, board, namespace, at, actor) {
|
|
61
75
|
return planTaskComposition({ markdown, board, namespace, at, ...(actor === undefined ? {} : { actor }) });
|
|
62
76
|
}
|
|
@@ -70,7 +84,8 @@ async function admitPlan(world, snapshot, plan, signal) {
|
|
|
70
84
|
const before = beforeBytes === null ? "" : Buffer.from(beforeBytes).toString("utf8");
|
|
71
85
|
const after = Buffer.from(afterBytes).toString("utf8");
|
|
72
86
|
const replaced = await replaceAuthority({
|
|
73
|
-
|
|
87
|
+
world,
|
|
88
|
+
id: item.after.id,
|
|
74
89
|
expected: beforeBytes,
|
|
75
90
|
next: afterBytes,
|
|
76
91
|
});
|
|
@@ -115,32 +130,43 @@ function composeInput(input) {
|
|
|
115
130
|
}
|
|
116
131
|
export async function composeTasks(input) {
|
|
117
132
|
const { world, markdown, signal, actor, defaultNamespace = [], planOnly = false } = input;
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
133
|
+
try {
|
|
134
|
+
const at = currentTimestamp();
|
|
135
|
+
const initial = await readBoard(world);
|
|
136
|
+
const initialPlan = planAgainst(markdown, initial.board, defaultNamespace, at, actor);
|
|
137
|
+
if (initialPlan.kind === "refused")
|
|
138
|
+
return refusal(initialPlan.diagnostics);
|
|
139
|
+
const physicalDiagnostics = physicalPlanDiagnostics(initialPlan.plan);
|
|
140
|
+
if (physicalDiagnostics.length > 0)
|
|
141
|
+
return refusal(physicalDiagnostics);
|
|
142
|
+
if (planOnly)
|
|
143
|
+
return plannedResult(initialPlan.plan);
|
|
144
|
+
const request = composeInput({
|
|
145
|
+
world,
|
|
146
|
+
markdown,
|
|
147
|
+
namespace: defaultNamespace,
|
|
148
|
+
at,
|
|
149
|
+
...(actor === undefined ? {} : { actor }),
|
|
150
|
+
...(signal === undefined ? {} : { signal }),
|
|
151
|
+
});
|
|
152
|
+
const allocation = initialPlan.plan.tasks.some((task) => task.kind === "new");
|
|
153
|
+
const admitted = allocation
|
|
154
|
+
? await withTaskLocks({ world, allocation: true, ids: [], ...(signal === undefined ? {} : { signal }) }, async () => await composeUnderLocks(request))
|
|
155
|
+
: await composeUnderLocks(request);
|
|
156
|
+
if (admitted !== "busy")
|
|
157
|
+
return admitted;
|
|
158
|
+
return {
|
|
159
|
+
kind: "incomplete",
|
|
160
|
+
...facts(initialPlan.plan),
|
|
161
|
+
documentChanges: [],
|
|
162
|
+
stopped: { kind: "retry", reason: "busy" },
|
|
163
|
+
draft: recoveryDraft(initialPlan.plan.namespace, initialPlan.plan.tasks),
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
if (error instanceof TypeError &&
|
|
168
|
+
/task identity (?:cannot fit the physical filename budget|contains a Windows-reserved physical segment)/u.test(error.message))
|
|
169
|
+
return refusal([{ line: 1, reason: error.message, token: defaultNamespace.join("/") }]);
|
|
170
|
+
throw error;
|
|
171
|
+
}
|
|
146
172
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { WorldRoot } from "../world.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export declare const createdTaskObservationSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
4
|
+
kind: z.ZodLiteral<"present">;
|
|
5
|
+
rows: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
6
|
+
id: z.ZodPipe<z.ZodString, z.ZodTransform<`task/${string}`, string>>;
|
|
7
|
+
title: z.ZodString;
|
|
8
|
+
state: z.ZodEnum<{
|
|
9
|
+
open: "open";
|
|
10
|
+
in_progress: "in_progress";
|
|
11
|
+
on_hold: "on_hold";
|
|
12
|
+
done: "done";
|
|
13
|
+
drop: "drop";
|
|
14
|
+
}>;
|
|
15
|
+
priority: z.ZodUnion<readonly [z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>]>;
|
|
16
|
+
disposition: z.ZodEnum<{
|
|
17
|
+
in_progress: "in_progress";
|
|
18
|
+
on_hold: "on_hold";
|
|
19
|
+
done: "done";
|
|
20
|
+
drop: "drop";
|
|
21
|
+
ready: "ready";
|
|
22
|
+
blocked: "blocked";
|
|
23
|
+
}>;
|
|
24
|
+
updatedAt: z.ZodString;
|
|
25
|
+
bodyPresent: z.ZodBoolean;
|
|
26
|
+
children: z.ZodOptional<z.ZodObject<{
|
|
27
|
+
live: z.ZodNumber;
|
|
28
|
+
total: z.ZodNumber;
|
|
29
|
+
}, z.core.$strict>>;
|
|
30
|
+
}, z.core.$strict>>>;
|
|
31
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
32
|
+
kind: z.ZodLiteral<"failed">;
|
|
33
|
+
diagnostic: z.ZodString;
|
|
34
|
+
}, z.core.$strict>]>;
|
|
35
|
+
export type CreatedTaskObservation = z.infer<typeof createdTaskObservationSchema>;
|
|
36
|
+
export declare const EMPTY_CREATED_TASK_OBSERVATION: CreatedTaskObservation;
|
|
37
|
+
export declare function parseCreatedTaskObservation(value: unknown): CreatedTaskObservation;
|
|
38
|
+
/** Project Task board rows created by each identity, preserving input order. */
|
|
39
|
+
export declare function observeCreatedTaskObservations(world: WorldRoot, createdByIds: readonly string[]): Promise<readonly CreatedTaskObservation[]>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { taskRowsSchema } from "./board.js";
|
|
3
|
+
import { observeTaskBoard } from "./operations.js";
|
|
4
|
+
export const createdTaskObservationSchema = z.union([
|
|
5
|
+
z.object({ kind: z.literal("present"), rows: taskRowsSchema }).strict(),
|
|
6
|
+
z.object({ kind: z.literal("failed"), diagnostic: z.string() }).strict(),
|
|
7
|
+
]);
|
|
8
|
+
export const EMPTY_CREATED_TASK_OBSERVATION = { kind: "present", rows: [] };
|
|
9
|
+
export function parseCreatedTaskObservation(value) {
|
|
10
|
+
return createdTaskObservationSchema.parse(value);
|
|
11
|
+
}
|
|
12
|
+
function observationDiagnostic(error) {
|
|
13
|
+
return error instanceof Error ? error.message : String(error);
|
|
14
|
+
}
|
|
15
|
+
/** Project Task board rows created by each identity, preserving input order. */
|
|
16
|
+
export async function observeCreatedTaskObservations(world, createdByIds) {
|
|
17
|
+
let board;
|
|
18
|
+
try {
|
|
19
|
+
board = await observeTaskBoard(world);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
const failed = { kind: "failed", diagnostic: observationDiagnostic(error) };
|
|
23
|
+
return createdByIds.map(() => failed);
|
|
24
|
+
}
|
|
25
|
+
return createdByIds.map((createdBy) => parseCreatedTaskObservation({ kind: "present", rows: board.selectCreatedBy(createdBy) }));
|
|
26
|
+
}
|
|
@@ -1,12 +1,18 @@
|
|
|
1
|
+
import { type ContractId } from "../core/facts/types.js";
|
|
1
2
|
export type TaskId = `task/${string}`;
|
|
2
3
|
export type TaskCoordinate = Readonly<{
|
|
3
4
|
namespace: readonly string[];
|
|
4
5
|
localId: string;
|
|
5
6
|
}>;
|
|
7
|
+
export declare const TASK_LOCK_ID_BYTES: number;
|
|
8
|
+
export declare const TASK_LOCAL_ID_BYTES: number;
|
|
6
9
|
export declare function isTaskSegment(value: string): boolean;
|
|
7
10
|
export declare function parseTaskId(value: string): TaskCoordinate;
|
|
8
11
|
export declare function formatTaskId(coordinate: TaskCoordinate): TaskId;
|
|
12
|
+
export declare function canonicalTaskId(value: string): TaskId;
|
|
13
|
+
export declare function contractNamespace(id: ContractId): readonly string[];
|
|
9
14
|
export declare function taskAuthorityPath(tasksDirectory: string, coordinate: TaskCoordinate): string;
|
|
10
15
|
export declare function deriveLocalStem(title: string): string;
|
|
11
16
|
export declare function allocateLocalId(stem: string, occupied: ReadonlySet<string>): string;
|
|
17
|
+
export declare function physicalTaskSegment(segment: string, maxBytes?: number): string;
|
|
12
18
|
export declare function sameNamespace(left: readonly string[], right: readonly string[]): boolean;
|