@astrosheep/keiyaku 4.0.1 → 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.
- package/README.md +137 -5
- package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +3 -3
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +91 -35
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +98 -58
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +152 -53
- package/build/src/akuma/abort.d.ts +2 -0
- package/build/src/akuma/abort.js +50 -0
- package/build/src/akuma/akuma.d.ts +23 -14
- package/build/src/akuma/akuma.js +120 -104
- package/build/src/akuma/archetype.d.ts +7 -6
- package/build/src/akuma/archetype.js +68 -41
- package/build/src/akuma/body.d.ts +3 -5
- package/build/src/akuma/body.js +408 -213
- package/build/src/akuma/heart/facts.d.ts +25 -34
- package/build/src/akuma/heart/facts.js +18 -7
- package/build/src/akuma/heart/index.d.ts +39 -42
- package/build/src/akuma/heart/index.js +134 -93
- package/build/src/akuma/heart/rows.d.ts +9 -31
- package/build/src/akuma/heart/rows.js +26 -44
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +7 -15
- package/build/src/akuma/heart/soul.d.ts +8 -0
- package/build/src/akuma/heart/soul.js +136 -0
- package/build/src/akuma/heart/storage.d.ts +28 -14
- package/build/src/akuma/heart/storage.js +86 -26
- package/build/src/akuma/identity.d.ts +2 -2
- package/build/src/akuma/identity.js +9 -9
- package/build/src/akuma/index.d.ts +6 -1
- package/build/src/akuma/index.js +6 -0
- package/build/src/akuma/projection.d.ts +117 -38
- package/build/src/akuma/projection.js +208 -97
- package/build/src/akuma/provider-recipe.d.ts +24 -0
- package/build/src/akuma/provider-recipe.js +100 -0
- package/build/src/akuma/provider.d.ts +12 -4
- package/build/src/akuma/provider.js +117 -70
- package/build/src/akuma/providers/acp/core.d.ts +19 -0
- package/build/src/akuma/providers/acp/core.js +159 -0
- package/build/src/akuma/providers/acp/events.d.ts +20 -0
- package/build/src/akuma/providers/acp/events.js +73 -0
- package/build/src/akuma/providers/acp/index.d.ts +12 -0
- package/build/src/akuma/providers/acp/index.js +94 -0
- package/build/src/akuma/providers/claude/events.js +66 -13
- package/build/src/akuma/providers/claude/index.d.ts +2 -1
- package/build/src/akuma/providers/claude/index.js +35 -21
- package/build/src/akuma/providers/codex-app-server/events.js +4 -1
- package/build/src/akuma/providers/codex-app-server/index.d.ts +3 -3
- package/build/src/akuma/providers/codex-app-server/index.js +24 -31
- package/build/src/akuma/providers/grok-build/index.d.ts +4 -0
- package/build/src/akuma/providers/grok-build/index.js +70 -0
- package/build/src/akuma/providers/index.d.ts +5 -3
- package/build/src/akuma/providers/index.js +24 -59
- package/build/src/akuma/providers/opencode-sdk/events.d.ts +40 -34
- package/build/src/akuma/providers/opencode-sdk/events.js +220 -101
- package/build/src/akuma/providers/opencode-sdk/index.d.ts +3 -2
- package/build/src/akuma/providers/opencode-sdk/index.js +233 -128
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +11 -26
- package/build/src/akuma/providers/opencode-sdk/session.js +10 -9
- package/build/src/akuma/providers/pi/events.js +49 -11
- package/build/src/akuma/providers/pi/index.d.ts +1 -1
- package/build/src/akuma/providers/pi/index.js +50 -21
- package/build/src/akuma/publication.d.ts +3 -3
- package/build/src/akuma/publication.js +28 -40
- package/build/src/akuma/requests.d.ts +9 -7
- package/build/src/akuma/requests.js +92 -65
- package/build/src/alias/index.d.ts +2 -2
- package/build/src/alias/index.js +10 -10
- package/build/src/body/decode.js +7 -1
- package/build/src/body/region.d.ts +2 -0
- package/build/src/body/region.js +77 -7
- package/build/src/cli/accepted.d.ts +17 -13
- package/build/src/cli/accepted.js +72 -34
- package/build/src/cli/actor.js +3 -3
- package/build/src/cli/commands/akuma-invoke.d.ts +4 -3
- package/build/src/cli/commands/akuma-invoke.js +14 -9
- package/build/src/cli/commands/akuma.d.ts +13 -3
- package/build/src/cli/commands/akuma.js +67 -34
- package/build/src/cli/commands/contract.d.ts +18 -5
- package/build/src/cli/commands/contract.js +9 -3
- package/build/src/cli/commands/task-invoke.d.ts +17 -4
- package/build/src/cli/commands/task-invoke.js +43 -20
- package/build/src/cli/commands/task-query.d.ts +5 -0
- package/build/src/cli/commands/task-query.js +247 -0
- package/build/src/cli/commands/task.d.ts +3 -1
- package/build/src/cli/commands/task.js +51 -13
- package/build/src/cli/coordinates.d.ts +18 -0
- package/build/src/cli/coordinates.js +120 -0
- package/build/src/cli/draft.d.ts +8 -0
- package/build/src/cli/draft.js +96 -0
- package/build/src/cli/invoke.d.ts +4 -3
- package/build/src/cli/invoke.js +160 -179
- package/build/src/cli/main.js +34 -6
- package/build/src/cli/parse.d.ts +9 -2
- package/build/src/cli/parse.js +29 -7
- package/build/src/cli/render/akuma-tool-command.d.ts +6 -0
- package/build/src/cli/render/akuma-tool-command.js +144 -0
- package/build/src/cli/render/akuma-tool.d.ts +2 -2
- package/build/src/cli/render/akuma-tool.js +30 -4
- package/build/src/cli/render/akuma.d.ts +1 -0
- package/build/src/cli/render/akuma.js +211 -116
- package/build/src/cli/render/audit.d.ts +3 -0
- package/build/src/cli/render/audit.js +104 -0
- package/build/src/cli/render/contract.d.ts +3 -3
- package/build/src/cli/render/contract.js +192 -79
- package/build/src/cli/render/kanshi.js +263 -168
- package/build/src/cli/render/receipt.d.ts +19 -0
- package/build/src/cli/render/receipt.js +106 -0
- package/build/src/cli/render/refusal.d.ts +16 -2
- package/build/src/cli/render/refusal.js +88 -20
- package/build/src/cli/render/region.d.ts +2 -0
- package/build/src/cli/render/region.js +17 -0
- package/build/src/cli/render/task.d.ts +2 -1
- package/build/src/cli/render/task.js +223 -60
- package/build/src/cli/render/terminal.d.ts +7 -0
- package/build/src/cli/render/terminal.js +46 -0
- package/build/src/cli/render/text.js +6 -3
- package/build/src/cli/result.d.ts +115 -20
- package/build/src/cli/usage.d.ts +1 -0
- package/build/src/cli/usage.js +3 -0
- package/build/src/contract-worktree.d.ts +6 -5
- package/build/src/contract-worktree.js +95 -57
- package/build/src/coordination/durable-file.d.ts +4 -3
- package/build/src/coordination/durable-file.js +29 -25
- package/build/src/coordination/sqlite-transaction-lock.d.ts +4 -0
- package/build/src/coordination/sqlite-transaction-lock.js +22 -5
- package/build/src/core/facts/fold.js +1 -6
- package/build/src/core/facts/gate.d.ts +1 -0
- package/build/src/core/facts/gate.js +1 -0
- package/build/src/core/verbs/amend.d.ts +1 -1
- package/build/src/core/verbs/amend.js +0 -11
- package/build/src/core/verbs/deliver.d.ts +1 -1
- package/build/src/core/verbs/deliver.js +1 -7
- package/build/src/core/verbs/placement.d.ts +1 -1
- package/build/src/core/verbs/placement.js +4 -1
- package/build/src/dispatch/index.d.ts +2 -2
- package/build/src/dispatch/index.js +17 -17
- package/build/src/git/admission.d.ts +1 -1
- package/build/src/git/admission.js +11 -11
- package/build/src/git/hooks.js +13 -13
- package/build/src/git/integration.d.ts +14 -15
- package/build/src/git/integration.js +80 -44
- package/build/src/git/observe.d.ts +5 -3
- package/build/src/git/observe.js +18 -12
- package/build/src/git/read-observation.js +9 -9
- package/build/src/git/reconcile.d.ts +2 -0
- package/build/src/git/reconcile.js +138 -95
- package/build/src/git/repository.d.ts +27 -19
- package/build/src/git/repository.js +155 -83
- package/build/src/git/scratch.d.ts +7 -3
- package/build/src/git/scratch.js +44 -37
- package/build/src/git/target-placement.d.ts +40 -4
- package/build/src/git/target-placement.js +221 -101
- package/build/src/git/tender.d.ts +6 -5
- package/build/src/git/tender.js +24 -43
- package/build/src/git/terminal-seal.d.ts +1 -1
- package/build/src/git/terminal-seal.js +7 -5
- package/build/src/git/workspace.d.ts +36 -4
- package/build/src/git/workspace.js +53 -18
- package/build/src/identity/selector.js +1 -1
- package/build/src/index.d.ts +3 -3
- package/build/src/index.js +1 -1
- package/build/src/kanshi/index.d.ts +2 -2
- package/build/src/kanshi/index.js +1 -1
- package/build/src/kanshi/read.d.ts +2 -1
- package/build/src/kanshi/read.js +118 -27
- package/build/src/kanshi/report.d.ts +50 -0
- package/build/src/kanshi/select.d.ts +5 -0
- package/build/src/kanshi/select.js +32 -0
- package/build/src/library/address.d.ts +12 -3
- package/build/src/library/address.js +77 -46
- package/build/src/library/akuma-creation.d.ts +6 -1
- package/build/src/library/akuma-creation.js +86 -13
- package/build/src/library/audit.d.ts +18 -0
- package/build/src/library/audit.js +44 -0
- package/build/src/library/bind.js +4 -4
- package/build/src/library/catalog.d.ts +1 -1
- package/build/src/library/catalog.js +5 -8
- package/build/src/library/contract.d.ts +5 -6
- package/build/src/library/contract.js +11 -35
- package/build/src/library/delivery.d.ts +2 -1
- package/build/src/library/fleet.d.ts +2 -2
- package/build/src/library/fleet.js +35 -71
- package/build/src/library/keiyaku.d.ts +3 -2
- package/build/src/library/keiyaku.js +1 -0
- package/build/src/library/mutation.d.ts +7 -6
- package/build/src/library/mutation.js +23 -25
- package/build/src/library/reconcile.d.ts +29 -0
- package/build/src/library/reconcile.js +179 -0
- package/build/src/library/region.d.ts +12 -0
- package/build/src/library/region.js +15 -1
- package/build/src/library/repo.d.ts +4 -16
- package/build/src/library/repo.js +13 -38
- package/build/src/protocol/attempt.js +6 -6
- package/build/src/protocol/bind.js +4 -4
- package/build/src/protocol/intent.d.ts +15 -2
- package/build/src/protocol/intent.js +21 -6
- package/build/src/protocol/operations.d.ts +73 -22
- package/build/src/protocol/operations.js +292 -88
- package/build/src/protocol/outcome.d.ts +9 -3
- package/build/src/protocol/outcome.js +3 -1
- package/build/src/protocol/placement.d.ts +15 -4
- package/build/src/protocol/placement.js +58 -25
- package/build/src/protocol/read/status.d.ts +8 -1
- package/build/src/protocol/read/status.js +61 -14
- package/build/src/runtime/proc/line-rpc.d.ts +3 -8
- package/build/src/runtime/proc/line-rpc.js +16 -43
- package/build/src/runtime/proc/run.d.ts +15 -29
- package/build/src/runtime/proc/run.js +113 -105
- package/build/src/runtime/proc/stdio.d.ts +18 -0
- package/build/src/runtime/proc/stdio.js +58 -0
- package/build/src/settings.d.ts +2 -2
- package/build/src/settings.js +8 -8
- package/build/src/settlement/fence.d.ts +0 -4
- package/build/src/settlement/fence.js +0 -9
- package/build/src/settlement/holder.d.ts +11 -1
- package/build/src/settlement/holder.js +25 -0
- package/build/src/settlement/settle.d.ts +1 -1
- package/build/src/settlement/settle.js +52 -89
- package/build/src/task/board.d.ts +3 -3
- package/build/src/task/board.js +6 -9
- package/build/src/task/compose.d.ts +1 -1
- package/build/src/task/compose.js +18 -10
- package/build/src/task/context.d.ts +3 -3
- package/build/src/task/context.js +14 -14
- package/build/src/task/document.d.ts +2 -1
- package/build/src/task/document.js +15 -5
- package/build/src/task/index.d.ts +19 -7
- package/build/src/task/index.js +42 -23
- package/build/src/task/operations.d.ts +15 -9
- package/build/src/task/operations.js +78 -48
- package/build/src/task/query.d.ts +67 -0
- package/build/src/task/query.js +279 -0
- package/build/src/task/store.d.ts +2 -2
- package/build/src/task/store.js +40 -25
- package/build/src/verification/execution.d.ts +4 -2
- package/build/src/verification/execution.js +9 -5
- package/build/src/workspace-place.d.ts +41 -0
- package/build/src/workspace-place.js +386 -0
- package/build/src/world.d.ts +13 -2
- package/build/src/world.js +81 -48
- package/package.json +3 -2
- package/build/src/protocol/read/audit.d.ts +0 -31
- package/build/src/protocol/read/audit.js +0 -55
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { samePrerequisites } from "./eligibility.js";
|
|
2
1
|
import { gatesSatisfied } from "./gate.js";
|
|
3
2
|
import { AuthorityCorruptionError } from "./errors.js";
|
|
4
3
|
function foldError(message) {
|
|
@@ -47,12 +46,8 @@ function foldEntry(state, entry, attestations) {
|
|
|
47
46
|
switch (entry.kind) {
|
|
48
47
|
case "bind":
|
|
49
48
|
foldError("bind may appear only once");
|
|
50
|
-
case "amend":
|
|
51
|
-
if (state.bound !== null && !samePrerequisites(state.terms.after, entry.data.after)) {
|
|
52
|
-
foldError("cannot change after once prerequisites are consumed");
|
|
53
|
-
}
|
|
49
|
+
case "amend":
|
|
54
50
|
return { ...state, terms: cloneTerms(entry.data) };
|
|
55
|
-
}
|
|
56
51
|
case "bound":
|
|
57
52
|
if (state.bound !== null)
|
|
58
53
|
foldError("bound may appear only once");
|
|
@@ -8,7 +8,7 @@ export type AmendInput<Failure = never> = Readonly<{
|
|
|
8
8
|
preparation?: Preparation<AmendData, Failure>;
|
|
9
9
|
}>;
|
|
10
10
|
export type AmendRefusal = Readonly<{
|
|
11
|
-
kind: "contract-missing" | "terminal" | "terms-moved" | "
|
|
11
|
+
kind: "contract-missing" | "terminal" | "terms-moved" | "unknown-prerequisite" | "cyclic-prerequisite";
|
|
12
12
|
contractId: ContractId;
|
|
13
13
|
}>;
|
|
14
14
|
export declare function decideAmend<Failure>({ input, attempt, observation }: DecideInput<AmendInput<Failure>>): OfferDecision<AmendRefusal | Failure>;
|
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
import { prerequisitesReach, samePrerequisites } from "../facts/eligibility.js";
|
|
2
2
|
import { activeContract, prerequisiteStatus } from "../facts/observation.js";
|
|
3
|
-
function prerequisitesConsumed(current, next, observation) {
|
|
4
|
-
if (samePrerequisites(current.terms.after, next.after))
|
|
5
|
-
return false;
|
|
6
|
-
const status = prerequisiteStatus(current.terms.after, observation);
|
|
7
|
-
if (status === "unknown")
|
|
8
|
-
throw new Error("current prerequisite is absent from the decision observation");
|
|
9
|
-
return current.bound !== null || status === "claimed";
|
|
10
|
-
}
|
|
11
3
|
export function decideAmend({ input, attempt, observation }) {
|
|
12
4
|
const id = input.contractId;
|
|
13
5
|
const current = activeContract(observation, id);
|
|
@@ -29,9 +21,6 @@ export function decideAmend({ input, attempt, observation }) {
|
|
|
29
21
|
if (input.preparation.kind === "refused")
|
|
30
22
|
return { kind: "refused", refusal: input.preparation.refusal };
|
|
31
23
|
const { data } = input.preparation;
|
|
32
|
-
if (prerequisitesConsumed(current, data, observation)) {
|
|
33
|
-
return { kind: "refused", refusal: { kind: "prerequisites-already-consumed", contractId: id } };
|
|
34
|
-
}
|
|
35
24
|
const prerequisites = prerequisiteStatus(data.after, observation);
|
|
36
25
|
if (prerequisites === "unknown") {
|
|
37
26
|
return { kind: "refused", refusal: { kind: "unknown-prerequisite", contractId: id } };
|
|
@@ -7,7 +7,7 @@ export type DeliverInput<Failure = never> = Readonly<{
|
|
|
7
7
|
preparation: StampedPreparation<DeliverData, Failure>;
|
|
8
8
|
}>;
|
|
9
9
|
export type DeliverRefusal = Readonly<{
|
|
10
|
-
kind: "contract-missing" | "
|
|
10
|
+
kind: "contract-missing" | "terminal" | "document-moved";
|
|
11
11
|
contractId: ContractId;
|
|
12
12
|
}>;
|
|
13
13
|
export declare function decideDeliver<Failure>({ input, attempt, observation, }: DecideInput<DeliverInput<Failure>>): OfferDecision<DeliverRefusal | Failure>;
|
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
import { activeContract, documentIsCurrent
|
|
1
|
+
import { activeContract, documentIsCurrent } from "../facts/observation.js";
|
|
2
2
|
export function decideDeliver({ input, attempt, observation, }) {
|
|
3
3
|
const state = activeContract(observation, input.contractId);
|
|
4
4
|
if ("kind" in state)
|
|
5
5
|
return { kind: "refused", refusal: state };
|
|
6
|
-
const prerequisites = state.bound === null
|
|
7
|
-
? prerequisiteStatus(state.terms.after, observation)
|
|
8
|
-
: "claimed";
|
|
9
|
-
if (prerequisites !== "claimed") {
|
|
10
|
-
return { kind: "refused", refusal: { kind: "not-bound", contractId: input.contractId } };
|
|
11
|
-
}
|
|
12
6
|
if (input.preparation.kind === "unavailable") {
|
|
13
7
|
throw new Error("existing contract requires a stamped delivery preparation");
|
|
14
8
|
}
|
|
@@ -6,7 +6,7 @@ type PlacementInput = Readonly<{
|
|
|
6
6
|
at: string;
|
|
7
7
|
}>;
|
|
8
8
|
export type PlacementRefusal = Readonly<{
|
|
9
|
-
kind: "contract-missing" | "delivery-missing" | "terminal" | "gates-unsatisfied";
|
|
9
|
+
kind: "contract-missing" | "delivery-missing" | "terminal" | "prerequisites-unsatisfied" | "gates-unsatisfied";
|
|
10
10
|
contractId: ContractId;
|
|
11
11
|
}>;
|
|
12
12
|
export declare function decidePlacement({ input, attempt, observation }: DecideInput<PlacementInput>): OfferDecision<PlacementRefusal>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { gatesSatisfied } from "../facts/gate.js";
|
|
2
|
-
import { activeContract } from "../facts/observation.js";
|
|
2
|
+
import { activeContract, prerequisiteStatus } from "../facts/observation.js";
|
|
3
3
|
export function decidePlacement({ input, attempt, observation }) {
|
|
4
4
|
const id = input.contractId;
|
|
5
5
|
const current = activeContract(observation, id);
|
|
@@ -9,6 +9,9 @@ export function decidePlacement({ input, attempt, observation }) {
|
|
|
9
9
|
if (!delivery) {
|
|
10
10
|
return { kind: "refused", refusal: { kind: "delivery-missing", contractId: id } };
|
|
11
11
|
}
|
|
12
|
+
if (prerequisiteStatus(current.terms.after, observation) !== "claimed") {
|
|
13
|
+
return { kind: "refused", refusal: { kind: "prerequisites-unsatisfied", contractId: id } };
|
|
14
|
+
}
|
|
12
15
|
if (!gatesSatisfied(current)) {
|
|
13
16
|
return { kind: "refused", refusal: { kind: "gates-unsatisfied", contractId: id } };
|
|
14
17
|
}
|
|
@@ -23,11 +23,11 @@ export type DispatchPublication = Readonly<{
|
|
|
23
23
|
kind: "failed";
|
|
24
24
|
failure: DispatchFailure;
|
|
25
25
|
}>;
|
|
26
|
-
export declare function readDispatch(repository: GitRepository, value: AkuId): Dispatch | null
|
|
26
|
+
export declare function readDispatch(repository: GitRepository, value: AkuId): Promise<Dispatch | null>;
|
|
27
27
|
export declare function readDispatchesAt(observation: GitReadObservation): Promise<readonly Dispatch[]>;
|
|
28
28
|
export declare function readDispatches(repository: GitRepository): Promise<readonly Dispatch[]>;
|
|
29
29
|
export declare function publishDispatch(input: Readonly<{
|
|
30
30
|
repository: GitRepository;
|
|
31
31
|
akuId: AkuId;
|
|
32
32
|
contractId: ContractId;
|
|
33
|
-
}>): DispatchPublication
|
|
33
|
+
}>): Promise<DispatchPublication>;
|
|
@@ -64,19 +64,19 @@ function decode(path, bytes) {
|
|
|
64
64
|
}
|
|
65
65
|
return dispatch;
|
|
66
66
|
}
|
|
67
|
-
function dispatchFromSnapshot(repository, snapshot, akuId) {
|
|
67
|
+
async function dispatchFromSnapshot(repository, snapshot, akuId) {
|
|
68
68
|
const path = pathFor(akuId);
|
|
69
69
|
const entry = snapshot.paths.get(path);
|
|
70
70
|
if (entry === undefined)
|
|
71
71
|
return null;
|
|
72
72
|
if (entry.type !== "blob")
|
|
73
73
|
corruption(`Dispatch path is not a blob: ${path}`);
|
|
74
|
-
return decode(path, readBlob(repository, entry.oid));
|
|
74
|
+
return decode(path, await readBlob(repository, entry.oid));
|
|
75
75
|
}
|
|
76
|
-
export function readDispatch(repository, value) {
|
|
76
|
+
export async function readDispatch(repository, value) {
|
|
77
77
|
const akuId = parseAkuId(value).id;
|
|
78
78
|
const path = pathFor(akuId);
|
|
79
|
-
return dispatchFromSnapshot(repository, readGitPaths(repository, [path]), akuId);
|
|
79
|
+
return await dispatchFromSnapshot(repository, await readGitPaths(repository, [path]), akuId);
|
|
80
80
|
}
|
|
81
81
|
export async function readDispatchesAt(observation) {
|
|
82
82
|
const entries = [...observation.snapshot.paths]
|
|
@@ -105,10 +105,10 @@ export async function readDispatchesAt(observation) {
|
|
|
105
105
|
return dispatches.sort((left, right) => Buffer.compare(Buffer.from(left.akuId), Buffer.from(right.akuId)));
|
|
106
106
|
}
|
|
107
107
|
export async function readDispatches(repository) {
|
|
108
|
-
return withGitDecodeChannel(repository, (channel) => withGitReadObservation(repository, channel, readDispatchesAt));
|
|
108
|
+
return await withGitDecodeChannel(repository, (channel) => withGitReadObservation(repository, channel, readDispatchesAt));
|
|
109
109
|
}
|
|
110
|
-
function observedPublication(repository, akuId, owner) {
|
|
111
|
-
const current = readDispatch(repository, akuId);
|
|
110
|
+
async function observedPublication(repository, akuId, owner) {
|
|
111
|
+
const current = await readDispatch(repository, akuId);
|
|
112
112
|
if (current === null)
|
|
113
113
|
return null;
|
|
114
114
|
return current.contractId === owner
|
|
@@ -118,14 +118,14 @@ function observedPublication(repository, akuId, owner) {
|
|
|
118
118
|
function diagnostic(error) {
|
|
119
119
|
return error instanceof Error ? error.message : String(error);
|
|
120
120
|
}
|
|
121
|
-
export function publishDispatch(input) {
|
|
121
|
+
export async function publishDispatch(input) {
|
|
122
122
|
const akuId = parseAkuId(input.akuId).id;
|
|
123
123
|
const owner = contractId(input.contractId);
|
|
124
124
|
const intended = { akuId, contractId: owner, dispatchedAt: new Date().toISOString() };
|
|
125
125
|
const path = pathFor(akuId);
|
|
126
126
|
for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt += 1) {
|
|
127
|
-
const snapshot = readGitPaths(input.repository, [path]);
|
|
128
|
-
const current = dispatchFromSnapshot(input.repository, snapshot, akuId);
|
|
127
|
+
const snapshot = await readGitPaths(input.repository, [path]);
|
|
128
|
+
const current = await dispatchFromSnapshot(input.repository, snapshot, akuId);
|
|
129
129
|
if (current !== null) {
|
|
130
130
|
return current.contractId === owner
|
|
131
131
|
? { kind: "dispatched", dispatch: current }
|
|
@@ -133,29 +133,29 @@ export function publishDispatch(input) {
|
|
|
133
133
|
}
|
|
134
134
|
const changes = new Map();
|
|
135
135
|
if (snapshot.commit === null) {
|
|
136
|
-
changes.set(GIT_FORMAT_PATH, { oid: writeBlob(input.repository, GIT_FORMAT_BYTES) });
|
|
136
|
+
changes.set(GIT_FORMAT_PATH, { oid: await writeBlob(input.repository, GIT_FORMAT_BYTES) });
|
|
137
137
|
}
|
|
138
|
-
changes.set(path, { oid: writeBlob(input.repository, bytesFor(intended)) });
|
|
139
|
-
const tree = updateGitTree(input.repository, snapshot.tree, changes);
|
|
140
|
-
const commit = writeCommit({
|
|
138
|
+
changes.set(path, { oid: await writeBlob(input.repository, bytesFor(intended)) });
|
|
139
|
+
const tree = await updateGitTree(input.repository, snapshot.tree, changes);
|
|
140
|
+
const commit = await writeCommit({
|
|
141
141
|
repository: input.repository,
|
|
142
142
|
tree,
|
|
143
143
|
parent: snapshot.commit,
|
|
144
144
|
message: `dispatch ${akuId}`,
|
|
145
145
|
at: intended.dispatchedAt,
|
|
146
146
|
});
|
|
147
|
-
const publication = updateRefsAtomically(input.repository, [{
|
|
147
|
+
const publication = await updateRefsAtomically(input.repository, [{
|
|
148
148
|
ref: GIT_REF,
|
|
149
149
|
newOid: commit,
|
|
150
150
|
expectedOid: snapshot.commit,
|
|
151
151
|
}]);
|
|
152
152
|
if (publication.kind === "published")
|
|
153
153
|
return { kind: "dispatched", dispatch: intended };
|
|
154
|
-
const observed = observedPublication(input.repository, akuId, owner);
|
|
154
|
+
const observed = await observedPublication(input.repository, akuId, owner);
|
|
155
155
|
if (observed !== null)
|
|
156
156
|
return observed;
|
|
157
157
|
if (publication.kind === "non-published") {
|
|
158
|
-
const fresh = readGitPaths(input.repository, [path]);
|
|
158
|
+
const fresh = await readGitPaths(input.repository, [path]);
|
|
159
159
|
if (fresh.commit === snapshot.commit) {
|
|
160
160
|
return {
|
|
161
161
|
kind: "failed",
|
|
@@ -14,5 +14,5 @@ type Unknown = Readonly<{
|
|
|
14
14
|
kind: "unknown";
|
|
15
15
|
}>;
|
|
16
16
|
export type Admission = Accepted | PublicationFailed | Unknown;
|
|
17
|
-
export declare function admit(repository: GitRepository, offer: Offer, admission: GitAdmissionSnapshot, assertions?: readonly GitRefAssertion[]): Admission
|
|
17
|
+
export declare function admit(repository: GitRepository, offer: Offer, admission: GitAdmissionSnapshot, assertions?: readonly GitRefAssertion[]): Promise<Admission>;
|
|
18
18
|
export {};
|
|
@@ -53,16 +53,16 @@ function readCanonicalJournal(admission, id) {
|
|
|
53
53
|
throw new Error(`missing frozen journal bytes: ${path}`);
|
|
54
54
|
return { bytes: journal, path };
|
|
55
55
|
}
|
|
56
|
-
function buildOffer(repository, admission, appends, companions) {
|
|
56
|
+
async function buildOffer(repository, admission, appends, companions) {
|
|
57
57
|
const snapshot = admission.snapshot;
|
|
58
58
|
const changes = new Map();
|
|
59
59
|
const heads = {};
|
|
60
60
|
if (snapshot.commit === null) {
|
|
61
|
-
changes.set(GIT_FORMAT_PATH, { oid: writeBlob(repository, GIT_FORMAT_BYTES), mode: "100644", type: "blob" });
|
|
61
|
+
changes.set(GIT_FORMAT_PATH, { oid: await writeBlob(repository, GIT_FORMAT_BYTES), mode: "100644", type: "blob" });
|
|
62
62
|
}
|
|
63
63
|
for (const companion of companions) {
|
|
64
64
|
changes.set(companion.path, {
|
|
65
|
-
oid: writeBlob(repository, companion.bytes),
|
|
65
|
+
oid: await writeBlob(repository, companion.bytes),
|
|
66
66
|
mode: "100644",
|
|
67
67
|
type: "blob",
|
|
68
68
|
});
|
|
@@ -72,7 +72,7 @@ function buildOffer(repository, admission, appends, companions) {
|
|
|
72
72
|
let journal = current.bytes;
|
|
73
73
|
for (const entry of append.entries)
|
|
74
74
|
journal = Buffer.concat([journal, Buffer.from(encodeEntry(entry))]);
|
|
75
|
-
const blob = writeBlob(repository, journal);
|
|
75
|
+
const blob = await writeBlob(repository, journal);
|
|
76
76
|
const entries = decodeJournal(journal.toString("utf8"));
|
|
77
77
|
const terminal = entries.some((entry) => entry.kind === "claimed" || entry.kind === "abandoned");
|
|
78
78
|
const destination = contractJournalPath(append.contractId, terminal ? "terminal" : "active");
|
|
@@ -83,15 +83,15 @@ function buildOffer(repository, admission, appends, companions) {
|
|
|
83
83
|
}
|
|
84
84
|
return { changes, heads };
|
|
85
85
|
}
|
|
86
|
-
function publishOffer(repository, admission, target, changes, assertions) {
|
|
86
|
+
async function publishOffer(repository, admission, target, changes, assertions) {
|
|
87
87
|
const { snapshot } = admission;
|
|
88
|
-
const gitTree = updateGitTreeFromFrozenDirectories(repository, snapshot.tree, admission.treeDirectories, changes);
|
|
89
|
-
const gitCommit = mintSnapshotId(writeCommit({
|
|
88
|
+
const gitTree = await updateGitTreeFromFrozenDirectories(repository, snapshot.tree, admission.treeDirectories, changes);
|
|
89
|
+
const gitCommit = mintSnapshotId(await writeCommit({
|
|
90
90
|
repository,
|
|
91
91
|
tree: gitTree,
|
|
92
92
|
parent: snapshot.commit,
|
|
93
93
|
}));
|
|
94
|
-
return updateRefsAtomically(repository, [
|
|
94
|
+
return await updateRefsAtomically(repository, [
|
|
95
95
|
{ ref: GIT_REF, newOid: gitObjectIdForSnapshot(gitCommit), expectedOid: snapshot.commit },
|
|
96
96
|
...(target === null
|
|
97
97
|
? []
|
|
@@ -102,15 +102,15 @@ function publishOffer(repository, admission, target, changes, assertions) {
|
|
|
102
102
|
}]),
|
|
103
103
|
], assertions);
|
|
104
104
|
}
|
|
105
|
-
export function admit(repository, offer, admission, assertions = []) {
|
|
105
|
+
export async function admit(repository, offer, admission, assertions = []) {
|
|
106
106
|
if (!Array.isArray(offer.facts) || offer.facts.length === 0) {
|
|
107
107
|
throw new Error("facts must be a nonempty array");
|
|
108
108
|
}
|
|
109
109
|
const appends = assertAppendStructure(offer.facts);
|
|
110
110
|
const companions = assertCompanionStructure(offer.companions ?? [], appends);
|
|
111
111
|
const target = offer.target ?? null;
|
|
112
|
-
const attempt = buildOffer(repository, admission, appends, companions);
|
|
113
|
-
const publication = publishOffer(repository, admission, target, attempt.changes, assertions);
|
|
112
|
+
const attempt = await buildOffer(repository, admission, appends, companions);
|
|
113
|
+
const publication = await publishOffer(repository, admission, target, attempt.changes, assertions);
|
|
114
114
|
if (publication.kind === "published") {
|
|
115
115
|
return {
|
|
116
116
|
kind: "accepted",
|
package/build/src/git/hooks.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { mkdir, readFile } from "node:fs/promises";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { replaceFileDurably } from "../coordination/durable-file.js";
|
|
@@ -140,9 +140,9 @@ function decodeMarker(bytes) {
|
|
|
140
140
|
export function hookMarkerPath(administrationDirectory) {
|
|
141
141
|
return join(administrationDirectory, "keiyaku", "hooks.json");
|
|
142
142
|
}
|
|
143
|
-
function readMarker(administrationDirectory) {
|
|
143
|
+
async function readMarker(administrationDirectory) {
|
|
144
144
|
try {
|
|
145
|
-
return decodeMarker(
|
|
145
|
+
return decodeMarker(await readFile(hookMarkerPath(administrationDirectory), "utf8"));
|
|
146
146
|
}
|
|
147
147
|
catch (error) {
|
|
148
148
|
if (error.code === "ENOENT")
|
|
@@ -150,10 +150,10 @@ function readMarker(administrationDirectory) {
|
|
|
150
150
|
throw error;
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
|
-
function writeMarker(administrationDirectory, marker) {
|
|
153
|
+
async function writeMarker(administrationDirectory, marker) {
|
|
154
154
|
const path = hookMarkerPath(administrationDirectory);
|
|
155
|
-
|
|
156
|
-
replaceFileDurably(path, `${JSON.stringify(marker)}\n`);
|
|
155
|
+
await mkdir(dirname(path), { recursive: true });
|
|
156
|
+
await replaceFileDurably(path, `${JSON.stringify(marker)}\n`);
|
|
157
157
|
}
|
|
158
158
|
function freshMarker(commands, createPending) {
|
|
159
159
|
return {
|
|
@@ -227,7 +227,7 @@ async function executePendingCommand(input) {
|
|
|
227
227
|
mode: "immediate",
|
|
228
228
|
});
|
|
229
229
|
try {
|
|
230
|
-
const marker = readMarker(input.administrationDirectory);
|
|
230
|
+
const marker = await readMarker(input.administrationDirectory);
|
|
231
231
|
if (marker === null)
|
|
232
232
|
throw new Error("worktree hook marker disappeared before execution");
|
|
233
233
|
const progress = marker[input.phase];
|
|
@@ -241,7 +241,7 @@ async function executePendingCommand(input) {
|
|
|
241
241
|
throw new Error("managed hook runner cancelled without a signal");
|
|
242
242
|
const failure = result.kind === "failed" ? result.failure : null;
|
|
243
243
|
const next = input.command + 1;
|
|
244
|
-
writeMarker(input.administrationDirectory, withProgress(marker, input.phase, failure === null
|
|
244
|
+
await writeMarker(input.administrationDirectory, withProgress(marker, input.phase, failure === null
|
|
245
245
|
? next === marker.commands[input.phase].length ? { status: "ok" } : { status: "pending", next }
|
|
246
246
|
: { status: "failed", command: input.command, failure }));
|
|
247
247
|
}
|
|
@@ -268,14 +268,14 @@ async function runPendingCommand(input) {
|
|
|
268
268
|
throw runnerFailure(outcome);
|
|
269
269
|
}
|
|
270
270
|
async function runPhase(worktree, administrationDirectory, hooks, phase, retryHooks) {
|
|
271
|
-
let marker = readMarker(administrationDirectory);
|
|
271
|
+
let marker = await readMarker(administrationDirectory);
|
|
272
272
|
if (marker === null) {
|
|
273
273
|
marker = freshMarker(hooks, phase === "create");
|
|
274
|
-
writeMarker(administrationDirectory, marker);
|
|
274
|
+
await writeMarker(administrationDirectory, marker);
|
|
275
275
|
}
|
|
276
276
|
let retryFailure = retryHooks && marker[phase].status === "failed";
|
|
277
277
|
for (;;) {
|
|
278
|
-
marker = readMarker(administrationDirectory);
|
|
278
|
+
marker = await readMarker(administrationDirectory);
|
|
279
279
|
if (marker === null)
|
|
280
280
|
throw new Error("worktree hook marker disappeared during execution");
|
|
281
281
|
const progress = marker[phase];
|
|
@@ -286,11 +286,11 @@ async function runPhase(worktree, administrationDirectory, hooks, phase, retryHo
|
|
|
286
286
|
return { kind: "worktree-hook-failed", phase, path: worktree, command: progress.command, failure: progress.failure };
|
|
287
287
|
}
|
|
288
288
|
retryFailure = false;
|
|
289
|
-
writeMarker(administrationDirectory, withProgress(marker, phase, { status: "pending", next: progress.command }));
|
|
289
|
+
await writeMarker(administrationDirectory, withProgress(marker, phase, { status: "pending", next: progress.command }));
|
|
290
290
|
continue;
|
|
291
291
|
}
|
|
292
292
|
if (progress.next === marker.commands[phase].length) {
|
|
293
|
-
writeMarker(administrationDirectory, withProgress(marker, phase, { status: "ok" }));
|
|
293
|
+
await writeMarker(administrationDirectory, withProgress(marker, phase, { status: "ok" }));
|
|
294
294
|
continue;
|
|
295
295
|
}
|
|
296
296
|
await runPendingCommand({ administrationDirectory, worktree, phase, command: progress.next });
|
|
@@ -3,7 +3,6 @@ import type { ChangeId, ContractCoordinates, ContractId, SnapshotId } from "../c
|
|
|
3
3
|
import { type GitObjectId } from "./identity.js";
|
|
4
4
|
import { type GitRepository } from "./repository.js";
|
|
5
5
|
import type { TenderCapture } from "./tender.js";
|
|
6
|
-
import type { WorkspaceDirtyDelta } from "./tender.js";
|
|
7
6
|
declare const REQUIRED_GIT: "2.38";
|
|
8
7
|
export type IntegrationPreparationRefusal = Readonly<{
|
|
9
8
|
kind: "integration-failed";
|
|
@@ -23,27 +22,27 @@ export type IntegrationCoordinates = Readonly<{
|
|
|
23
22
|
export type IntegrationPlan = Readonly<{
|
|
24
23
|
predecessor: SnapshotId;
|
|
25
24
|
tree: GitObjectId;
|
|
26
|
-
changeId: ChangeId;
|
|
27
|
-
}>;
|
|
28
|
-
export type ReviewIntegration = Readonly<{
|
|
29
|
-
changeId: ChangeId;
|
|
30
|
-
workspace?: WorkspaceDirtyDelta;
|
|
31
25
|
}>;
|
|
26
|
+
/** Mint the one worktree-content identity shared by review and delivery. */
|
|
27
|
+
export declare function worktreeChangeId(repository: GitRepository, input: IntegrationCoordinates, tender: TenderCapture): Promise<ChangeId>;
|
|
32
28
|
/** Materialize the exact integration tree against its observed predecessor. */
|
|
33
29
|
export declare function materializeIntegrationSnapshot(repository: GitRepository, tree: GitObjectId, parent: SnapshotId, input: Readonly<{
|
|
34
30
|
contractId: ContractId;
|
|
35
31
|
title: string;
|
|
36
32
|
message?: string;
|
|
37
|
-
}>): SnapshotId
|
|
38
|
-
export declare function planIntegration(repository: GitRepository, input: IntegrationCoordinates, tender: TenderCapture, requireBranchesToBeUpToDate: boolean): Preparation<IntegrationPlan, Readonly<{
|
|
39
|
-
kind: "target-missing";
|
|
40
|
-
contractId: ContractId;
|
|
41
|
-
}> | IntegrationPreparationRefusal>;
|
|
42
|
-
/** Prepare the integration-derived review subject from one captured tender. */
|
|
43
|
-
export declare function prepareReviewIntegration(repository: GitRepository, input: IntegrationCoordinates, tender: TenderCapture, workspace?: WorkspaceDirtyDelta): Preparation<ReviewIntegration, Readonly<{
|
|
33
|
+
}>): Promise<SnapshotId>;
|
|
34
|
+
export declare function planIntegration(repository: GitRepository, input: IntegrationCoordinates, tender: TenderCapture, requireBranchesToBeUpToDate: boolean): Promise<Preparation<IntegrationPlan, Readonly<{
|
|
44
35
|
kind: "target-missing";
|
|
45
36
|
contractId: ContractId;
|
|
46
|
-
}> | IntegrationPreparationRefusal
|
|
37
|
+
}> | IntegrationPreparationRefusal>>;
|
|
38
|
+
export type DeliveryDiffScope = Readonly<{
|
|
39
|
+
filesChanged: number;
|
|
40
|
+
insertions: number;
|
|
41
|
+
deletions: number;
|
|
42
|
+
paths?: readonly string[];
|
|
43
|
+
}>;
|
|
44
|
+
/** Compute predecessor-to-candidate scope from the exact integration trees. */
|
|
45
|
+
export declare function readDeliveryScope(repository: GitRepository, predecessor: SnapshotId, candidate: SnapshotId, includePaths: boolean): Promise<DeliveryDiffScope>;
|
|
47
46
|
/** Read a recorded integration pair's patch, or null when Git no longer has it. */
|
|
48
|
-
export declare function readDeliveryDiff(repository: GitRepository, predecessor: SnapshotId, candidate: SnapshotId): string | null
|
|
47
|
+
export declare function readDeliveryDiff(repository: GitRepository, predecessor: SnapshotId, candidate: SnapshotId): Promise<string | null>;
|
|
49
48
|
export {};
|